diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst
index d378698c9..c3601589c 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/README.rst
@@ -75,48 +75,6 @@ To uninstrument clients, call the uninstrument method:
# Uninstrument all clients
OpenAIInstrumentor().uninstrument()
-Bucket Boundaries
------------------
-
-This section describes the explicit bucket boundaries for metrics such as token usage and operation duration, and guides users to create Views to implement them according to the semantic conventions.
-
-The bucket boundaries are defined as follows:
-
-- For `gen_ai.client.token.usage`: [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864]
-- For `gen_ai.client.operation.duration`: [0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48, 40.96, 81.92]
-
-To implement these bucket boundaries, you can create Views in your OpenTelemetry SDK setup. Here is an example:
-
-.. code-block:: python
-
- from opentelemetry.sdk.metrics import MeterProvider, View
- from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
- from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter
- from opentelemetry.sdk.metrics.aggregation import ExplicitBucketHistogramAggregation
-
- views = [
- View(
- instrument_name="gen_ai.client.token.usage",
- aggregation=ExplicitBucketHistogramAggregation([1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864]),
- ),
- View(
- instrument_name="gen_ai.client.operation.duration",
- aggregation=ExplicitBucketHistogramAggregation([0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24, 20.48, 40.96, 81.92]),
- ),
- ]
-
- metric_exporter = OTLPMetricExporter(endpoint="http://localhost:4317")
- metric_reader = PeriodicExportingMetricReader(metric_exporter)
- provider = MeterProvider(
- metric_readers=[metric_reader],
- views=views
- )
-
- from opentelemetry.sdk.metrics import set_meter_provider
- set_meter_provider(provider)
-
-For more details, refer to the `OpenTelemetry GenAI Metrics documentation `_.
-
References
----------
* `OpenTelemetry OpenAI Instrumentation `_
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt
index 75b6bee8f..384c64be4 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/manual/requirements.txt
@@ -1,5 +1,5 @@
openai~=1.57.3
-opentelemetry-sdk~=1.29.0
-opentelemetry-exporter-otlp-proto-grpc~=1.29.0
-opentelemetry-instrumentation-openai-v2~=2.0b0
+opentelemetry-sdk~=1.30.0
+opentelemetry-exporter-otlp-proto-grpc~=1.30.0
+opentelemetry-instrumentation-openai-v2~=2.2b0
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt
index df462da75..708dc9590 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/examples/zero-code/requirements.txt
@@ -1,6 +1,6 @@
openai~=1.57.3
-opentelemetry-sdk~=1.29.0
-opentelemetry-exporter-otlp-proto-grpc~=1.29.0
-opentelemetry-distro~=0.50b0
-opentelemetry-instrumentation-openai-v2~=2.0b0
+opentelemetry-sdk~=1.30.0
+opentelemetry-exporter-otlp-proto-grpc~=1.30.0
+opentelemetry-distro~=0.51b0
+opentelemetry-instrumentation-openai-v2~=2.2b0
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml
index fdc0afc9c..377a97e7b 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/pyproject.toml
@@ -26,9 +26,9 @@ classifiers = [
"Programming Language :: Python :: 3.13",
]
dependencies = [
- "opentelemetry-api ~= 1.28",
- "opentelemetry-instrumentation ~= 0.49b0",
- "opentelemetry-semantic-conventions ~= 0.49b0"
+ "opentelemetry-api ~= 1.30",
+ "opentelemetry-instrumentation ~= 0.51b0",
+ "opentelemetry-semantic-conventions ~= 0.51b0"
]
[project.optional-dependencies]
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py
index d1e184ac8..70c10055e 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/src/opentelemetry/instrumentation/openai_v2/instruments.py
@@ -1,11 +1,52 @@
+from opentelemetry.metrics import Histogram, Meter
from opentelemetry.semconv._incubating.metrics import gen_ai_metrics
+_GEN_AI_CLIENT_OPERATION_DURATION_BUCKETS = [
+ 0.01,
+ 0.02,
+ 0.04,
+ 0.08,
+ 0.16,
+ 0.32,
+ 0.64,
+ 1.28,
+ 2.56,
+ 5.12,
+ 10.24,
+ 20.48,
+ 40.96,
+ 81.92,
+]
+
+_GEN_AI_CLIENT_TOKEN_USAGE_BUCKETS = [
+ 1,
+ 4,
+ 16,
+ 64,
+ 256,
+ 1024,
+ 4096,
+ 16384,
+ 65536,
+ 262144,
+ 1048576,
+ 4194304,
+ 16777216,
+ 67108864,
+]
+
class Instruments:
- def __init__(self, meter):
- self.operation_duration_histogram = (
- gen_ai_metrics.create_gen_ai_client_operation_duration(meter)
+ def __init__(self, meter: Meter):
+ self.operation_duration_histogram: Histogram = meter.create_histogram(
+ name=gen_ai_metrics.GEN_AI_CLIENT_OPERATION_DURATION,
+ description="GenAI operation duration",
+ unit="s",
+ explicit_bucket_boundaries_advisory=_GEN_AI_CLIENT_OPERATION_DURATION_BUCKETS,
)
- self.token_usage_histogram = (
- gen_ai_metrics.create_gen_ai_client_token_usage(meter)
+ self.token_usage_histogram: Histogram = meter.create_histogram(
+ name=gen_ai_metrics.GEN_AI_CLIENT_TOKEN_USAGE,
+ description="Measures number of input and output tokens used",
+ unit="{token}",
+ explicit_bucket_boundaries_advisory=_GEN_AI_CLIENT_TOKEN_USAGE_BUCKETS,
)
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt
index bd22b7a87..4e88239d1 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/test-requirements-0.txt
@@ -8,9 +8,9 @@ pytest==7.4.4
pytest-vcr==1.0.2
pytest-asyncio==0.21.0
wrapt==1.16.0
-opentelemetry-exporter-otlp-proto-http~=1.28
-opentelemetry-api==1.28 # when updating, also update in pyproject.toml
-opentelemetry-sdk==1.28 # when updating, also update in pyproject.toml
-opentelemetry-semantic-conventions==0.49b0 # when updating, also update in pyproject.toml
+opentelemetry-exporter-otlp-proto-http~=1.30
+opentelemetry-api==1.30 # when updating, also update in pyproject.toml
+opentelemetry-sdk==1.30 # when updating, also update in pyproject.toml
+opentelemetry-semantic-conventions==0.51b0 # when updating, also update in pyproject.toml
-e instrumentation-genai/opentelemetry-instrumentation-openai-v2
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py
index 5b80b49d6..87505046a 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/conftest.py
@@ -18,16 +18,11 @@ from opentelemetry.sdk._logs.export import (
SimpleLogRecordProcessor,
)
from opentelemetry.sdk.metrics import (
- Histogram,
MeterProvider,
)
from opentelemetry.sdk.metrics.export import (
InMemoryMetricReader,
)
-from opentelemetry.sdk.metrics.view import (
- ExplicitBucketHistogramAggregation,
- View,
-)
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import SimpleSpanProcessor
from opentelemetry.sdk.trace.export.in_memory_span_exporter import (
@@ -72,55 +67,8 @@ def fixture_event_logger_provider(log_exporter):
@pytest.fixture(scope="function", name="meter_provider")
def fixture_meter_provider(metric_reader):
- token_usage_histogram_view = View(
- instrument_type=Histogram,
- instrument_name="gen_ai.client.token.usage",
- aggregation=ExplicitBucketHistogramAggregation(
- boundaries=[
- 1,
- 4,
- 16,
- 64,
- 256,
- 1024,
- 4096,
- 16384,
- 65536,
- 262144,
- 1048576,
- 4194304,
- 16777216,
- 67108864,
- ]
- ),
- )
-
- duration_histogram_view = View(
- instrument_type=Histogram,
- instrument_name="gen_ai.client.operation.duration",
- aggregation=ExplicitBucketHistogramAggregation(
- boundaries=[
- 0.01,
- 0.02,
- 0.04,
- 0.08,
- 0.16,
- 0.32,
- 0.64,
- 1.28,
- 2.56,
- 5.12,
- 10.24,
- 20.48,
- 40.96,
- 81.92,
- ]
- ),
- )
-
meter_provider = MeterProvider(
metric_readers=[metric_reader],
- views=[token_usage_histogram_view, duration_histogram_view],
)
return meter_provider
diff --git a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py
index d0f7c5a59..ffcd99c5b 100644
--- a/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py
+++ b/instrumentation-genai/opentelemetry-instrumentation-openai-v2/tests/test_chat_metrics.py
@@ -8,6 +8,39 @@ from opentelemetry.semconv._incubating.attributes import (
)
from opentelemetry.semconv._incubating.metrics import gen_ai_metrics
+_DURATION_BUCKETS = (
+ 0.01,
+ 0.02,
+ 0.04,
+ 0.08,
+ 0.16,
+ 0.32,
+ 0.64,
+ 1.28,
+ 2.56,
+ 5.12,
+ 10.24,
+ 20.48,
+ 40.96,
+ 81.92,
+)
+_TOKEN_USAGE_BUCKETS = (
+ 1,
+ 4,
+ 16,
+ 64,
+ 256,
+ 1024,
+ 4096,
+ 16384,
+ 65536,
+ 262144,
+ 1048576,
+ 4194304,
+ 16777216,
+ 67108864,
+)
+
def assert_all_metric_attributes(data_point):
assert GenAIAttributes.GEN_AI_OPERATION_NAME in data_point.attributes
@@ -77,8 +110,11 @@ def test_chat_completion_metrics(
None,
)
assert duration_metric is not None
- assert duration_metric.data.data_points[0].sum > 0
- assert_all_metric_attributes(duration_metric.data.data_points[0])
+
+ duration_point = duration_metric.data.data_points[0]
+ assert duration_point.sum > 0
+ assert_all_metric_attributes(duration_point)
+ assert duration_point.explicit_bounds == _DURATION_BUCKETS
token_usage_metric = next(
(
@@ -101,7 +137,8 @@ def test_chat_completion_metrics(
)
assert input_token_usage is not None
assert input_token_usage.sum == 12
- # assert against buckets [1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864]
+
+ assert input_token_usage.explicit_bounds == _TOKEN_USAGE_BUCKETS
assert input_token_usage.bucket_counts[2] == 1
assert_all_metric_attributes(input_token_usage)