Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(metrics): Add value, unit to before_emit_metric #2958

Merged
merged 5 commits into from
Apr 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 5 additions & 1 deletion sentry_sdk/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
Event,
EventProcessor,
Hint,
MeasurementUnit,
ProfilerMode,
TracesSampler,
TransactionProcessor,
MetricTags,
MetricValue,
)

# Experiments are feature flags to enable and disable certain unstable SDK
Expand All @@ -47,7 +49,9 @@
"transport_zlib_compression_level": Optional[int],
"transport_num_pools": Optional[int],
"enable_metrics": Optional[bool],
"before_emit_metric": Optional[Callable[[str, MetricTags], bool]],
"before_emit_metric": Optional[
Callable[[str, MetricValue, MeasurementUnit, MetricTags], bool]
],
"metric_code_locations": Optional[bool],
},
total=False,
Expand Down
31 changes: 22 additions & 9 deletions sentry_sdk/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -703,8 +703,8 @@ def _get_aggregator():
)


def _get_aggregator_and_update_tags(key, tags):
# type: (str, Optional[MetricTags]) -> Tuple[Optional[MetricsAggregator], Optional[LocalAggregator], Optional[MetricTags]]
def _get_aggregator_and_update_tags(key, value, unit, tags):
# type: (str, Optional[MetricValue], MeasurementUnit, Optional[MetricTags]) -> Tuple[Optional[MetricsAggregator], Optional[LocalAggregator], Optional[MetricTags]]
hub = sentry_sdk.Hub.current
client = hub.client
if client is None or client.metrics_aggregator is None:
Expand Down Expand Up @@ -732,7 +732,7 @@ def _get_aggregator_and_update_tags(key, tags):
if before_emit_callback is not None:
with recursion_protection() as in_metrics:
if not in_metrics:
if not before_emit_callback(key, updated_tags):
if not before_emit_callback(key, value, unit, updated_tags):
return None, None, updated_tags

return client.metrics_aggregator, local_aggregator, updated_tags
Expand All @@ -748,7 +748,9 @@ def increment(
):
# type: (...) -> None
"""Increments a counter."""
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(key, tags)
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(
key, value, unit, tags
)
if aggregator is not None:
aggregator.add(
"c", key, value, unit, tags, timestamp, local_aggregator, stacklevel
Expand Down Expand Up @@ -809,7 +811,10 @@ def __exit__(self, exc_type, exc_value, tb):
# type: (Any, Any, Any) -> None
assert self._span, "did not enter"
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(
self.key, self.tags
self.key,
self.value,
self.unit,
self.tags,
)
if aggregator is not None:
elapsed = TIMING_FUNCTIONS[self.unit]() - self.entered # type: ignore
Expand Down Expand Up @@ -864,7 +869,9 @@ def timing(
- it can be used as a decorator
"""
if value is not None:
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(key, tags)
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(
key, value, unit, tags
)
if aggregator is not None:
aggregator.add(
"d", key, value, unit, tags, timestamp, local_aggregator, stacklevel
Expand All @@ -882,7 +889,9 @@ def distribution(
):
# type: (...) -> None
"""Emits a distribution."""
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(key, tags)
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(
key, value, unit, tags
)
if aggregator is not None:
aggregator.add(
"d", key, value, unit, tags, timestamp, local_aggregator, stacklevel
Expand All @@ -899,7 +908,9 @@ def set(
):
# type: (...) -> None
"""Emits a set."""
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(key, tags)
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(
key, value, unit, tags
)
if aggregator is not None:
aggregator.add(
"s", key, value, unit, tags, timestamp, local_aggregator, stacklevel
Expand All @@ -916,7 +927,9 @@ def gauge(
):
# type: (...) -> None
"""Emits a gauge."""
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(key, tags)
aggregator, local_aggregator, tags = _get_aggregator_and_update_tags(
key, value, unit, tags
)
if aggregator is not None:
aggregator.add(
"g", key, value, unit, tags, timestamp, local_aggregator, stacklevel
Expand Down
7 changes: 5 additions & 2 deletions tests/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,9 +734,10 @@ def test_tag_normalization(
def test_before_emit_metric(
sentry_init, capture_envelopes, maybe_monkeypatched_threading
):
def before_emit(key, tags):
if key == "removed-metric":
def before_emit(key, value, unit, tags):
if key == "removed-metric" or value == 47 or unit == "unsupported":
return False

tags["extra"] = "foo"
del tags["release"]
# this better be a noop!
Expand All @@ -755,6 +756,8 @@ def before_emit(key, tags):
envelopes = capture_envelopes()

metrics.increment("removed-metric", 1.0)
metrics.increment("another-removed-metric", 47)
metrics.increment("yet-another-removed-metric", 1.0, unit="unsupported")
metrics.increment("actual-metric", 1.0)
Hub.current.flush()

Expand Down