sentry-sdk 2.26.1__py2.py3-none-any.whl → 3.0.0a1__py2.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.

Potentially problematic release.


This version of sentry-sdk might be problematic. Click here for more details.

Files changed (114) hide show
  1. sentry_sdk/__init__.py +4 -8
  2. sentry_sdk/_compat.py +0 -1
  3. sentry_sdk/_init_implementation.py +6 -44
  4. sentry_sdk/_log_batcher.py +47 -28
  5. sentry_sdk/_types.py +8 -64
  6. sentry_sdk/ai/monitoring.py +14 -10
  7. sentry_sdk/ai/utils.py +1 -1
  8. sentry_sdk/api.py +69 -163
  9. sentry_sdk/client.py +25 -72
  10. sentry_sdk/consts.py +42 -23
  11. sentry_sdk/debug.py +0 -10
  12. sentry_sdk/envelope.py +2 -10
  13. sentry_sdk/feature_flags.py +5 -1
  14. sentry_sdk/integrations/__init__.py +5 -2
  15. sentry_sdk/integrations/_asgi_common.py +3 -3
  16. sentry_sdk/integrations/_wsgi_common.py +11 -40
  17. sentry_sdk/integrations/aiohttp.py +104 -57
  18. sentry_sdk/integrations/anthropic.py +10 -7
  19. sentry_sdk/integrations/arq.py +24 -13
  20. sentry_sdk/integrations/asgi.py +103 -83
  21. sentry_sdk/integrations/asyncio.py +1 -0
  22. sentry_sdk/integrations/asyncpg.py +45 -30
  23. sentry_sdk/integrations/aws_lambda.py +109 -92
  24. sentry_sdk/integrations/boto3.py +38 -9
  25. sentry_sdk/integrations/bottle.py +1 -1
  26. sentry_sdk/integrations/celery/__init__.py +48 -38
  27. sentry_sdk/integrations/clickhouse_driver.py +59 -28
  28. sentry_sdk/integrations/cohere.py +2 -0
  29. sentry_sdk/integrations/django/__init__.py +25 -46
  30. sentry_sdk/integrations/django/asgi.py +6 -2
  31. sentry_sdk/integrations/django/caching.py +13 -22
  32. sentry_sdk/integrations/django/middleware.py +1 -0
  33. sentry_sdk/integrations/django/signals_handlers.py +3 -1
  34. sentry_sdk/integrations/django/templates.py +8 -12
  35. sentry_sdk/integrations/django/transactions.py +1 -6
  36. sentry_sdk/integrations/django/views.py +5 -2
  37. sentry_sdk/integrations/falcon.py +7 -25
  38. sentry_sdk/integrations/fastapi.py +3 -3
  39. sentry_sdk/integrations/flask.py +1 -1
  40. sentry_sdk/integrations/gcp.py +63 -38
  41. sentry_sdk/integrations/graphene.py +6 -13
  42. sentry_sdk/integrations/grpc/aio/client.py +14 -8
  43. sentry_sdk/integrations/grpc/aio/server.py +19 -21
  44. sentry_sdk/integrations/grpc/client.py +8 -6
  45. sentry_sdk/integrations/grpc/server.py +12 -14
  46. sentry_sdk/integrations/httpx.py +47 -12
  47. sentry_sdk/integrations/huey.py +26 -22
  48. sentry_sdk/integrations/huggingface_hub.py +1 -0
  49. sentry_sdk/integrations/langchain.py +22 -15
  50. sentry_sdk/integrations/launchdarkly.py +3 -3
  51. sentry_sdk/integrations/litestar.py +4 -2
  52. sentry_sdk/integrations/logging.py +12 -3
  53. sentry_sdk/integrations/openai.py +2 -0
  54. sentry_sdk/integrations/openfeature.py +3 -5
  55. sentry_sdk/integrations/pymongo.py +18 -25
  56. sentry_sdk/integrations/pyramid.py +1 -1
  57. sentry_sdk/integrations/quart.py +3 -3
  58. sentry_sdk/integrations/ray.py +23 -17
  59. sentry_sdk/integrations/redis/_async_common.py +30 -18
  60. sentry_sdk/integrations/redis/_sync_common.py +28 -18
  61. sentry_sdk/integrations/redis/modules/caches.py +13 -10
  62. sentry_sdk/integrations/redis/modules/queries.py +14 -11
  63. sentry_sdk/integrations/redis/rb.py +4 -4
  64. sentry_sdk/integrations/redis/redis.py +6 -6
  65. sentry_sdk/integrations/redis/redis_cluster.py +18 -16
  66. sentry_sdk/integrations/redis/redis_py_cluster_legacy.py +4 -4
  67. sentry_sdk/integrations/redis/utils.py +63 -19
  68. sentry_sdk/integrations/rq.py +68 -23
  69. sentry_sdk/integrations/rust_tracing.py +28 -43
  70. sentry_sdk/integrations/sanic.py +23 -13
  71. sentry_sdk/integrations/socket.py +9 -5
  72. sentry_sdk/integrations/sqlalchemy.py +8 -8
  73. sentry_sdk/integrations/starlette.py +11 -31
  74. sentry_sdk/integrations/starlite.py +4 -2
  75. sentry_sdk/integrations/stdlib.py +56 -9
  76. sentry_sdk/integrations/strawberry.py +40 -59
  77. sentry_sdk/integrations/threading.py +10 -26
  78. sentry_sdk/integrations/tornado.py +57 -18
  79. sentry_sdk/integrations/trytond.py +4 -1
  80. sentry_sdk/integrations/unleash.py +2 -3
  81. sentry_sdk/integrations/wsgi.py +84 -38
  82. sentry_sdk/opentelemetry/__init__.py +9 -0
  83. sentry_sdk/opentelemetry/consts.py +33 -0
  84. sentry_sdk/opentelemetry/contextvars_context.py +73 -0
  85. sentry_sdk/{integrations/opentelemetry → opentelemetry}/propagator.py +19 -28
  86. sentry_sdk/opentelemetry/sampler.py +326 -0
  87. sentry_sdk/opentelemetry/scope.py +218 -0
  88. sentry_sdk/opentelemetry/span_processor.py +329 -0
  89. sentry_sdk/opentelemetry/tracing.py +35 -0
  90. sentry_sdk/opentelemetry/utils.py +476 -0
  91. sentry_sdk/profiler/__init__.py +0 -40
  92. sentry_sdk/profiler/continuous_profiler.py +1 -30
  93. sentry_sdk/profiler/transaction_profiler.py +5 -56
  94. sentry_sdk/scope.py +107 -351
  95. sentry_sdk/sessions.py +0 -87
  96. sentry_sdk/tracing.py +418 -1134
  97. sentry_sdk/tracing_utils.py +134 -169
  98. sentry_sdk/transport.py +4 -104
  99. sentry_sdk/types.py +26 -2
  100. sentry_sdk/utils.py +169 -152
  101. {sentry_sdk-2.26.1.dist-info → sentry_sdk-3.0.0a1.dist-info}/METADATA +3 -5
  102. sentry_sdk-3.0.0a1.dist-info/RECORD +154 -0
  103. {sentry_sdk-2.26.1.dist-info → sentry_sdk-3.0.0a1.dist-info}/WHEEL +1 -1
  104. sentry_sdk-3.0.0a1.dist-info/entry_points.txt +2 -0
  105. sentry_sdk/hub.py +0 -739
  106. sentry_sdk/integrations/opentelemetry/__init__.py +0 -7
  107. sentry_sdk/integrations/opentelemetry/consts.py +0 -5
  108. sentry_sdk/integrations/opentelemetry/integration.py +0 -58
  109. sentry_sdk/integrations/opentelemetry/span_processor.py +0 -391
  110. sentry_sdk/metrics.py +0 -965
  111. sentry_sdk-2.26.1.dist-info/RECORD +0 -152
  112. sentry_sdk-2.26.1.dist-info/entry_points.txt +0 -2
  113. {sentry_sdk-2.26.1.dist-info → sentry_sdk-3.0.0a1.dist-info}/licenses/LICENSE +0 -0
  114. {sentry_sdk-2.26.1.dist-info → sentry_sdk-3.0.0a1.dist-info}/top_level.txt +0 -0
sentry_sdk/__init__.py CHANGED
@@ -1,4 +1,6 @@
1
- from sentry_sdk.scope import Scope
1
+ # TODO-neel scope switch
2
+ # TODO-neel avoid duplication between api and __init__
3
+ from sentry_sdk.opentelemetry.scope import PotelScope as Scope
2
4
  from sentry_sdk.transport import Transport, HttpTransport
3
5
  from sentry_sdk.client import Client
4
6
 
@@ -7,7 +9,6 @@ from sentry_sdk.api import * # noqa
7
9
  from sentry_sdk.consts import VERSION # noqa
8
10
 
9
11
  __all__ = [ # noqa
10
- "Hub",
11
12
  "Scope",
12
13
  "Client",
13
14
  "Transport",
@@ -15,11 +16,11 @@ __all__ = [ # noqa
15
16
  "integrations",
16
17
  # From sentry_sdk.api
17
18
  "init",
19
+ "add_attachment",
18
20
  "add_breadcrumb",
19
21
  "capture_event",
20
22
  "capture_exception",
21
23
  "capture_message",
22
- "configure_scope",
23
24
  "continue_trace",
24
25
  "flush",
25
26
  "get_baggage",
@@ -33,11 +34,9 @@ __all__ = [ # noqa
33
34
  "isolation_scope",
34
35
  "last_event_id",
35
36
  "new_scope",
36
- "push_scope",
37
37
  "set_context",
38
38
  "set_extra",
39
39
  "set_level",
40
- "set_measurement",
41
40
  "set_tag",
42
41
  "set_tags",
43
42
  "set_user",
@@ -53,6 +52,3 @@ from sentry_sdk.debug import init_debug_support
53
52
 
54
53
  init_debug_support()
55
54
  del init_debug_support
56
-
57
- # circular imports
58
- from sentry_sdk.hub import Hub
sentry_sdk/_compat.py CHANGED
@@ -9,7 +9,6 @@ if TYPE_CHECKING:
9
9
  T = TypeVar("T")
10
10
 
11
11
 
12
- PY37 = sys.version_info[0] == 3 and sys.version_info[1] >= 7
13
12
  PY38 = sys.version_info[0] == 3 and sys.version_info[1] >= 8
14
13
  PY310 = sys.version_info[0] == 3 and sys.version_info[1] >= 10
15
14
  PY311 = sys.version_info[0] == 3 and sys.version_info[1] >= 11
@@ -1,48 +1,11 @@
1
- import warnings
2
-
3
1
  from typing import TYPE_CHECKING
4
2
 
5
3
  import sentry_sdk
4
+ from sentry_sdk.consts import ClientConstructor
5
+ from sentry_sdk.opentelemetry.scope import setup_scope_context_management
6
6
 
7
7
  if TYPE_CHECKING:
8
- from typing import Any, ContextManager, Optional
9
-
10
- import sentry_sdk.consts
11
-
12
-
13
- class _InitGuard:
14
- _CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE = (
15
- "Using the return value of sentry_sdk.init as a context manager "
16
- "and manually calling the __enter__ and __exit__ methods on the "
17
- "return value are deprecated. We are no longer maintaining this "
18
- "functionality, and we will remove it in the next major release."
19
- )
20
-
21
- def __init__(self, client):
22
- # type: (sentry_sdk.Client) -> None
23
- self._client = client
24
-
25
- def __enter__(self):
26
- # type: () -> _InitGuard
27
- warnings.warn(
28
- self._CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE,
29
- stacklevel=2,
30
- category=DeprecationWarning,
31
- )
32
-
33
- return self
34
-
35
- def __exit__(self, exc_type, exc_value, tb):
36
- # type: (Any, Any, Any) -> None
37
- warnings.warn(
38
- self._CONTEXT_MANAGER_DEPRECATION_WARNING_MESSAGE,
39
- stacklevel=2,
40
- category=DeprecationWarning,
41
- )
42
-
43
- c = self._client
44
- if c is not None:
45
- c.close()
8
+ from typing import Any, Optional
46
9
 
47
10
 
48
11
  def _check_python_deprecations():
@@ -54,16 +17,15 @@ def _check_python_deprecations():
54
17
 
55
18
 
56
19
  def _init(*args, **kwargs):
57
- # type: (*Optional[str], **Any) -> ContextManager[Any]
20
+ # type: (*Optional[str], **Any) -> None
58
21
  """Initializes the SDK and optionally integrations.
59
22
 
60
23
  This takes the same arguments as the client constructor.
61
24
  """
25
+ setup_scope_context_management()
62
26
  client = sentry_sdk.Client(*args, **kwargs)
63
27
  sentry_sdk.get_global_scope().set_client(client)
64
28
  _check_python_deprecations()
65
- rv = _InitGuard(client)
66
- return rv
67
29
 
68
30
 
69
31
  if TYPE_CHECKING:
@@ -73,7 +35,7 @@ if TYPE_CHECKING:
73
35
  # Use `ClientConstructor` to define the argument types of `init` and
74
36
  # `ContextManager[Any]` to tell static analyzers about the return type.
75
37
 
76
- class init(sentry_sdk.consts.ClientConstructor, _InitGuard): # noqa: N801
38
+ class init(ClientConstructor): # noqa: N801
77
39
  pass
78
40
 
79
41
  else:
@@ -5,7 +5,7 @@ from datetime import datetime, timezone
5
5
  from typing import Optional, List, Callable, TYPE_CHECKING, Any
6
6
 
7
7
  from sentry_sdk.utils import format_timestamp, safe_repr
8
- from sentry_sdk.envelope import Envelope
8
+ from sentry_sdk.envelope import Envelope, Item, PayloadRef
9
9
 
10
10
  if TYPE_CHECKING:
11
11
  from sentry_sdk._types import Log
@@ -97,34 +97,36 @@ class LogBatcher:
97
97
  self._flush()
98
98
 
99
99
  @staticmethod
100
- def _log_to_otel(log):
100
+ def _log_to_transport_format(log):
101
101
  # type: (Log) -> Any
102
- def format_attribute(key, val):
103
- # type: (str, int | float | str | bool) -> Any
102
+ def format_attribute(val):
103
+ # type: (int | float | str | bool) -> Any
104
104
  if isinstance(val, bool):
105
- return {"key": key, "value": {"boolValue": val}}
105
+ return {"value": val, "type": "boolean"}
106
106
  if isinstance(val, int):
107
- return {"key": key, "value": {"intValue": str(val)}}
107
+ return {"value": val, "type": "integer"}
108
108
  if isinstance(val, float):
109
- return {"key": key, "value": {"doubleValue": val}}
109
+ return {"value": val, "type": "double"}
110
110
  if isinstance(val, str):
111
- return {"key": key, "value": {"stringValue": val}}
112
- return {"key": key, "value": {"stringValue": safe_repr(val)}}
113
-
114
- otel_log = {
115
- "severityText": log["severity_text"],
116
- "severityNumber": log["severity_number"],
117
- "body": {"stringValue": log["body"]},
118
- "timeUnixNano": str(log["time_unix_nano"]),
119
- "attributes": [
120
- format_attribute(k, v) for (k, v) in log["attributes"].items()
121
- ],
111
+ return {"value": val, "type": "string"}
112
+ return {"value": safe_repr(val), "type": "string"}
113
+
114
+ if "sentry.severity_number" not in log["attributes"]:
115
+ log["attributes"]["sentry.severity_number"] = log["severity_number"]
116
+ if "sentry.severity_text" not in log["attributes"]:
117
+ log["attributes"]["sentry.severity_text"] = log["severity_text"]
118
+
119
+ res = {
120
+ "timestamp": int(log["time_unix_nano"]) / 1.0e9,
121
+ "trace_id": log.get("trace_id", "00000000-0000-0000-0000-000000000000"),
122
+ "level": str(log["severity_text"]),
123
+ "body": str(log["body"]),
124
+ "attributes": {
125
+ k: format_attribute(v) for (k, v) in log["attributes"].items()
126
+ },
122
127
  }
123
128
 
124
- if "trace_id" in log:
125
- otel_log["traceId"] = log["trace_id"]
126
-
127
- return otel_log
129
+ return res
128
130
 
129
131
  def _flush(self):
130
132
  # type: (...) -> Optional[Envelope]
@@ -133,10 +135,27 @@ class LogBatcher:
133
135
  headers={"sent_at": format_timestamp(datetime.now(timezone.utc))}
134
136
  )
135
137
  with self._lock:
136
- for log in self._log_buffer:
137
- envelope.add_log(self._log_to_otel(log))
138
+ if len(self._log_buffer) == 0:
139
+ return None
140
+
141
+ envelope.add_item(
142
+ Item(
143
+ type="log",
144
+ content_type="application/vnd.sentry.items.log+json",
145
+ headers={
146
+ "item_count": len(self._log_buffer),
147
+ },
148
+ payload=PayloadRef(
149
+ json={
150
+ "items": [
151
+ self._log_to_transport_format(log)
152
+ for log in self._log_buffer
153
+ ]
154
+ }
155
+ ),
156
+ )
157
+ )
138
158
  self._log_buffer.clear()
139
- if envelope.items:
140
- self._capture_func(envelope)
141
- return envelope
142
- return None
159
+
160
+ self._capture_func(envelope)
161
+ return envelope
sentry_sdk/_types.py CHANGED
@@ -107,9 +107,7 @@ if TYPE_CHECKING:
107
107
  from typing import Callable
108
108
  from typing import Dict
109
109
  from typing import Mapping
110
- from typing import NotRequired
111
110
  from typing import Optional
112
- from typing import Tuple
113
111
  from typing import Type
114
112
  from typing_extensions import Literal, TypedDict
115
113
 
@@ -121,45 +119,6 @@ if TYPE_CHECKING:
121
119
  # "critical" is an alias of "fatal" recognized by Relay
122
120
  LogLevelStr = Literal["fatal", "critical", "error", "warning", "info", "debug"]
123
121
 
124
- DurationUnit = Literal[
125
- "nanosecond",
126
- "microsecond",
127
- "millisecond",
128
- "second",
129
- "minute",
130
- "hour",
131
- "day",
132
- "week",
133
- ]
134
-
135
- InformationUnit = Literal[
136
- "bit",
137
- "byte",
138
- "kilobyte",
139
- "kibibyte",
140
- "megabyte",
141
- "mebibyte",
142
- "gigabyte",
143
- "gibibyte",
144
- "terabyte",
145
- "tebibyte",
146
- "petabyte",
147
- "pebibyte",
148
- "exabyte",
149
- "exbibyte",
150
- ]
151
-
152
- FractionUnit = Literal["ratio", "percent"]
153
- MeasurementUnit = Union[DurationUnit, InformationUnit, FractionUnit, str]
154
-
155
- MeasurementValue = TypedDict(
156
- "MeasurementValue",
157
- {
158
- "value": float,
159
- "unit": NotRequired[Optional[MeasurementUnit]],
160
- },
161
- )
162
-
163
122
  Event = TypedDict(
164
123
  "Event",
165
124
  {
@@ -181,7 +140,6 @@ if TYPE_CHECKING:
181
140
  "level": LogLevelStr,
182
141
  "logentry": Mapping[str, object],
183
142
  "logger": str,
184
- "measurements": dict[str, MeasurementValue],
185
143
  "message": str,
186
144
  "modules": dict[str, str],
187
145
  "monitor_config": Mapping[str, object],
@@ -210,7 +168,6 @@ if TYPE_CHECKING:
210
168
  "type": Literal["check_in", "transaction"],
211
169
  "user": dict[str, object],
212
170
  "_dropped_spans": int,
213
- "_metrics_summary": dict[str, object],
214
171
  },
215
172
  total=False,
216
173
  )
@@ -220,7 +177,9 @@ if TYPE_CHECKING:
220
177
  tuple[None, None, None],
221
178
  ]
222
179
 
180
+ # TODO: Make a proper type definition for this (PRs welcome!)
223
181
  Hint = Dict[str, Any]
182
+
224
183
  Log = TypedDict(
225
184
  "Log",
226
185
  {
@@ -233,9 +192,13 @@ if TYPE_CHECKING:
233
192
  },
234
193
  )
235
194
 
195
+ # TODO: Make a proper type definition for this (PRs welcome!)
236
196
  Breadcrumb = Dict[str, Any]
197
+
198
+ # TODO: Make a proper type definition for this (PRs welcome!)
237
199
  BreadcrumbHint = Dict[str, Any]
238
200
 
201
+ # TODO: Make a proper type definition for this (PRs welcome!)
239
202
  SamplingContext = Dict[str, Any]
240
203
 
241
204
  EventProcessor = Callable[[Event, Hint], Optional[Event]]
@@ -260,7 +223,6 @@ if TYPE_CHECKING:
260
223
  "internal",
261
224
  "profile",
262
225
  "profile_chunk",
263
- "metric_bucket",
264
226
  "monitor",
265
227
  "span",
266
228
  "log",
@@ -270,26 +232,6 @@ if TYPE_CHECKING:
270
232
  ContinuousProfilerMode = Literal["thread", "gevent", "unknown"]
271
233
  ProfilerMode = Union[ContinuousProfilerMode, Literal["sleep"]]
272
234
 
273
- # Type of the metric.
274
- MetricType = Literal["d", "s", "g", "c"]
275
-
276
- # Value of the metric.
277
- MetricValue = Union[int, float, str]
278
-
279
- # Internal representation of tags as a tuple of tuples (this is done in order to allow for the same key to exist
280
- # multiple times).
281
- MetricTagsInternal = Tuple[Tuple[str, str], ...]
282
-
283
- # External representation of tags as a dictionary.
284
- MetricTagValue = Union[str, int, float, None]
285
- MetricTags = Mapping[str, MetricTagValue]
286
-
287
- # Value inside the generator for the metric value.
288
- FlushedMetricValue = Union[int, float]
289
-
290
- BucketKey = Tuple[MetricType, str, MeasurementUnit, MetricTagsInternal]
291
- MetricMetaKey = Tuple[MetricType, str, MeasurementUnit]
292
-
293
235
  MonitorConfigScheduleType = Literal["crontab", "interval"]
294
236
  MonitorConfigScheduleUnit = Literal[
295
237
  "year",
@@ -325,3 +267,5 @@ if TYPE_CHECKING:
325
267
  )
326
268
 
327
269
  HttpStatusCodeRange = Union[int, Container[int]]
270
+
271
+ OtelExtractedSpanData = tuple[str, str, Optional[str], Optional[int], Optional[str]]
@@ -33,13 +33,15 @@ def ai_track(description, **span_kwargs):
33
33
  curr_pipeline = _ai_pipeline_name.get()
34
34
  op = span_kwargs.get("op", "ai.run" if curr_pipeline else "ai.pipeline")
35
35
 
36
- with start_span(name=description, op=op, **span_kwargs) as span:
36
+ with start_span(
37
+ name=description, op=op, only_if_parent=True, **span_kwargs
38
+ ) as span:
37
39
  for k, v in kwargs.pop("sentry_tags", {}).items():
38
40
  span.set_tag(k, v)
39
41
  for k, v in kwargs.pop("sentry_data", {}).items():
40
- span.set_data(k, v)
42
+ span.set_attribute(k, v)
41
43
  if curr_pipeline:
42
- span.set_data("ai.pipeline.name", curr_pipeline)
44
+ span.set_attribute("ai.pipeline.name", curr_pipeline)
43
45
  return f(*args, **kwargs)
44
46
  else:
45
47
  _ai_pipeline_name.set(description)
@@ -62,13 +64,15 @@ def ai_track(description, **span_kwargs):
62
64
  curr_pipeline = _ai_pipeline_name.get()
63
65
  op = span_kwargs.get("op", "ai.run" if curr_pipeline else "ai.pipeline")
64
66
 
65
- with start_span(name=description, op=op, **span_kwargs) as span:
67
+ with start_span(
68
+ name=description, op=op, only_if_parent=True, **span_kwargs
69
+ ) as span:
66
70
  for k, v in kwargs.pop("sentry_tags", {}).items():
67
71
  span.set_tag(k, v)
68
72
  for k, v in kwargs.pop("sentry_data", {}).items():
69
- span.set_data(k, v)
73
+ span.set_attribute(k, v)
70
74
  if curr_pipeline:
71
- span.set_data("ai.pipeline.name", curr_pipeline)
75
+ span.set_attribute("ai.pipeline.name", curr_pipeline)
72
76
  return await f(*args, **kwargs)
73
77
  else:
74
78
  _ai_pipeline_name.set(description)
@@ -100,11 +104,11 @@ def record_token_usage(
100
104
  # type: (Span, Optional[int], Optional[int], Optional[int]) -> None
101
105
  ai_pipeline_name = get_ai_pipeline_name()
102
106
  if ai_pipeline_name:
103
- span.set_data("ai.pipeline.name", ai_pipeline_name)
107
+ span.set_attribute("ai.pipeline.name", ai_pipeline_name)
104
108
  if prompt_tokens is not None:
105
- span.set_measurement("ai_prompt_tokens_used", value=prompt_tokens)
109
+ span.set_attribute("ai.prompt_tokens.used", prompt_tokens)
106
110
  if completion_tokens is not None:
107
- span.set_measurement("ai_completion_tokens_used", value=completion_tokens)
111
+ span.set_attribute("ai.completion_tokens.used", completion_tokens)
108
112
  if (
109
113
  total_tokens is None
110
114
  and prompt_tokens is not None
@@ -112,4 +116,4 @@ def record_token_usage(
112
116
  ):
113
117
  total_tokens = prompt_tokens + completion_tokens
114
118
  if total_tokens is not None:
115
- span.set_measurement("ai_total_tokens_used", total_tokens)
119
+ span.set_attribute("ai.total_tokens.used", total_tokens)
sentry_sdk/ai/utils.py CHANGED
@@ -29,4 +29,4 @@ def _normalize_data(data):
29
29
  def set_data_normalized(span, key, value):
30
30
  # type: (Span, str, Any) -> None
31
31
  normalized = _normalize_data(value)
32
- span.set_data(key, normalized)
32
+ span.set_attribute(key, normalized)