Skip to content

Commit be6e5f4

Browse files
committed
Switch to a metric for total tokens used
1 parent 3f37dca commit be6e5f4

File tree

5 files changed

+14
-37
lines changed

5 files changed

+14
-37
lines changed

sentry_sdk/consts.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -97,24 +97,6 @@ class SPANDATA:
9797
Example: [{"role": "user", "message": "hello"}]
9898
"""
9999

100-
AI_COMPLETION_TOKENS_USED = "ai.completion_tokens.used"
101-
"""
102-
The number of tokens used to respond to an AI model request
103-
Example: 10
104-
"""
105-
106-
AI_PROMPT_TOKENS_USED = "ai.prompt_tokens.used"
107-
"""
108-
The number of tokens used to process the input text to an AI model request
109-
Example: 20
110-
"""
111-
112-
AI_TOTAL_TOKENS_USED = "ai.total_tokens.used"
113-
"""
114-
The number of tokens used in total to process an AI model request
115-
Example: 30
116-
"""
117-
118100
AI_MODEL_ID = "ai.model_id"
119101
"""
120102
The unique descriptor of the model being execugted

sentry_sdk/integrations/_ai_common.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
from sentry_sdk import metrics
21
from sentry_sdk._types import TYPE_CHECKING
3-
from sentry_sdk.consts import SPANDATA
42

53
if TYPE_CHECKING:
64
from typing import Any, Optional
@@ -39,19 +37,14 @@ def record_token_usage(
3937
):
4038
# type: (Span, Optional[int], Optional[int], Optional[int]) -> None
4139
if prompt_tokens is not None:
42-
span.set_data(SPANDATA.AI_PROMPT_TOKENS_USED, prompt_tokens)
43-
metrics.incr(SPANDATA.AI_PROMPT_TOKENS_USED, value=prompt_tokens, unit="tokens")
40+
span.set_measurement("ai_prompt_tokens_used", value=prompt_tokens)
4441
if completion_tokens is not None:
45-
span.set_data(SPANDATA.AI_COMPLETION_TOKENS_USED, completion_tokens)
46-
metrics.incr(
47-
SPANDATA.AI_COMPLETION_TOKENS_USED, value=completion_tokens, unit="tokens"
48-
)
42+
span.set_measurement("ai_completion_tokens_used", value=completion_tokens)
4943
if (
5044
total_tokens is None
5145
and prompt_tokens is not None
5246
and completion_tokens is not None
5347
):
5448
total_tokens = prompt_tokens + completion_tokens
5549
if total_tokens is not None:
56-
span.set_data(SPANDATA.AI_TOTAL_TOKENS_USED, total_tokens)
57-
metrics.incr(SPANDATA.AI_TOTAL_TOKENS_USED, value=total_tokens, unit="tokens")
50+
span.set_measurement("ai_total_tokens_used", total_tokens)

sentry_sdk/integrations/langchain.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ def _create_span(self, run_id, parent_id, **kwargs):
136136
span = sentry_sdk.start_span(**kwargs)
137137

138138
span.__enter__()
139+
span.set_data("sdk.integration", "langchain")
139140
watched_span = WatchedSpan(span)
140141
self.span_map[run_id] = watched_span
141142
self.gc_span_map()

sentry_sdk/integrations/openai.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def new_chat_completion(*args, **kwargs):
143143
op=consts.OP.OPENAI_CHAT_COMPLETIONS_CREATE, description="Chat Completion"
144144
)
145145
span.__enter__()
146+
span.set_data("sdk.integration", "openai")
146147
try:
147148
res = f(*args, **kwargs)
148149
except Exception as e:
@@ -225,6 +226,7 @@ def new_embeddings_create(*args, **kwargs):
225226
op=consts.OP.OPENAI_EMBEDDINGS_CREATE,
226227
description="OpenAI Embedding Creation",
227228
) as span:
229+
span.set_data("sdk.integration", "openai")
228230
integration = sentry_sdk.get_client().get_integration(OpenAIIntegration)
229231
if "input" in kwargs and (
230232
should_send_default_pii() and integration.include_prompts

tests/integrations/openai/test_openai.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from openai.types.create_embedding_response import Usage as EmbeddingTokenUsage
88

99
from sentry_sdk import start_transaction
10-
from sentry_sdk.consts import SPANDATA
1110
from sentry_sdk.integrations.openai import OpenAIIntegration
1211

1312
from unittest import mock # python 3.3 and above
@@ -74,9 +73,9 @@ def test_nonstreaming_chat_completion(
7473
assert "ai.input_messages" not in span["data"]
7574
assert "ai.responses" not in span["data"]
7675

77-
assert span["data"][SPANDATA.AI_COMPLETION_TOKENS_USED] == 10
78-
assert span["data"][SPANDATA.AI_PROMPT_TOKENS_USED] == 20
79-
assert span["data"][SPANDATA.AI_TOTAL_TOKENS_USED] == 30
76+
assert span["measurements"]["ai_completion_tokens_used"]["value"] == 10
77+
assert span["measurements"]["ai_prompt_tokens_used"]["value"] == 20
78+
assert span["measurements"]["ai_total_tokens_used"]["value"] == 30
8079

8180

8281
# noinspection PyTypeChecker
@@ -156,9 +155,9 @@ def test_streaming_chat_completion(
156155
try:
157156
import tiktoken # type: ignore # noqa # pylint: disable=unused-import
158157

159-
assert span["data"][SPANDATA.AI_COMPLETION_TOKENS_USED] == 2
160-
assert span["data"][SPANDATA.AI_PROMPT_TOKENS_USED] == 1
161-
assert span["data"][SPANDATA.AI_TOTAL_TOKENS_USED] == 3
158+
assert span["measurements"]["ai_completion_tokens_used"]["value"] == 2
159+
assert span["measurements"]["ai_prompt_tokens_used"]["value"] == 1
160+
assert span["measurements"]["ai_total_tokens_used"]["value"] == 3
162161
except ImportError:
163162
pass # if tiktoken is not installed, we can't guarantee token usage will be calculated properly
164163

@@ -223,5 +222,5 @@ def test_embeddings_create(
223222
else:
224223
assert "ai.input_messages" not in span["data"]
225224

226-
assert span["data"][SPANDATA.AI_PROMPT_TOKENS_USED] == 20
227-
assert span["data"][SPANDATA.AI_TOTAL_TOKENS_USED] == 30
225+
assert span["measurements"]["ai_prompt_tokens_used"]["value"] == 20
226+
assert span["measurements"]["ai_total_tokens_used"]["value"] == 30

0 commit comments

Comments
 (0)