Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ asgiref==3.8.1
# via opentelemetry-test-utils
build==1.2.2.post1
# via pip-tools
certifi==2024.8.30
certifi==2025.1.31
# via
# httpcore
# httpx
click==8.1.7
click==8.1.8
# via pip-tools
deprecated==1.2.15
deprecated==1.2.18
# via
# opentelemetry-api
# opentelemetry-semantic-conventions
Expand All @@ -47,31 +47,31 @@ importlib-metadata==8.5.0
# opentelemetry-api
iniconfig==2.0.0
# via pytest
jiter==0.7.1
jiter==0.9.0
# via openai
multidict==6.1.0
# via yarl
numpy==1.24.4
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
openai==1.54.4
openai==1.66.5
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
opentelemetry-api==1.28.2
opentelemetry-api==1.31.0
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# opentelemetry-instrumentation
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# opentelemetry-test-utils
opentelemetry-instrumentation==0.49b2
opentelemetry-instrumentation==0.52b0
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
opentelemetry-sdk==1.28.2
opentelemetry-sdk==1.31.0
# via opentelemetry-test-utils
opentelemetry-semantic-conventions==0.49b2
opentelemetry-semantic-conventions==0.52b0
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# opentelemetry-instrumentation
# opentelemetry-sdk
opentelemetry-test-utils==0.49b2
opentelemetry-test-utils==0.52b0
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
packaging==24.2
# via
Expand All @@ -84,15 +84,17 @@ pluggy==1.5.0
# via pytest
propcache==0.2.0
# via yarl
pydantic==2.9.2
# via openai
pydantic-core==2.23.4
pydantic==2.10.6
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# openai
pydantic-core==2.27.2
# via pydantic
pyproject-hooks==1.2.0
# via
# build
# pip-tools
pytest==8.3.3
pytest==8.3.5
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# pytest-asyncio
Expand All @@ -106,14 +108,13 @@ pyyaml==6.0.2
sniffio==1.3.1
# via
# anyio
# httpx
# openai
tomli==2.1.0
tomli==2.2.1
# via
# build
# pip-tools
# pytest
tqdm==4.67.0
tqdm==4.67.1
# via openai
typing-extensions==4.12.2
# via
Expand All @@ -131,9 +132,9 @@ vcrpy==6.0.2
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# pytest-vcr
wheel==0.45.0
wheel==0.45.1
# via pip-tools
wrapt==1.16.0
wrapt==1.17.2
# via
# deprecated
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@
#
annotated-types==0.7.0
# via pydantic
anyio==4.6.2.post1
anyio==4.9.0
# via
# httpx
# openai
asgiref==3.8.1
# via opentelemetry-test-utils
build==1.2.2.post1
# via pip-tools
certifi==2024.8.30
certifi==2025.1.31
# via
# httpcore
# httpx
click==8.1.7
click==8.1.8
# via pip-tools
deprecated==1.2.15
deprecated==1.2.18
# via
# opentelemetry-api
# opentelemetry-semantic-conventions
Expand All @@ -41,35 +41,35 @@ idna==3.10
# anyio
# httpx
# yarl
importlib-metadata==8.5.0
importlib-metadata==8.6.1
# via opentelemetry-api
iniconfig==2.0.0
# via pytest
jiter==0.7.1
jiter==0.9.0
# via openai
multidict==6.1.0
multidict==6.2.0
# via yarl
numpy==2.1.3
numpy==2.2.4
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
openai==1.54.4
openai==1.66.5
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
opentelemetry-api==1.28.2
opentelemetry-api==1.31.0
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# opentelemetry-instrumentation
# opentelemetry-sdk
# opentelemetry-semantic-conventions
# opentelemetry-test-utils
opentelemetry-instrumentation==0.49b2
opentelemetry-instrumentation==0.52b0
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
opentelemetry-sdk==1.28.2
opentelemetry-sdk==1.31.0
# via opentelemetry-test-utils
opentelemetry-semantic-conventions==0.49b2
opentelemetry-semantic-conventions==0.52b0
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# opentelemetry-instrumentation
# opentelemetry-sdk
opentelemetry-test-utils==0.49b2
opentelemetry-test-utils==0.52b0
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
packaging==24.2
# via
Expand All @@ -80,22 +80,24 @@ pip-tools==7.4.1
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
pluggy==1.5.0
# via pytest
propcache==0.2.0
propcache==0.3.0
# via yarl
pydantic==2.9.2
# via openai
pydantic-core==2.23.4
pydantic==2.10.6
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# openai
pydantic-core==2.27.2
# via pydantic
pyproject-hooks==1.2.0
# via
# build
# pip-tools
pytest==8.3.3
pytest==8.3.5
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# pytest-asyncio
# pytest-vcr
pytest-asyncio==0.24.0
pytest-asyncio==0.25.3
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
pytest-vcr==1.0.2
# via elastic-opentelemetry-instrumentation-openai (pyproject.toml)
Expand All @@ -104,14 +106,13 @@ pyyaml==6.0.2
sniffio==1.3.1
# via
# anyio
# httpx
# openai
tomli==2.1.0
tomli==2.2.1
# via
# build
# pip-tools
# pytest
tqdm==4.67.0
tqdm==4.67.1
# via openai
typing-extensions==4.12.2
# via
Expand All @@ -122,21 +123,21 @@ typing-extensions==4.12.2
# opentelemetry-sdk
# pydantic
# pydantic-core
urllib3==2.2.3
urllib3==2.3.0
# via vcrpy
vcrpy==6.0.2
vcrpy==7.0.0
# via
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# pytest-vcr
wheel==0.45.0
wheel==0.45.1
# via pip-tools
wrapt==1.16.0
wrapt==1.17.2
# via
# deprecated
# elastic-opentelemetry-instrumentation-openai (pyproject.toml)
# opentelemetry-instrumentation
# vcrpy
yarl==1.17.2
yarl==1.18.3
# via vcrpy
zipp==3.21.0
# via importlib-metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ classifiers = [
"Programming Language :: Python :: 3.12",
]
dependencies = [
# 1.28.2 is required for *robust* Events API/SDK
"opentelemetry-api ~= 1.28",
"opentelemetry-instrumentation ~= 0.49b2",
"opentelemetry-semantic-conventions ~= 0.49b2",
# 1.31.0 is required for proper histogram bucket advisory support
"opentelemetry-api ~= 1.31",
"opentelemetry-instrumentation ~= 0.52b0",
"opentelemetry-semantic-conventions ~= 0.52b0",
"wrapt >= 1.0.0, < 2.0.0",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@
_send_log_events_from_messages,
_span_name_from_attributes,
)
from opentelemetry.instrumentation.openai.metrics import (
_GEN_AI_CLIENT_OPERATION_DURATION_BUCKETS,
_GEN_AI_CLIENT_TOKEN_USAGE_BUCKETS,
)
from opentelemetry.instrumentation.openai.package import _instruments
from opentelemetry.instrumentation.openai.version import __version__
from opentelemetry.instrumentation.openai.wrappers import StreamWrapper
from opentelemetry.instrumentation.utils import unwrap
from opentelemetry.metrics import get_meter
from opentelemetry.semconv._incubating.metrics.gen_ai_metrics import (
create_gen_ai_client_operation_duration,
create_gen_ai_client_token_usage,
GEN_AI_CLIENT_OPERATION_DURATION,
GEN_AI_CLIENT_TOKEN_USAGE,
)
from opentelemetry.semconv.attributes.error_attributes import ERROR_TYPE
from opentelemetry.semconv.schemas import Schemas
Expand Down Expand Up @@ -94,8 +98,19 @@ def _instrument(self, **kwargs):
event_logger_provider = kwargs.get("event_logger_provider")
self.event_logger = get_event_logger(__name__, event_logger_provider)

self.token_usage_metric = create_gen_ai_client_token_usage(self.meter)
self.operation_duration_metric = create_gen_ai_client_operation_duration(self.meter)
self.token_usage_metric = self.meter.create_histogram(
name=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,
)

self.operation_duration_metric = self.meter.create_histogram(
name=GEN_AI_CLIENT_OPERATION_DURATION,
description="GenAI operation duration",
unit="s",
explicit_bucket_boundaries_advisory=_GEN_AI_CLIENT_OPERATION_DURATION_BUCKETS,
)

register_post_import_hook(self._patch, "openai")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
# or more contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright
# ownership. Elasticsearch B.V. licenses this file to you under
# the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

_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,
]
Loading