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(ddm): Enable metrics related settings by default #2685

Merged
merged 13 commits into from
Jan 30, 2024
23 changes: 14 additions & 9 deletions sentry_sdk/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
get_default_release,
handle_in_app,
logger,
is_gevent,
)
from sentry_sdk.serializer import serialize
from sentry_sdk.tracing import trace, has_tracing_enabled
Expand Down Expand Up @@ -249,15 +250,19 @@

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

self.metrics_aggregator = MetricsAggregator(
capture_func=_capture_envelope,
enable_code_locations=bool(
experiments.get("metric_code_locations")
),
)
if experiments.get("enable_metrics", True):
if is_gevent():
logger.warning("Metrics currently not supported with gevent.")

Check warning on line 255 in sentry_sdk/client.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/client.py#L255

Added line #L255 was not covered by tests

else:
from sentry_sdk.metrics import MetricsAggregator

self.metrics_aggregator = MetricsAggregator(
capture_func=_capture_envelope,
enable_code_locations=bool(
experiments.get("metric_code_locations", True)
),
)

max_request_body_size = ("always", "never", "small", "medium")
if self.options["max_request_body_size"] not in max_request_body_size:
Expand Down
6 changes: 5 additions & 1 deletion sentry_sdk/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -719,7 +719,11 @@
if transaction_name:
updated_tags.setdefault("transaction", transaction_name)
if scope._span is not None:
sample_rate = experiments.get("metrics_summary_sample_rate") or 0.0
sample_rate = experiments.get("metrics_summary_sample_rate")

Check warning on line 722 in sentry_sdk/metrics.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/metrics.py#L722

Added line #L722 was not covered by tests
# We default the sample rate of metrics summaries to 1.0 only when the sample rate is `None` since we
# want to honor the user's decision if they pass a valid float.
if sample_rate is None:
sample_rate = 1.0

Check warning on line 726 in sentry_sdk/metrics.py

View check run for this annotation

Codecov / codecov/patch

sentry_sdk/metrics.py#L726

Added line #L726 was not covered by tests
should_summarize_metric_callback = experiments.get(
"should_summarize_metric"
)
Expand Down
15 changes: 15 additions & 0 deletions sentry_sdk/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -1741,3 +1741,18 @@ def now():
def now():
# type: () -> float
return time.perf_counter()


try:
from gevent.monkey import is_module_patched
except ImportError:

def is_module_patched(*args, **kwargs):
# type: (*Any, **Any) -> bool
# unable to import from gevent means no modules have been patched
return False


def is_gevent():
# type: () -> bool
return is_module_patched("threading") or is_module_patched("_thread")
53 changes: 44 additions & 9 deletions tests/test_metrics.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# coding: utf-8

import pytest
import sys
import time
import linecache
Expand All @@ -13,6 +13,13 @@
except ImportError:
import mock # python < 3.3

try:
import gevent
except ImportError:
gevent = None

requires_gevent = pytest.mark.skipif(gevent is None, reason="gevent not enabled")


def parse_metrics(bytes):
rv = []
Expand Down Expand Up @@ -418,7 +425,7 @@ def test_gauge(sentry_init, capture_envelopes):
sentry_init(
release="fun-release@1.0.0",
environment="not-fun-env",
_experiments={"enable_metrics": True},
_experiments={"enable_metrics": True, "metric_code_locations": False},
)
ts = time.time()
envelopes = capture_envelopes()
Expand Down Expand Up @@ -450,7 +457,7 @@ def test_multiple(sentry_init, capture_envelopes):
sentry_init(
release="fun-release@1.0.0",
environment="not-fun-env",
_experiments={"enable_metrics": True},
_experiments={"enable_metrics": True, "metric_code_locations": False},
)
ts = time.time()
envelopes = capture_envelopes()
Expand Down Expand Up @@ -503,7 +510,7 @@ def test_transaction_name(sentry_init, capture_envelopes):
sentry_init(
release="fun-release@1.0.0",
environment="not-fun-env",
_experiments={"enable_metrics": True},
_experiments={"enable_metrics": True, "metric_code_locations": False},
)
ts = time.time()
envelopes = capture_envelopes()
Expand Down Expand Up @@ -536,12 +543,16 @@ def test_transaction_name(sentry_init, capture_envelopes):
}


def test_metric_summaries(sentry_init, capture_envelopes):
@pytest.mark.parametrize("sample_rate", [1.0, None])
def test_metric_summaries(sentry_init, capture_envelopes, sample_rate):
sentry_init(
release="fun-release@1.0.0",
environment="not-fun-env",
enable_tracing=True,
_experiments={"enable_metrics": True, "metrics_summary_sample_rate": 1.0},
_experiments={
"enable_metrics": True,
"metrics_summary_sample_rate": sample_rate,
},
)
ts = time.time()
envelopes = capture_envelopes()
Expand Down Expand Up @@ -644,7 +655,7 @@ def test_metrics_summary_disabled(sentry_init, capture_envelopes):
release="fun-release@1.0.0",
environment="not-fun-env",
enable_tracing=True,
_experiments={"enable_metrics": True},
_experiments={"enable_metrics": True, "metrics_summary_sample_rate": 0.0},
)
ts = time.time()
envelopes = capture_envelopes()
Expand Down Expand Up @@ -750,7 +761,7 @@ def test_tag_normalization(sentry_init, capture_envelopes):
sentry_init(
release="fun-release@1.0.0",
environment="not-fun-env",
_experiments={"enable_metrics": True},
_experiments={"enable_metrics": True, "metric_code_locations": False},
)
ts = time.time()
envelopes = capture_envelopes()
Expand Down Expand Up @@ -805,6 +816,7 @@ def before_emit(key, tags):
environment="not-fun-env",
_experiments={
"enable_metrics": True,
"metric_code_locations": False,
"before_emit_metric": before_emit,
},
)
Expand Down Expand Up @@ -850,7 +862,7 @@ def test_tag_serialization(sentry_init, capture_envelopes):
sentry_init(
release="fun-release",
environment="not-fun-env",
_experiments={"enable_metrics": True},
_experiments={"enable_metrics": True, "metric_code_locations": False},
)
envelopes = capture_envelopes()

Expand Down Expand Up @@ -942,3 +954,26 @@ def bad_capture_envelope(*args, **kwargs):
m = parse_metrics(envelope.items[0].payload.get_bytes())
assert len(m) == 1
assert m[0][1] == "counter@none"


@pytest.mark.forked
@requires_gevent
def test_no_metrics_with_gevent(sentry_init, capture_envelopes):
from gevent import monkey

monkey.patch_all()

sentry_init(
release="fun-release",
environment="not-fun-env",
_experiments={"enable_metrics": True, "metric_code_locations": True},
)
ts = time.time()
envelopes = capture_envelopes()

metrics.incr("foobar", 1.0, tags={"foo": "bar", "blub": "blah"}, timestamp=ts)
metrics.incr("foobar", 2.0, tags={"foo": "bar", "blub": "blah"}, timestamp=ts)
Hub.current.flush()

assert Hub.current.client.metrics_aggregator is None
assert len(envelopes) == 0
1 change: 1 addition & 0 deletions tests/test_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ def test_minimum_unique_samples_required(
assert reports == [("insufficient_data", "profile")]


@pytest.mark.forked
@requires_python_version(3, 3)
def test_profile_captured(
sentry_init,
Expand Down