Skip to content

Commit

Permalink
Fix: Configurable traces sampling rate for Sentry (#1360)
Browse files Browse the repository at this point in the history
  • Loading branch information
thekaveman authored Apr 20, 2023
2 parents b0c31c6 + 2ae770f commit cdec5fb
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 8 deletions.
23 changes: 20 additions & 3 deletions benefits/sentry.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging
import shutil
import os
import subprocess
Expand All @@ -8,6 +9,7 @@

from benefits import VERSION

logger = logging.getLogger(__name__)

SENTRY_ENVIRONMENT = os.environ.get("SENTRY_ENVIRONMENT", "local")
SENTRY_CSP_REPORT_URI = None
Expand Down Expand Up @@ -62,19 +64,34 @@ def get_denylist():
return denylist


def get_traces_sample_rate():
try:
rate = float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0.0"))
if rate < 0.0 or rate > 1.0:
logger.warn("SENTRY_TRACES_SAMPLE_RATE was not in the range [0.0, 1.0], defaulting to 0.0")
rate = 0.0
else:
logger.info(f"SENTRY_TRACES_SAMPLE_RATE set to: {rate}")
except ValueError:
logger.warn("SENTRY_TRACES_SAMPLE_RATE did not parse to float, defaulting to 0.0")
rate = 0.0

return rate


def configure():
SENTRY_DSN = os.environ.get("SENTRY_DSN")
if SENTRY_DSN:
release = get_release()
print(f"Enabling Sentry for environment '{SENTRY_ENVIRONMENT}', release '{release}'...")
logger.info(f"Enabling Sentry for environment '{SENTRY_ENVIRONMENT}', release '{release}'...")

# https://docs.sentry.io/platforms/python/configuration/
sentry_sdk.init(
dsn=SENTRY_DSN,
integrations=[
DjangoIntegration(),
],
traces_sample_rate=1.0,
traces_sample_rate=get_traces_sample_rate(),
environment=SENTRY_ENVIRONMENT,
release=release,
in_app_include=["benefits"],
Expand All @@ -88,4 +105,4 @@ def configure():
global SENTRY_CSP_REPORT_URI
SENTRY_CSP_REPORT_URI = os.environ.get("SENTRY_REPORT_URI", "")
else:
print("SENTRY_DSN not set, so won't send events")
logger.info("SENTRY_DSN not set, so won't send events")
10 changes: 10 additions & 0 deletions docs/configuration/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,15 @@ Collect information on Content-Security-Policy (CSP) violations. Read more about

To enable report collection, set this env var to the authenticated Sentry endpoint.

### `SENTRY_TRACES_SAMPLE_RATE`

!!! tldr "Sentry docs"

[`traces_sample_rate`](https://docs.sentry.io/platforms/python/configuration/sampling/#configuring-the-transaction-sample-rate)

Control the volume of transactions sent to Sentry. Value must be a float in the range `[0.0, 1.0]`.

The default is `0.0` (i.e. no transactions are tracked).

[app-service-config]: https://docs.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal
[getting-started_create-env]: ../getting-started/README.md#create-an-environment-file
7 changes: 4 additions & 3 deletions terraform/app_service.tf
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,10 @@ resource "azurerm_linux_web_app" "main" {
"HEALTHCHECK_USER_AGENTS" = local.is_dev ? null : "${local.secret_prefix}healthcheck-user-agents)",

# Sentry
"SENTRY_DSN" = "${local.secret_prefix}sentry-dsn)",
"SENTRY_ENVIRONMENT" = local.env_name,
"SENTRY_REPORT_URI" = "${local.secret_prefix}sentry-report-uri)",
"SENTRY_DSN" = "${local.secret_prefix}sentry-dsn)",
"SENTRY_ENVIRONMENT" = local.env_name,
"SENTRY_REPORT_URI" = "${local.secret_prefix}sentry-report-uri)",
"SENTRY_TRACES_SAMPLE_RATE" = "${local.secret_prefix}sentry-traces-sample-rate)",

# Environment variables for data migration
"MST_SENIOR_GROUP_ID" = "${local.secret_prefix}mst-senior-group-id)",
Expand Down
36 changes: 34 additions & 2 deletions tests/pytest/test_sentry.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from benefits import VERSION
from benefits.sentry import get_release
import os
from tempfile import NamedTemporaryFile

import pytest

from benefits import VERSION
from benefits.sentry import get_release, get_traces_sample_rate


def test_git(mocker):
mocker.patch("benefits.sentry.git_available", return_value=True)
Expand Down Expand Up @@ -45,3 +48,32 @@ def test_git_no_repo(mocker):
mocker.patch("benefits.sentry.get_sha_file_path", return_value=file_path)

assert get_release() == VERSION


def test_traces_sample_rate_default():
rate = get_traces_sample_rate()
assert rate == 0.0


@pytest.mark.parametrize("env_rate", ["0.0", "0.25", "0.99", "1.0"])
def test_traces_sample_rate_valid_range(mocker, env_rate):
mocker.patch("benefits.sentry.os.environ.get", return_value=env_rate)

rate = get_traces_sample_rate()
assert rate == float(env_rate)


@pytest.mark.parametrize("env_rate", ["-1.0", "-0.1", "1.01", "2.0"])
def test_traces_sample_rate_invalid_range(mocker, env_rate):
mocker.patch("benefits.sentry.os.environ.get", return_value=env_rate)

rate = get_traces_sample_rate()
assert rate == 0.0


@pytest.mark.parametrize("env_rate", ["zero", "one", "huh?"])
def test_traces_sample_rate_not_float(mocker, env_rate):
mocker.patch("benefits.sentry.os.environ.get", return_value=env_rate)

rate = get_traces_sample_rate()
assert rate == 0.0

0 comments on commit cdec5fb

Please sign in to comment.