11package com.langchain.smith.wrappers.openai
22
3+ import com.fasterxml.jackson.databind.ObjectMapper
4+ import io.opentelemetry.api.common.AttributeKey
35import io.opentelemetry.api.trace.Span
46import io.opentelemetry.api.trace.SpanBuilder
57import io.opentelemetry.api.trace.SpanKind
@@ -8,26 +10,10 @@ import io.opentelemetry.api.trace.Tracer
810/* * Internal utility for OpenTelemetry span creation and management. */
911internal object TracingUtils {
1012 private const val INSTRUMENTATION_NAME = " langsmith-java-otel-wrappers"
13+ private val jsonMapper = ObjectMapper ()
1114
12- fun getTracer (): Tracer {
13- return try {
14- val tracer =
15- io.opentelemetry.api.GlobalOpenTelemetry .get().getTracer(INSTRUMENTATION_NAME )
16- val debug =
17- java.lang.Boolean .getBoolean(" langsmith.debug" ) ||
18- " true" .equals(System .getenv(" LANGSMITH_DEBUG" ), ignoreCase = true )
19- if (debug) {
20- val otel = io.opentelemetry.api.GlobalOpenTelemetry .get()
21- val isNoop = otel.javaClass.name.contains(" Noop" )
22- println (
23- " [TracingUtils] Tracer obtained: ${tracer.javaClass.name} , OpenTelemetry isNoop: $isNoop "
24- )
25- }
26- tracer
27- } catch (e: Exception ) {
28- io.opentelemetry.api.GlobalOpenTelemetry .get().getTracer(INSTRUMENTATION_NAME )
29- }
30- }
15+ fun getTracer (): Tracer =
16+ io.opentelemetry.api.GlobalOpenTelemetry .get().getTracer(INSTRUMENTATION_NAME )
3117
3218 fun createSpanBuilder (
3319 model : String? ,
@@ -40,29 +26,33 @@ internal object TracingUtils {
4026 tracer
4127 .spanBuilder(spanName)
4228 .setSpanKind(SpanKind .CLIENT )
43- .setAttribute(" gen_ai.system" , " openai" )
44- .setAttribute(" gen_ai.operation.name" , operationType)
45- .setAttribute(" gen_ai.provider.name" , " openai" )
46- spanKind?.let { builder.setAttribute(" langsmith.span.kind" , it) }
29+ .setAttribute(AttributeKey .stringKey( " gen_ai.system" ) , " openai" )
30+ .setAttribute(AttributeKey .stringKey( " gen_ai.operation.name" ) , operationType)
31+ .setAttribute(AttributeKey .stringKey( " gen_ai.provider.name" ) , " openai" )
32+ spanKind?.let { builder.setAttribute(AttributeKey .stringKey( " langsmith.span.kind" ) , it) }
4733 return builder
4834 }
4935
5036 fun setRequestAttributes (span : Span , model : String? ) {
51- model?.let { span.setAttribute(" gen_ai.request.model" , it) }
37+ model?.let { span.setAttribute(AttributeKey .stringKey( " gen_ai.request.model" ) , it) }
5238 }
5339
5440 fun setRequestParameters (span : Span , temperature : Double? , topP : Double? , maxTokens : Long? ) {
55- temperature?.let { span.setAttribute(" gen_ai.request.temperature" , it) }
56- topP?.let { span.setAttribute(" gen_ai.request.top_p" , it) }
57- maxTokens?.let { span.setAttribute(" gen_ai.request.max_tokens" , it) }
41+ temperature?.let {
42+ span.setAttribute(AttributeKey .doubleKey(" gen_ai.request.temperature" ), it)
43+ }
44+ topP?.let { span.setAttribute(AttributeKey .doubleKey(" gen_ai.request.top_p" ), it) }
45+ maxTokens?.let { span.setAttribute(AttributeKey .longKey(" gen_ai.request.max_tokens" ), it) }
5846 }
5947
6048 fun setInputMessages (span : Span , messagesJson : String? ) {
61- messagesJson?.let { span.setAttribute(" gen_ai.input.messages" , it) }
49+ messagesJson?.let { span.setAttribute(AttributeKey .stringKey( " gen_ai.input.messages" ) , it) }
6250 }
6351
6452 fun setOutputMessages (span : Span , messagesJson : String? ) {
65- messagesJson?.let { span.setAttribute(" gen_ai.output.messages" , it) }
53+ messagesJson?.let {
54+ span.setAttribute(AttributeKey .stringKey(" gen_ai.output.messages" ), it)
55+ }
6656 }
6757
6858 fun setResponseAttributes (
@@ -71,27 +61,30 @@ internal object TracingUtils {
7161 outputTokens : Long? ,
7262 totalTokens : Long? ,
7363 ) {
74- inputTokens?.let { span.setAttribute(" gen_ai.usage.input_tokens" , it) }
75- outputTokens?.let { span.setAttribute(" gen_ai.usage.output_tokens" , it) }
76- totalTokens?.let { span.setAttribute(" gen_ai.usage.total_tokens" , it) }
64+ inputTokens?.let {
65+ span.setAttribute(AttributeKey .longKey(" gen_ai.usage.input_tokens" ), it)
66+ }
67+ outputTokens?.let {
68+ span.setAttribute(AttributeKey .longKey(" gen_ai.usage.output_tokens" ), it)
69+ }
70+ totalTokens?.let {
71+ span.setAttribute(AttributeKey .longKey(" gen_ai.usage.total_tokens" ), it)
72+ }
7773 }
7874
7975 fun setResponseMetadata (span : Span , responseModel : String? , finishReason : String? ) {
80- responseModel?.let { span.setAttribute(" gen_ai.response.model" , it) }
81- finishReason?.let { span.setAttribute(" gen_ai.response.finish_reason" , it) }
76+ responseModel?.let {
77+ span.setAttribute(AttributeKey .stringKey(" gen_ai.response.model" ), it)
78+ }
79+ finishReason?.let {
80+ span.setAttribute(AttributeKey .stringKey(" gen_ai.response.finish_reason" ), it)
81+ }
8282 }
8383
8484 fun recordException (span : Span , exception : Throwable ) {
8585 span.recordException(exception)
86- span.setAttribute(" error" , true )
86+ span.setAttribute(AttributeKey .booleanKey( " error" ) , true )
8787 }
8888
89- fun escapeJsonString (str : String? ): String {
90- if (str == null ) return " "
91- return str.replace(" \\ " , " \\\\ " )
92- .replace(" \" " , " \\\" " )
93- .replace(" \n " , " \\ n" )
94- .replace(" \r " , " \\ r" )
95- .replace(" \t " , " \\ t" )
96- }
89+ fun writeJson (value : Any ): String = jsonMapper.writeValueAsString(value)
9790}
0 commit comments