Skip to content

Commit

Permalink
feat(metrics): Move minimetrics code to the SDK (#2385)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko authored Sep 21, 2023
1 parent 7b72efd commit 0dd7d5f
Show file tree
Hide file tree
Showing 7 changed files with 1,173 additions and 1 deletion.
29 changes: 29 additions & 0 deletions sentry_sdk/_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
from typing import Any
from typing import Callable
from typing import Dict
from typing import List
from typing import Mapping
from typing import Optional
from typing import Tuple
from typing import Type
Expand Down Expand Up @@ -51,6 +53,7 @@
"session",
"internal",
"profile",
"statsd",
]
SessionStatus = Literal["ok", "exited", "crashed", "abnormal"]
EndpointType = Literal["store", "envelope"]
Expand Down Expand Up @@ -87,3 +90,29 @@
MeasurementUnit = Union[DurationUnit, InformationUnit, FractionUnit, str]

ProfilerMode = Literal["sleep", "thread", "gevent", "unknown"]

# Type of the metric.
MetricType = Literal["d", "s", "g", "c"]

# Value of the metric.
MetricValue = Union[int, float, str]

# Internal representation of tags as a tuple of tuples (this is done in order to allow for the same key to exist
# multiple times).
MetricTagsInternal = Tuple[Tuple[str, str], ...]

# External representation of tags as a dictionary.
MetricTagValue = Union[
str,
int,
float,
None,
List[Union[int, str, float, None]],
Tuple[Union[int, str, float, None], ...],
]
MetricTags = Mapping[str, MetricTagValue]

# Value inside the generator for the metric value.
FlushedMetricValue = Union[int, float]

BucketKey = Tuple[MetricType, str, MeasurementUnit, MetricTagsInternal]
12 changes: 12 additions & 0 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,14 @@ def _capture_envelope(envelope):

self.session_flusher = SessionFlusher(capture_func=_capture_envelope)

self.metrics_aggregator = None # type: Optional[MetricsAggregator]
if self.options.get("_experiments", {}).get("enable_metrics"):
from sentry_sdk.metrics import MetricsAggregator

self.metrics_aggregator = MetricsAggregator(
capture_func=_capture_envelope
)

max_request_body_size = ("always", "never", "small", "medium")
if self.options["max_request_body_size"] not in max_request_body_size:
raise ValueError(
Expand Down Expand Up @@ -610,6 +618,8 @@ def close(
if self.transport is not None:
self.flush(timeout=timeout, callback=callback)
self.session_flusher.kill()
if self.metrics_aggregator is not None:
self.metrics_aggregator.kill()
if self.monitor:
self.monitor.kill()
self.transport.kill()
Expand All @@ -632,6 +642,8 @@ def flush(
if timeout is None:
timeout = self.options["shutdown_timeout"]
self.session_flusher.flush()
if self.metrics_aggregator is not None:
self.metrics_aggregator.flush()
self.transport.flush(timeout=timeout, callback=callback)

def __enter__(self):
Expand Down
3 changes: 3 additions & 0 deletions sentry_sdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
ProfilerMode,
TracesSampler,
TransactionProcessor,
MetricTags,
)

# Experiments are feature flags to enable and disable certain unstable SDK
Expand All @@ -41,6 +42,8 @@
"profiler_mode": Optional[ProfilerMode],
"otel_powered_performance": Optional[bool],
"transport_zlib_compression_level": Optional[int],
"enable_metrics": Optional[bool],
"before_emit_metric": Optional[Callable[[str, MetricTags], bool]],
},
total=False,
)
Expand Down
2 changes: 2 additions & 0 deletions sentry_sdk/envelope.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ def data_category(self):
return "internal"
elif ty == "profile":
return "profile"
elif ty == "statsd":
return "statsd"
else:
return "default"

Expand Down
Loading

0 comments on commit 0dd7d5f

Please sign in to comment.