Skip to content

Commit 2ea483a

Browse files
committed
Add operation duration metrics
1 parent 9a17f97 commit 2ea483a

File tree

1 file changed

+49
-11
lines changed
  • instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions

1 file changed

+49
-11
lines changed

instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock.py

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import io
2222
import json
2323
import logging
24+
from timeit import default_timer
2425
from typing import Any
2526

2627
from botocore.eventstream import EventStream
@@ -326,14 +327,15 @@ def before_service_call(
326327
for event in message_to_event(message, capture_content):
327328
event_logger.emit(event)
328329

329-
if not span.is_recording():
330-
return
330+
if span.is_recording():
331+
operation_name = span.attributes.get(GEN_AI_OPERATION_NAME, "")
332+
request_model = span.attributes.get(GEN_AI_REQUEST_MODEL, "")
333+
# avoid setting to an empty string if are not available
334+
if operation_name and request_model:
335+
span.update_name(f"{operation_name} {request_model}")
331336

332-
operation_name = span.attributes.get(GEN_AI_OPERATION_NAME, "")
333-
request_model = span.attributes.get(GEN_AI_REQUEST_MODEL, "")
334-
# avoid setting to an empty string if are not available
335-
if operation_name and request_model:
336-
span.update_name(f"{operation_name} {request_model}")
337+
# this is used to calculate the operation duration metric, duration may be skewed by request_hook
338+
self._operation_start = default_timer()
337339

338340
# pylint: disable=no-self-use
339341
def _converse_on_success(
@@ -376,9 +378,18 @@ def _converse_on_success(
376378
)
377379

378380
metrics = instrumentor_context.metrics
381+
metrics_attributes = self._extract_metrics_attributes()
382+
if operation_duration_histogram := metrics.get(
383+
GEN_AI_CLIENT_OPERATION_DURATION
384+
):
385+
duration = max((default_timer() - self._operation_start), 0)
386+
operation_duration_histogram.record(
387+
duration,
388+
attributes=metrics_attributes,
389+
)
390+
379391
if token_usage_histogram := metrics.get(GEN_AI_CLIENT_TOKEN_USAGE):
380392
if usage := result.get("usage"):
381-
metrics_attributes = self._extract_metrics_attributes()
382393
if input_tokens := usage.get("inputTokens"):
383394
input_attributes = {
384395
**metrics_attributes,
@@ -543,8 +554,17 @@ def _handle_amazon_titan_response(
543554
event_logger.emit(choice.to_choice_event())
544555

545556
metrics = instrumentor_context.metrics
557+
metrics_attributes = self._extract_metrics_attributes()
558+
if operation_duration_histogram := metrics.get(
559+
GEN_AI_CLIENT_OPERATION_DURATION
560+
):
561+
duration = max((default_timer() - self._operation_start), 0)
562+
operation_duration_histogram.record(
563+
duration,
564+
attributes=metrics_attributes,
565+
)
566+
546567
if token_usage_histogram := metrics.get(GEN_AI_CLIENT_TOKEN_USAGE):
547-
metrics_attributes = self._extract_metrics_attributes()
548568
if input_tokens := response_body.get("inputTextTokenCount"):
549569
input_attributes = {
550570
**metrics_attributes,
@@ -592,9 +612,18 @@ def _handle_amazon_nova_response(
592612
event_logger.emit(choice.to_choice_event())
593613

594614
metrics = instrumentor_context.metrics
615+
metrics_attributes = self._extract_metrics_attributes()
616+
if operation_duration_histogram := metrics.get(
617+
GEN_AI_CLIENT_OPERATION_DURATION
618+
):
619+
duration = max((default_timer() - self._operation_start), 0)
620+
operation_duration_histogram.record(
621+
duration,
622+
attributes=metrics_attributes,
623+
)
624+
595625
if token_usage_histogram := metrics.get(GEN_AI_CLIENT_TOKEN_USAGE):
596626
if usage := response_body.get("usage"):
597-
metrics_attributes = self._extract_metrics_attributes()
598627
if input_tokens := usage.get("inputTokens"):
599628
input_attributes = {
600629
**metrics_attributes,
@@ -642,9 +671,18 @@ def _handle_anthropic_claude_response(
642671
event_logger.emit(choice.to_choice_event())
643672

644673
metrics = instrumentor_context.metrics
674+
metrics_attributes = self._extract_metrics_attributes()
675+
if operation_duration_histogram := metrics.get(
676+
GEN_AI_CLIENT_OPERATION_DURATION
677+
):
678+
duration = max((default_timer() - self._operation_start), 0)
679+
operation_duration_histogram.record(
680+
duration,
681+
attributes=metrics_attributes,
682+
)
683+
645684
if token_usage_histogram := metrics.get(GEN_AI_CLIENT_TOKEN_USAGE):
646685
if usage := response_body.get("usage"):
647-
metrics_attributes = self._extract_metrics_attributes()
648686
if input_tokens := usage.get("input_tokens"):
649687
input_attributes = {
650688
**metrics_attributes,

0 commit comments

Comments
 (0)