8000 feat(metrics): Move minimetrics code to the SDK (#2385) · GitLukeW/sentry-python@0dd7d5f · GitHub
[go: up one dir, main page]

Skip to content

Commit 0dd7d5f

Browse files
authored
feat(metrics): Move minimetrics code to the SDK (getsentry#2385)
1 parent 7b72efd commit 0dd7d5f

File tree

7 files changed

+1173
-1
lines changed

7 files changed

+1173
-1
lines changed

sentry_sdk/_types.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
from typing import Any
1414
from typing import Callable
1515
from typing import Dict
16+
from typing import List
17+
from typing import Mapping
1618
from typing import Optional
1719
from typing import Tuple
1820
from typing import Type
@@ -51,6 +53,7 @@
5153
"session",
5254
"internal",
5355
"profile",
56+
"statsd",
5457
]
5558
SessionStatus = Literal["ok", "exited", "crashed", "abnormal"]
5659
EndpointType = Literal["store", "envelope"]
@@ -87,3 +90,29 @@
8790
MeasurementUnit = Union[DurationUnit, InformationUnit, FractionUnit, str]
8891

8992
ProfilerMode = Literal["sleep", "thread", "gevent", "unknown"]
93+
94+
# Type of the metric.
95+
MetricType = Literal["d", "s", "g", "c"]
96+
97+
# Value of the metric.
98+
MetricValue = Union[int, float, str]
99+
100+
# Internal representation of tags as a tuple of tuples (this is done in order to allow for the same key to exist
101+
# multiple times).
102+
MetricTagsInternal = Tuple[Tuple[str, str], ...]
103+
104+
# External representation of tags as a dictionary.
105+
MetricTagValue = Union[
106+
str,
107+
int,
108+
float,
109+
None,
110+
List[Union[int, str, float, None]],
111+
Tuple[Union[int, str, float, None], ...],
112+
]
113+
MetricTags = Mapping[str, MetricTagValue]
114+
115+
# Value inside the generator for the metric value.
116+
FlushedMetricValue = Union[int, float]
117+
118+
BucketKey = Tuple[MetricType, str, MeasurementUnit, MetricTagsInternal]

sentry_sdk/client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,14 @@ def _capture_envelope(envelope):
229229

230230
self.session_flusher = SessionFlusher(capture_func=_capture_envelope)
231231

232+
self.metrics_aggregator = None # type: Optional[MetricsAggregator]
233+
if self.options.get("_experiments", {}).get("enable_metrics"):
234+
from sentry_sdk.metrics import MetricsAggregator
235+
236+
self.metrics_aggregator = MetricsAggregator(
237+
capture_func=_capture_envelope
238+
)
239+
232240
max_request_body_size = ("always", "never", "small", "medium")
233241
if self.options["max_request_body_size"] not in max_request_body_size:
234242
raise ValueError(
@@ -610,6 +618,8 @@ def close(
610618
if self.transport is not None:
611619
self.flush(timeout=timeout, callback=callback)
612620
self.session_flusher.kill()
621+
if self.metrics_aggregator is not None:
622+
self.metrics_aggregator.kill()
613623
if self.monitor:
614624
self.monitor.kill()
615625
self.transport.kill()
@@ -632,6 +642,8 @@ def flush(
632642
if timeout is None:
633643
timeout = self.options["shutdown_timeout"]
634644
self.session_flusher.flush()
645+
if self.metrics_aggregator is not None:
646+
self.metrics_aggregator.flush()
635647
self.transport.flush(timeout=timeout, callback=callback)
636648

637649
def __enter__(self):

sentry_sdk/consts.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
ProfilerMode,
2626
TracesSampler,
2727
TransactionProcessor,
28+
MetricTags,
2829
)
2930

3031
# Experiments are feature flags to enable and disable certain unstable SDK
@@ -41,6 +42,8 @@
4142
"profiler_mode": Optional[ProfilerMode],
4243
"otel_powered_performance": Optional[bool],
4344
"transport_zlib_compression_level": Optional[int],
45+
"enable_metrics": Optional[bool],
46+
"before_emit_metric": Optional[Callable[[str, MetricTags], bool]],
4447
},
4548
total=False,
4649
)

sentry_sdk/envelope.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,8 @@ def data_category(self):
260260
return "internal"
261261
elif ty == "profile":
262262
return "profile"
263+
elif ty == "statsd":
264+
return "statsd"
263265
else:
264266
return "default"
265267

0 commit comments

Comments
 (0)
0