Skip to content
Snippets Groups Projects
Commit 4ccb7dec authored by Renaud Boyer's avatar Renaud Boyer
Browse files

sentry: Implement performance tracing

parent 6368526c
No related branches found
No related tags found
No related merge requests found
Pipeline #12593 passed
......@@ -29,6 +29,7 @@ def test_post_fork_default(mocker):
debug=False,
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -53,6 +54,7 @@ def test_post_fork_with_dsn_env(mocker):
debug=False,
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -87,6 +89,7 @@ def test_post_fork_with_package_env(mocker):
debug=False,
release="swh.core@" + version,
environment="tests",
traces_sample_rate=None,
)
......@@ -114,6 +117,7 @@ def test_post_fork_debug(mocker):
debug=True,
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -134,6 +138,7 @@ def test_post_fork_no_flask(mocker):
debug=False,
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -152,6 +157,7 @@ def test_post_fork_override_logging_events_envvar(mocker):
debug=False,
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -178,4 +184,5 @@ def test_post_fork_extras(mocker):
bar="baz",
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -40,6 +40,37 @@ def override_with_bool_envvar(envvar: str, default: bool) -> bool:
return default
def override_with_float_envvar(
envvar: str, default: Optional[float]
) -> Optional[float]:
"""Override `default` with the environment variable `envvar` casted as a float.
`default` is returned if the environment variable `envvar` is missing or if
we're not able to cast it to a float.
Args:
envvar: the name of the environment variable
default: default value
Returns:
A float or `default`
"""
envvalue = os.environ.get(envvar)
if envvalue is None:
return default
try:
return float(envvalue)
except ValueError:
logger.warning(
"Could not interpret environment variable %s=%r as float, "
"using default value %s",
envvar,
envvalue,
default,
)
return default
def init_sentry(
sentry_dsn: Optional[str] = None,
*,
......@@ -48,10 +79,11 @@ def init_sentry(
debug: bool = False,
disable_logging_events: bool = False,
integrations: Optional[List] = None,
traces_sample_rate: Optional[float] = None,
extra_kwargs: Optional[Dict] = None,
deferred_init: bool = False,
):
"""Configure the sentry integration
) -> None:
"""Configure the sentry integration.
Args:
sentry_dsn: Sentry DSN; where sentry report will be sent. Overridden by
......@@ -64,10 +96,12 @@ def init_sentry(
log entries as Sentry events. Overridden by
:envvar:`SWH_SENTRY_DISABLE_LOGGING_EVENTS`
integrations: list of dedicated Sentry integrations to include
traces_sample_rate: a number between 0 and 1, controlling the percentage chance a
given transaction will be sent to Sentry. Overridden by
:envvar:`SWH_SENTRY_TRACES_SAMPLE_RATE`
extra_kwargs: dict of additional parameters passed to :func:`sentry_sdk.init`
deferred_init: indicates that sentry will be properly initialized in subsequent
calls and that no warnings about missing DSN should be logged
"""
if integrations is None:
integrations = []
......@@ -95,10 +129,17 @@ def init_sentry(
integrations.append(LoggingIntegration(event_level=None))
# to completely disable tracing `traces_sample_rate` should be set to None instead
# of 0.0
traces_sample_rate = override_with_float_envvar(
"SWH_SENTRY_TRACES_SAMPLE_RATE", traces_sample_rate
)
sentry_sdk.init(
release=get_sentry_release(main_package),
environment=environment,
dsn=sentry_dsn,
traces_sample_rate=traces_sample_rate,
integrations=integrations,
debug=debug,
**extra_kwargs,
......
......@@ -124,6 +124,7 @@ def test_command(swhmain, mocker):
integrations=[],
release=None,
environment=None,
traces_sample_rate=None,
)
assert_result(result)
assert result.output.strip() == "Hello SWH!"
......@@ -185,6 +186,7 @@ def test_sentry(swhmain, mocker):
integrations=[],
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -207,6 +209,7 @@ def test_sentry_debug(swhmain, mocker):
integrations=[],
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -231,6 +234,7 @@ def test_sentry_env(swhmain, mocker):
integrations=[],
release=None,
environment=None,
traces_sample_rate=None,
)
......@@ -259,6 +263,7 @@ def test_sentry_env_main_package(swhmain, mocker):
integrations=[],
release="swh.core@" + version,
environment="tests",
traces_sample_rate=None,
)
......
......@@ -9,7 +9,11 @@ import pytest
import sentry_sdk
from sentry_sdk import capture_exception, capture_message, set_tag
from swh.core.sentry import init_sentry, override_with_bool_envvar
from swh.core.sentry import (
init_sentry,
override_with_bool_envvar,
override_with_float_envvar,
)
SENTRY_DSN = "https://user@example.org/1234"
......@@ -48,6 +52,31 @@ def test_override_with_bool_envvar_logging(monkeypatch, caplog):
assert caplog.records[0].levelname == "WARNING"
@pytest.mark.parametrize(
"envvalue,retval",
(("1.0", 1.0), ("0.0", 0.0), ("0", 0.0), ("a", None)),
)
def test_override_with_float_envvar(monkeypatch, envvalue: str, retval: bool):
envvar = "OVERRIDE_WITH_FLOAT_ENVVAR"
monkeypatch.setenv(envvar, envvalue)
assert override_with_float_envvar(envvar, None) == retval
def test_override_with_float_envvar_logging(monkeypatch, caplog):
envvar = "OVERRIDE_WITH_FLOAT_ENVVAR"
monkeypatch.setenv(envvar, "not a float env value")
for default in (None, 1.0):
caplog.clear()
assert override_with_float_envvar(envvar, default) == default
assert len(caplog.records) == 1
assert (
"OVERRIDE_WITH_FLOAT_ENVVAR='not a float env value'"
in caplog.records[0].getMessage()
)
assert f"using default value {default}" in caplog.records[0].getMessage()
assert caplog.records[0].levelname == "WARNING"
def test_sentry():
reports = []
init_sentry(SENTRY_DSN, extra_kwargs={"transport": reports.append})
......@@ -160,3 +189,14 @@ def test_sentry_deferred_init(caplog, deferred_init):
)
else:
assert not caplog.records
@pytest.mark.parametrize("traces_sample_rate", [1.0, 0.0, None])
def test_sentry_traces_sample_rate(caplog, traces_sample_rate):
init_sentry(None, traces_sample_rate=traces_sample_rate)
client = sentry_sdk.get_client()
if traces_sample_rate is not None:
assert client.options["traces_sample_rate"] == float(traces_sample_rate)
else:
assert client.options["enable_tracing"] is None
assert client.options["traces_sample_rate"] is None
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment