openlit 1.34.20__py3-none-any.whl → 1.34.23__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- openlit/__helpers.py +40 -0
- openlit/__init__.py +3 -0
- openlit/instrumentation/ag2/__init__.py +22 -18
- openlit/instrumentation/ag2/ag2.py +75 -124
- openlit/instrumentation/ag2/async_ag2.py +114 -0
- openlit/instrumentation/ag2/utils.py +175 -0
- openlit/instrumentation/langchain/__init__.py +11 -35
- openlit/instrumentation/langchain/async_langchain.py +51 -337
- openlit/instrumentation/langchain/langchain.py +50 -310
- openlit/instrumentation/langchain/utils.py +252 -0
- openlit/instrumentation/langchain_community/__init__.py +74 -0
- openlit/instrumentation/langchain_community/async_langchain_community.py +49 -0
- openlit/instrumentation/langchain_community/langchain_community.py +49 -0
- openlit/instrumentation/langchain_community/utils.py +69 -0
- openlit/instrumentation/openai/__init__.py +63 -68
- openlit/instrumentation/openai/async_openai.py +203 -1277
- openlit/instrumentation/openai/openai.py +200 -1274
- openlit/instrumentation/openai/utils.py +794 -0
- openlit/instrumentation/vertexai/__init__.py +18 -23
- openlit/instrumentation/vertexai/async_vertexai.py +46 -364
- openlit/instrumentation/vertexai/utils.py +204 -0
- openlit/instrumentation/vertexai/vertexai.py +46 -364
- {openlit-1.34.20.dist-info → openlit-1.34.23.dist-info}/METADATA +1 -1
- {openlit-1.34.20.dist-info → openlit-1.34.23.dist-info}/RECORD +26 -17
- {openlit-1.34.20.dist-info → openlit-1.34.23.dist-info}/LICENSE +0 -0
- {openlit-1.34.20.dist-info → openlit-1.34.23.dist-info}/WHEEL +0 -0
@@ -1,4 +1,3 @@
|
|
1
|
-
# pylint: disable=useless-return, bad-staticmethod-argument, disable=duplicate-code
|
2
1
|
"""Initializer of Auto Instrumentation of LangChain Functions"""
|
3
2
|
from typing import Collection
|
4
3
|
import importlib.metadata
|
@@ -6,41 +5,17 @@ from opentelemetry.instrumentation.instrumentor import BaseInstrumentor
|
|
6
5
|
from wrapt import wrap_function_wrapper
|
7
6
|
|
8
7
|
from openlit.instrumentation.langchain.langchain import (
|
9
|
-
general_wrap,
|
10
8
|
hub,
|
11
9
|
chat
|
12
10
|
)
|
13
11
|
from openlit.instrumentation.langchain.async_langchain import (
|
12
|
+
async_hub,
|
14
13
|
async_chat
|
15
14
|
)
|
16
15
|
|
17
16
|
_instruments = ("langchain >= 0.1.20",)
|
18
17
|
|
19
18
|
WRAPPED_METHODS = [
|
20
|
-
{
|
21
|
-
"package": "langchain_community.document_loaders.base",
|
22
|
-
"object": "BaseLoader.load",
|
23
|
-
"endpoint": "langchain.retrieve.load",
|
24
|
-
"wrapper": general_wrap,
|
25
|
-
},
|
26
|
-
{
|
27
|
-
"package": "langchain_community.document_loaders.base",
|
28
|
-
"object": "BaseLoader.aload",
|
29
|
-
"endpoint": "langchain.retrieve.load",
|
30
|
-
"wrapper": general_wrap,
|
31
|
-
},
|
32
|
-
{
|
33
|
-
"package": "langchain_text_splitters.base",
|
34
|
-
"object": "TextSplitter.split_documents",
|
35
|
-
"endpoint": "langchain.retrieve.split_documents",
|
36
|
-
"wrapper": general_wrap,
|
37
|
-
},
|
38
|
-
{
|
39
|
-
"package": "langchain_text_splitters.base",
|
40
|
-
"object": "TextSplitter.create_documents",
|
41
|
-
"endpoint": "langchain.retrieve.create_documents",
|
42
|
-
"wrapper": general_wrap,
|
43
|
-
},
|
44
19
|
{
|
45
20
|
"package": "langchain.hub",
|
46
21
|
"object": "pull",
|
@@ -79,27 +54,29 @@ WRAPPED_METHODS = [
|
|
79
54
|
},
|
80
55
|
{
|
81
56
|
"package": "langchain.chains.base",
|
82
|
-
"object": "Chain.
|
57
|
+
"object": "Chain.ainvoke",
|
83
58
|
"endpoint": "langchain.chain.invoke",
|
84
59
|
"wrapper": async_chat,
|
85
60
|
}
|
86
61
|
]
|
87
62
|
|
88
63
|
class LangChainInstrumentor(BaseInstrumentor):
|
89
|
-
"""
|
64
|
+
"""
|
65
|
+
An instrumentor for LangChain client library.
|
66
|
+
"""
|
90
67
|
|
91
68
|
def instrumentation_dependencies(self) -> Collection[str]:
|
92
69
|
return _instruments
|
93
70
|
|
94
71
|
def _instrument(self, **kwargs):
|
95
|
-
|
96
|
-
environment = kwargs.get("environment")
|
72
|
+
version = importlib.metadata.version("langchain")
|
73
|
+
environment = kwargs.get("environment", "default")
|
74
|
+
application_name = kwargs.get("application_name", "default")
|
97
75
|
tracer = kwargs.get("tracer")
|
98
|
-
pricing_info = kwargs.get("pricing_info")
|
99
|
-
capture_message_content = kwargs.get("capture_message_content")
|
76
|
+
pricing_info = kwargs.get("pricing_info", {})
|
77
|
+
capture_message_content = kwargs.get("capture_message_content", False)
|
100
78
|
metrics = kwargs.get("metrics_dict")
|
101
79
|
disable_metrics = kwargs.get("disable_metrics")
|
102
|
-
version = importlib.metadata.version("langchain")
|
103
80
|
|
104
81
|
for wrapped_method in WRAPPED_METHODS:
|
105
82
|
wrap_package = wrapped_method.get("package")
|
@@ -110,9 +87,8 @@ class LangChainInstrumentor(BaseInstrumentor):
|
|
110
87
|
wrap_package,
|
111
88
|
wrap_object,
|
112
89
|
wrapper(gen_ai_endpoint, version, environment, application_name,
|
113
|
-
|
90
|
+
tracer, pricing_info, capture_message_content, metrics, disable_metrics),
|
114
91
|
)
|
115
92
|
|
116
|
-
@staticmethod
|
117
93
|
def _uninstrument(self, **kwargs):
|
118
94
|
pass
|
@@ -1,245 +1,68 @@
|
|
1
|
-
# pylint: disable=duplicate-code, broad-exception-caught, too-many-statements, unused-argument, unused-import, too-many-function-args
|
2
1
|
"""
|
3
|
-
Module for monitoring
|
2
|
+
Module for monitoring LangChain API calls.
|
4
3
|
"""
|
5
4
|
|
6
|
-
import logging
|
7
5
|
import time
|
8
|
-
from opentelemetry.trace import SpanKind
|
9
|
-
from opentelemetry.sdk.resources import SERVICE_NAME, TELEMETRY_SDK_NAME, DEPLOYMENT_ENVIRONMENT
|
6
|
+
from opentelemetry.trace import SpanKind
|
10
7
|
from openlit.__helpers import (
|
11
|
-
get_chat_model_cost,
|
12
8
|
handle_exception,
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
9
|
+
set_server_address_and_port
|
10
|
+
)
|
11
|
+
from openlit.instrumentation.langchain.utils import (
|
12
|
+
get_model_from_instance,
|
13
|
+
process_chat_response,
|
14
|
+
process_hub_response,
|
17
15
|
)
|
18
16
|
from openlit.semcov import SemanticConvention
|
19
17
|
|
20
|
-
# Initialize logger for logging potential issues and operations
|
21
|
-
logger = logging.getLogger(__name__)
|
22
|
-
|
23
|
-
def get_attribute_from_instance_or_kwargs(instance, attribute_name, default=-1):
|
24
|
-
"""Return attribute from instance or kwargs"""
|
25
|
-
# Attempt to retrieve model_kwargs from the instance
|
26
|
-
model_kwargs = getattr(instance, 'model_kwargs', None)
|
27
|
-
|
28
|
-
# Check for attribute in model_kwargs if it exists
|
29
|
-
if model_kwargs and attribute_name in model_kwargs:
|
30
|
-
return model_kwargs[attribute_name]
|
31
|
-
|
32
|
-
# Attempt to get the attribute directly from the instance
|
33
|
-
try:
|
34
|
-
return getattr(instance, attribute_name)
|
35
|
-
except AttributeError:
|
36
|
-
# Special handling for 'model' attribute to consider 'model_id'
|
37
|
-
if attribute_name == 'model':
|
38
|
-
return getattr(instance, 'model_id', 'default_model_id')
|
39
|
-
|
40
|
-
# Default if the attribute isn't found in model_kwargs or the instance
|
41
|
-
return default
|
42
|
-
|
43
|
-
def async_general_wrap(gen_ai_endpoint, version, environment, application_name,
|
44
|
-
tracer, pricing_info, capture_message_content, metrics, disable_metrics):
|
45
|
-
"""
|
46
|
-
Creates a wrapper around a function call to trace and log its execution metrics.
|
47
|
-
|
48
|
-
This function wraps any given function to measure its execution time,
|
49
|
-
log its operation, and trace its execution using OpenTelemetry.
|
50
|
-
|
51
|
-
Parameters:
|
52
|
-
- gen_ai_endpoint (str): A descriptor or name for the endpoint being traced.
|
53
|
-
- version (str): The version of the Langchain application.
|
54
|
-
- environment (str): The deployment environment (e.g., 'production', 'development').
|
55
|
-
- application_name (str): Name of the Langchain application.
|
56
|
-
- tracer (opentelemetry.trace.Tracer): The tracer object used for OpenTelemetry tracing.
|
57
|
-
- pricing_info (dict): Information about the pricing for internal metrics (currently not used).
|
58
|
-
- capture_message_content (bool): Flag indicating whether to trace the content of the response.
|
59
|
-
|
60
|
-
Returns:
|
61
|
-
- function: A higher-order function that takes a function 'wrapped' and returns
|
62
|
-
a new function that wraps 'wrapped' with additional tracing and logging.
|
63
|
-
"""
|
64
|
-
|
65
|
-
async def wrapper(wrapped, instance, args, kwargs):
|
66
|
-
"""
|
67
|
-
An inner wrapper function that executes the wrapped function, measures execution
|
68
|
-
time, and records trace data using OpenTelemetry.
|
69
|
-
|
70
|
-
Parameters:
|
71
|
-
- wrapped (Callable): The original function that this wrapper will execute.
|
72
|
-
- instance (object): The instance to which the wrapped function belongs. This
|
73
|
-
is used for instance methods. For static and classmethods,
|
74
|
-
this may be None.
|
75
|
-
- args (tuple): Positional arguments passed to the wrapped function.
|
76
|
-
- kwargs (dict): Keyword arguments passed to the wrapped function.
|
77
|
-
|
78
|
-
Returns:
|
79
|
-
- The result of the wrapped function call.
|
80
|
-
|
81
|
-
The wrapper initiates a span with the provided tracer, sets various attributes
|
82
|
-
on the span based on the function's execution and response, and ensures
|
83
|
-
errors are handled and logged appropriately.
|
84
|
-
"""
|
85
|
-
with tracer.start_as_current_span(gen_ai_endpoint, kind= SpanKind.CLIENT) as span:
|
86
|
-
response = await wrapped(*args, **kwargs)
|
87
|
-
|
88
|
-
try:
|
89
|
-
span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
|
90
|
-
span.set_attribute(SemanticConvention.GEN_AI_SYSTEM,
|
91
|
-
SemanticConvention.GEN_AI_SYSTEM_LANGCHAIN)
|
92
|
-
span.set_attribute(SemanticConvention.GEN_AI_ENDPOINT,
|
93
|
-
gen_ai_endpoint)
|
94
|
-
span.set_attribute(DEPLOYMENT_ENVIRONMENT,
|
95
|
-
environment)
|
96
|
-
span.set_attribute(SemanticConvention.GEN_AI_OPERATION,
|
97
|
-
SemanticConvention.GEN_AI_OPERATION_TYPE_FRAMEWORK)
|
98
|
-
span.set_attribute(SERVICE_NAME,
|
99
|
-
application_name)
|
100
|
-
span.set_attribute(SemanticConvention.GEN_AI_RETRIEVAL_SOURCE,
|
101
|
-
response[0].metadata["source"])
|
102
|
-
span.set_status(Status(StatusCode.OK))
|
103
|
-
|
104
|
-
# Return original response
|
105
|
-
return response
|
106
|
-
|
107
|
-
except Exception as e:
|
108
|
-
handle_exception(span, e)
|
109
|
-
logger.error("Error in trace creation: %s", e)
|
110
|
-
|
111
|
-
# Return original response
|
112
|
-
return response
|
113
|
-
|
114
|
-
return wrapper
|
115
|
-
|
116
18
|
def async_hub(gen_ai_endpoint, version, environment, application_name, tracer,
|
117
|
-
|
19
|
+
pricing_info, capture_message_content, metrics, disable_metrics):
|
118
20
|
"""
|
119
|
-
|
120
|
-
|
121
|
-
Similar to `general_wrap`, this function focuses on wrapping functions involved
|
122
|
-
in interacting with the Langchain hub, adding specific metadata relevant to
|
123
|
-
hub operations to the span attributes.
|
124
|
-
|
125
|
-
Parameters:
|
126
|
-
- gen_ai_endpoint (str): A descriptor or name for the Langchain hub endpoint.
|
127
|
-
- version (str): The version of the Langchain application.
|
128
|
-
- environment (str): The deployment environment, such as 'production' or 'development'.
|
129
|
-
- application_name (str): Name of the Langchain application.
|
130
|
-
- tracer (opentelemetry.trace.Tracer): The tracer for OpenTelemetry tracing.
|
131
|
-
- pricing_info (dict): Pricing information for the operation (not currently used).
|
132
|
-
- capture_message_content (bool): Indicates if the content of the response should be traced.
|
133
|
-
|
134
|
-
Returns:
|
135
|
-
- function: A new function that wraps the original hub operation call with added
|
136
|
-
logging, tracing, and metric calculation functionalities.
|
21
|
+
Generates a telemetry wrapper for LangChain async hub operations.
|
137
22
|
"""
|
138
23
|
|
139
24
|
async def wrapper(wrapped, instance, args, kwargs):
|
140
25
|
"""
|
141
|
-
|
142
|
-
providing tracing, logging, and execution metrics.
|
143
|
-
|
144
|
-
Parameters:
|
145
|
-
- wrapped (Callable): The original hub operation function to be executed.
|
146
|
-
- instance (object): The instance of the class where the hub operation
|
147
|
-
method is defined. May be None for static or class methods.
|
148
|
-
- args (tuple): Positional arguments to pass to the hub operation function.
|
149
|
-
- kwargs (dict): Keyword arguments to pass to the hub operation function.
|
150
|
-
|
151
|
-
Returns:
|
152
|
-
- The result of executing the hub operation function.
|
153
|
-
|
154
|
-
This wrapper captures additional metadata relevant to Langchain hub operations,
|
155
|
-
creating spans with specific attributes and metrics that reflect the nature of
|
156
|
-
each hub call.
|
26
|
+
Wraps the LangChain async hub operation call.
|
157
27
|
"""
|
158
28
|
|
159
|
-
|
29
|
+
server_address, server_port = set_server_address_and_port(instance, "langchain.com", 443)
|
30
|
+
|
31
|
+
with tracer.start_as_current_span(gen_ai_endpoint, kind=SpanKind.CLIENT) as span:
|
160
32
|
response = await wrapped(*args, **kwargs)
|
161
33
|
|
162
34
|
try:
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
application_name)
|
174
|
-
span.set_attribute(SemanticConvention.GEN_AI_HUB_OWNER,
|
175
|
-
response.metadata["lc_hub_owner"])
|
176
|
-
span.set_attribute(SemanticConvention.GEN_AI_HUB_REPO,
|
177
|
-
response.metadata["lc_hub_repo"])
|
178
|
-
span.set_status(Status(StatusCode.OK))
|
179
|
-
|
180
|
-
return response
|
35
|
+
response = process_hub_response(
|
36
|
+
response=response,
|
37
|
+
gen_ai_endpoint=gen_ai_endpoint,
|
38
|
+
server_port=server_port,
|
39
|
+
server_address=server_address,
|
40
|
+
environment=environment,
|
41
|
+
application_name=application_name,
|
42
|
+
span=span,
|
43
|
+
version=version
|
44
|
+
)
|
181
45
|
|
182
46
|
except Exception as e:
|
183
47
|
handle_exception(span, e)
|
184
|
-
logger.error("Error in trace creation: %s", e)
|
185
48
|
|
186
|
-
|
187
|
-
return response
|
49
|
+
return response
|
188
50
|
|
189
51
|
return wrapper
|
190
52
|
|
191
53
|
def async_chat(gen_ai_endpoint, version, environment, application_name,
|
192
|
-
|
54
|
+
tracer, pricing_info, capture_message_content, metrics, disable_metrics):
|
193
55
|
"""
|
194
|
-
|
195
|
-
|
196
|
-
This function wraps any given function to measure its execution time,
|
197
|
-
log its operation, and trace its execution using OpenTelemetry.
|
198
|
-
|
199
|
-
Parameters:
|
200
|
-
- version (str): The version of the Langchain application.
|
201
|
-
- environment (str): The deployment environment (e.g., 'production', 'development').
|
202
|
-
- application_name (str): Name of the Langchain application.
|
203
|
-
- tracer (opentelemetry.trace.Tracer): The tracer object used for OpenTelemetry tracing.
|
204
|
-
- pricing_info (dict): Information about the pricing for internal metrics (currently not used).
|
205
|
-
- capture_message_content (bool): Flag indicating whether to trace the content of the response.
|
206
|
-
|
207
|
-
Returns:
|
208
|
-
- function: A higher-order function that takes a function 'wrapped' and returns
|
209
|
-
a new function that wraps 'wrapped' with additional tracing and logging.
|
56
|
+
Generates a telemetry wrapper for LangChain async chat operations.
|
210
57
|
"""
|
211
58
|
|
212
59
|
async def wrapper(wrapped, instance, args, kwargs):
|
213
60
|
"""
|
214
|
-
|
215
|
-
time, and records trace data using OpenTelemetry.
|
216
|
-
|
217
|
-
Parameters:
|
218
|
-
- wrapped (Callable): The original function that this wrapper will execute.
|
219
|
-
- instance (object): The instance to which the wrapped function belongs. This
|
220
|
-
is used for instance methods. For static and classmethods,
|
221
|
-
this may be None.
|
222
|
-
- args (tuple): Positional arguments passed to the wrapped function.
|
223
|
-
- kwargs (dict): Keyword arguments passed to the wrapped function.
|
224
|
-
|
225
|
-
Returns:
|
226
|
-
- The result of the wrapped function call.
|
227
|
-
|
228
|
-
The wrapper initiates a span with the provided tracer, sets various attributes
|
229
|
-
on the span based on the function's execution and response, and ensures
|
230
|
-
errors are handled and logged appropriately.
|
61
|
+
Wraps the LangChain async chat operation call.
|
231
62
|
"""
|
232
63
|
|
233
|
-
server_address, server_port = "
|
234
|
-
|
235
|
-
if hasattr(instance, "model_id"):
|
236
|
-
request_model = instance.model_id
|
237
|
-
elif hasattr(instance, "model"):
|
238
|
-
request_model = instance.model
|
239
|
-
elif hasattr(instance, "model_name"):
|
240
|
-
request_model = instance.model_name
|
241
|
-
else:
|
242
|
-
request_model = "NOT_FOUND"
|
64
|
+
server_address, server_port = set_server_address_and_port(instance, "langchain.com", 443)
|
65
|
+
request_model = get_model_from_instance(instance)
|
243
66
|
|
244
67
|
span_name = f"{SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT} {request_model}"
|
245
68
|
|
@@ -249,140 +72,31 @@ def async_chat(gen_ai_endpoint, version, environment, application_name,
|
|
249
72
|
end_time = time.time()
|
250
73
|
|
251
74
|
try:
|
252
|
-
#
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
for item in content
|
273
|
-
)
|
274
|
-
formatted_messages.append(f"{role}: {content_str}")
|
275
|
-
else:
|
276
|
-
formatted_messages.append(f"{role}: {content}")
|
277
|
-
|
278
|
-
# Join all formatted messages with newline
|
279
|
-
prompt = "\n".join(formatted_messages)
|
280
|
-
|
281
|
-
input_tokens = general_tokens(str(prompt))
|
282
|
-
output_tokens = general_tokens(str(response))
|
283
|
-
|
284
|
-
# Calculate cost of the operation
|
285
|
-
cost = get_chat_model_cost(
|
286
|
-
request_model,
|
287
|
-
pricing_info, input_tokens, output_tokens
|
75
|
+
# Add instance to kwargs for processing
|
76
|
+
kwargs["instance"] = instance
|
77
|
+
|
78
|
+
response = process_chat_response(
|
79
|
+
response=response,
|
80
|
+
request_model=request_model,
|
81
|
+
pricing_info=pricing_info,
|
82
|
+
server_port=server_port,
|
83
|
+
server_address=server_address,
|
84
|
+
environment=environment,
|
85
|
+
application_name=application_name,
|
86
|
+
metrics=metrics,
|
87
|
+
start_time=start_time,
|
88
|
+
end_time=end_time,
|
89
|
+
span=span,
|
90
|
+
capture_message_content=capture_message_content,
|
91
|
+
disable_metrics=disable_metrics,
|
92
|
+
version=version,
|
93
|
+
args=args,
|
94
|
+
**kwargs
|
288
95
|
)
|
289
96
|
|
290
|
-
try:
|
291
|
-
llm_response = response.content
|
292
|
-
except AttributeError:
|
293
|
-
llm_response = response
|
294
|
-
|
295
|
-
# Set base span attribues (OTel Semconv)
|
296
|
-
span.set_attribute(TELEMETRY_SDK_NAME, "openlit")
|
297
|
-
span.set_attribute(SemanticConvention.GEN_AI_OPERATION,
|
298
|
-
SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT)
|
299
|
-
span.set_attribute(SemanticConvention.GEN_AI_SYSTEM,
|
300
|
-
SemanticConvention.GEN_AI_SYSTEM_LANGCHAIN)
|
301
|
-
span.set_attribute(SemanticConvention.GEN_AI_REQUEST_MODEL,
|
302
|
-
request_model)
|
303
|
-
span.set_attribute(SemanticConvention.GEN_AI_RESPONSE_MODEL,
|
304
|
-
request_model)
|
305
|
-
span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TEMPERATURE,
|
306
|
-
str(getattr(instance, 'temperature', 1)))
|
307
|
-
span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TOP_K,
|
308
|
-
str(getattr(instance, 'top_k', 1)))
|
309
|
-
span.set_attribute(SemanticConvention.GEN_AI_REQUEST_TOP_P,
|
310
|
-
str(getattr(instance, 'top_p', 1)))
|
311
|
-
span.set_attribute(SemanticConvention.GEN_AI_USAGE_INPUT_TOKENS,
|
312
|
-
input_tokens)
|
313
|
-
span.set_attribute(SemanticConvention.GEN_AI_USAGE_OUTPUT_TOKENS,
|
314
|
-
output_tokens)
|
315
|
-
span.set_attribute(SemanticConvention.SERVER_ADDRESS,
|
316
|
-
server_address)
|
317
|
-
span.set_attribute(SemanticConvention.SERVER_PORT,
|
318
|
-
server_port)
|
319
|
-
|
320
|
-
# Set base span attribues (Extras)
|
321
|
-
span.set_attribute(DEPLOYMENT_ENVIRONMENT,
|
322
|
-
environment)
|
323
|
-
span.set_attribute(SERVICE_NAME,
|
324
|
-
application_name)
|
325
|
-
span.set_attribute(SemanticConvention.GEN_AI_REQUEST_IS_STREAM,
|
326
|
-
False)
|
327
|
-
span.set_attribute(SemanticConvention.GEN_AI_USAGE_TOTAL_TOKENS,
|
328
|
-
input_tokens + output_tokens)
|
329
|
-
span.set_attribute(SemanticConvention.GEN_AI_USAGE_COST,
|
330
|
-
cost)
|
331
|
-
span.set_attribute(SemanticConvention.GEN_AI_SERVER_TTFT,
|
332
|
-
end_time - start_time)
|
333
|
-
span.set_attribute(SemanticConvention.GEN_AI_SDK_VERSION,
|
334
|
-
version)
|
335
|
-
|
336
|
-
if capture_message_content:
|
337
|
-
span.add_event(
|
338
|
-
name=SemanticConvention.GEN_AI_CONTENT_PROMPT_EVENT,
|
339
|
-
attributes={
|
340
|
-
SemanticConvention.GEN_AI_CONTENT_PROMPT: prompt,
|
341
|
-
},
|
342
|
-
)
|
343
|
-
span.add_event(
|
344
|
-
name=SemanticConvention.GEN_AI_CONTENT_COMPLETION_EVENT,
|
345
|
-
attributes={
|
346
|
-
SemanticConvention.GEN_AI_CONTENT_COMPLETION: llm_response,
|
347
|
-
},
|
348
|
-
)
|
349
|
-
|
350
|
-
span.set_status(Status(StatusCode.OK))
|
351
|
-
|
352
|
-
if disable_metrics is False:
|
353
|
-
attributes = create_metrics_attributes(
|
354
|
-
service_name=application_name,
|
355
|
-
deployment_environment=environment,
|
356
|
-
operation=SemanticConvention.GEN_AI_OPERATION_TYPE_CHAT,
|
357
|
-
system=SemanticConvention.GEN_AI_SYSTEM_LANGCHAIN,
|
358
|
-
request_model=request_model,
|
359
|
-
server_address=server_address,
|
360
|
-
server_port=server_port,
|
361
|
-
response_model=request_model,
|
362
|
-
)
|
363
|
-
|
364
|
-
metrics["genai_client_usage_tokens"].record(
|
365
|
-
input_tokens + output_tokens, attributes
|
366
|
-
)
|
367
|
-
metrics["genai_client_operation_duration"].record(
|
368
|
-
end_time - start_time, attributes
|
369
|
-
)
|
370
|
-
metrics["genai_server_ttft"].record(
|
371
|
-
end_time - start_time, attributes
|
372
|
-
)
|
373
|
-
metrics["genai_requests"].add(1, attributes)
|
374
|
-
metrics["genai_completion_tokens"].add(output_tokens, attributes)
|
375
|
-
metrics["genai_prompt_tokens"].add(input_tokens, attributes)
|
376
|
-
metrics["genai_cost"].record(cost, attributes)
|
377
|
-
|
378
|
-
# Return original response
|
379
|
-
return response
|
380
|
-
|
381
97
|
except Exception as e:
|
382
98
|
handle_exception(span, e)
|
383
|
-
logger.error("Error in trace creation: %s", e)
|
384
99
|
|
385
|
-
|
386
|
-
return response
|
100
|
+
return response
|
387
101
|
|
388
102
|
return wrapper
|