Skip to content

Commit 5130590

Browse files
authored
feat(perf): Add ability to put measurements directly on spans. (#2967)
1 parent 842df5e commit 5130590

File tree

2 files changed

+56
-35
lines changed

2 files changed

+56
-35
lines changed

sentry_sdk/_types.py

Lines changed: 40 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,45 @@
2828
# "critical" is an alias of "fatal" recognized by Relay
2929
LogLevelStr = Literal["fatal", "critical", "error", "warning", "info", "debug"]
3030

31+
DurationUnit = Literal[
32+
"nanosecond",
33+
"microsecond",
34+
"millisecond",
35+
"second",
36+
"minute",
37+
"hour",
38+
"day",
39+
"week",
40+
]
41+
42+
InformationUnit = Literal[
43+
"bit",
44+
"byte",
45+
"kilobyte",
46+
"kibibyte",
47+
"megabyte",
48+
"mebibyte",
49+
"gigabyte",
50+
"gibibyte",
51+
"terabyte",
52+
"tebibyte",
53+
"petabyte",
54+
"pebibyte",
55+
"exabyte",
56+
"exbibyte",
57+
]
58+
59+
FractionUnit = Literal["ratio", "percent"]
60+
MeasurementUnit = Union[DurationUnit, InformationUnit, FractionUnit, str]
61+
62+
MeasurementValue = TypedDict(
63+
"MeasurementValue",
64+
{
65+
"value": float,
66+
"unit": Optional[MeasurementUnit],
67+
},
68+
)
69+
3170
Event = TypedDict(
3271
"Event",
3372
{
@@ -49,7 +88,7 @@
4988
"level": LogLevelStr,
5089
"logentry": Mapping[str, object],
5190
"logger": str,
52-
"measurements": dict[str, object],
91+
"measurements": dict[str, MeasurementValue],
5392
"message": str,
5493
"modules": dict[str, str],
5594
"monitor_config": Mapping[str, object],
@@ -118,37 +157,6 @@
118157
]
119158
SessionStatus = Literal["ok", "exited", "crashed", "abnormal"]
120159

121-
DurationUnit = Literal[
122-
"nanosecond",
123-
"microsecond",
124-
"millisecond",
125-
"second",
126-
"minute",
127-
"hour",
128-
"day",
129-
"week",
130-
]
131-
132-
InformationUnit = Literal[
133-
"bit",
134-
"byte",
135-
"kilobyte",
136-
"kibibyte",
137-
"megabyte",
138-
"mebibyte",
139-
"gigabyte",
140-
"gibibyte",
141-
"terabyte",
142-
"tebibyte",
143-
"petabyte",
144-
"pebibyte",
145-
"exabyte",
146-
"exbibyte",
147-
]
148-
149-
FractionUnit = Literal["ratio", "percent"]
150-
MeasurementUnit = Union[DurationUnit, InformationUnit, FractionUnit, str]
151-
152160
ProfilerMode = Literal["sleep", "thread", "gevent", "unknown"]
153161

154162
# Type of the metric.

sentry_sdk/tracing.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
)
1313
from sentry_sdk._types import TYPE_CHECKING
1414

15-
1615
if TYPE_CHECKING:
1716
from collections.abc import Callable, Mapping, MutableMapping
1817
from typing import Any
@@ -32,7 +31,12 @@
3231
R = TypeVar("R")
3332

3433
import sentry_sdk.profiler
35-
from sentry_sdk._types import Event, MeasurementUnit, SamplingContext
34+
from sentry_sdk._types import (
35+
Event,
36+
MeasurementUnit,
37+
SamplingContext,
38+
MeasurementValue,
39+
)
3640

3741
class SpanKwargs(TypedDict, total=False):
3842
trace_id: str
@@ -189,6 +193,7 @@ class Span:
189193
"sampled",
190194
"op",
191195
"description",
196+
"_measurements",
192197
"start_timestamp",
193198
"_start_timestamp_monotonic_ns",
194199
"status",
@@ -229,6 +234,7 @@ def __init__(
229234
self.status = status
230235
self.hub = hub
231236
self.scope = scope
237+
self._measurements = {} # type: Dict[str, MeasurementValue]
232238
self._tags = {} # type: MutableMapping[str, str]
233239
self._data = {} # type: Dict[str, Any]
234240
self._containing_transaction = containing_transaction
@@ -488,6 +494,10 @@ def set_status(self, value):
488494
# type: (str) -> None
489495
self.status = value
490496

497+
def set_measurement(self, name, value, unit=""):
498+
# type: (str, float, MeasurementUnit) -> None
499+
self._measurements[name] = {"value": value, "unit": unit}
500+
491501
def set_thread(self, thread_id, thread_name):
492502
# type: (Optional[int], Optional[str]) -> None
493503

@@ -598,6 +608,9 @@ def to_json(self):
598608
if metrics_summary:
599609
rv["_metrics_summary"] = metrics_summary
600610

611+
if len(self._measurements) > 0:
612+
rv["measurements"] = self._measurements
613+
601614
tags = self._tags
602615
if tags:
603616
rv["tags"] = tags
@@ -674,7 +687,7 @@ def __init__(
674687
self.source = source
675688
self.sample_rate = None # type: Optional[float]
676689
self.parent_sampled = parent_sampled
677-
self._measurements = {} # type: Dict[str, Any]
690+
self._measurements = {} # type: Dict[str, MeasurementValue]
678691
self._contexts = {} # type: Dict[str, Any]
679692
self._profile = None # type: Optional[sentry_sdk.profiler.Profile]
680693
self._baggage = baggage

0 commit comments

Comments
 (0)