From 72b2ab03cc11abcf97984f3f0eac027b618066e2 Mon Sep 17 00:00:00 2001 From: jeremystretch Date: Thu, 12 May 2022 10:00:57 -0400 Subject: [PATCH] #9340: Introduce config parameters for Sentry sampling rates --- docs/configuration/error-reporting.md | 54 +++++++++++++++++++++++++ docs/configuration/optional-settings.md | 36 ----------------- mkdocs.yml | 1 + netbox/netbox/settings.py | 19 ++++++--- 4 files changed, 69 insertions(+), 41 deletions(-) create mode 100644 docs/configuration/error-reporting.md diff --git a/docs/configuration/error-reporting.md b/docs/configuration/error-reporting.md new file mode 100644 index 000000000..d1c47e2fb --- /dev/null +++ b/docs/configuration/error-reporting.md @@ -0,0 +1,54 @@ +# Error Reporting Settings + +## SENTRY_DSN + +Default: None + +Defines a Sentry data source name (DSN) for automated error reporting. `SENTRY_ENABLED` must be True for this parameter to take effect. For example: + +``` +SENTRY_DSN = "https://examplePublicKey@o0.ingest.sentry.io/0" +``` + +--- + +## SENTRY_ENABLED + +Default: False + +Set to True to enable automatic error reporting via [Sentry](https://sentry.io/). + +--- + +## SENTRY_SAMPLE_RATE + +Default: 1.0 (all) + +The sampling rate for errors. Must be a value between 0 (disabled) and 1.0 (report on all errors). + +--- + +## SENTRY_TAGS + +An optional dictionary of tag names and values to apply to Sentry error reports.For example: + +``` +SENTRY_TAGS = { + "custom.foo": "123", + "custom.bar": "abc", +} +``` + +!!! warning "Reserved tag prefixes" + Avoid using any tag names which begin with `netbox.`, as this prefix is reserved by the NetBox application. + +--- + +## SENTRY_TRACES_SAMPLE_RATE + +Default: 0 (disabled) + +The sampling rate for transactions. Must be a value between 0 (disabled) and 1.0 (report on all transactions). + +!!! warning "Consider performance implications" + A high sampling rate for transactions can induce significant performance penalties. If transaction reporting is desired, it is recommended to use a relatively low sample rate of 10% to 20% (0.1 to 0.2). diff --git a/docs/configuration/optional-settings.md b/docs/configuration/optional-settings.md index 58f8cb526..76fd0a12c 100644 --- a/docs/configuration/optional-settings.md +++ b/docs/configuration/optional-settings.md @@ -404,42 +404,6 @@ The file path to the location where [custom scripts](../customization/custom-scr --- -## SENTRY_DSN - -Default: None - -Defines a Sentry data source name (DSN) for automated error reporting. `SENTRY_ENABLED` must be True for this parameter to take effect. For example: - -``` -SENTRY_DSN = "https://examplePublicKey@o0.ingest.sentry.io/0" -``` - ---- - -## SENTRY_ENABLED - -Default: False - -Set to True to enable automatic error reporting via [Sentry](https://sentry.io/). Requires `SENTRY_DSN` to be defined. - ---- - -## SENTRY_TAGS - -An optional dictionary of tag names and values to apply to Sentry error reports. `SENTRY_ENABLED` must be True for this parameter to take effect. For example: - -``` -SENTRY_TAGS = { - "custom.foo": "123", - "custom.bar": "abc", -} -``` - -!!! warning "Reserved tag prefixes" - Avoid using any tag names which begin with `netbox.`, as this prefix is reserved by the NetBox application. - ---- - ## SESSION_COOKIE_NAME Default: `sessionid` diff --git a/mkdocs.yml b/mkdocs.yml index 0b7108cd0..5c973e0d6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -73,6 +73,7 @@ nav: - Required Settings: 'configuration/required-settings.md' - Optional Settings: 'configuration/optional-settings.md' - Dynamic Settings: 'configuration/dynamic-settings.md' + - Error Reporting: 'configuration/error-reporting.md' - Remote Authentication: 'configuration/remote-authentication.md' - Core Functionality: - IP Address Management: 'core-functionality/ipam.md' diff --git a/netbox/netbox/settings.py b/netbox/netbox/settings.py index 2dfbf9be6..fafcf35a1 100644 --- a/netbox/netbox/settings.py +++ b/netbox/netbox/settings.py @@ -72,6 +72,9 @@ DATABASE = getattr(configuration, 'DATABASE') REDIS = getattr(configuration, 'REDIS') SECRET_KEY = getattr(configuration, 'SECRET_KEY') +# Calculate a unique deployment ID from the secret key +DEPLOYMENT_ID = hashlib.sha256(SECRET_KEY.encode('utf-8')).hexdigest()[:16] + # Set static config parameters ADMINS = getattr(configuration, 'ADMINS', []) AUTH_PASSWORD_VALIDATORS = getattr(configuration, 'AUTH_PASSWORD_VALIDATORS', []) @@ -119,6 +122,8 @@ RQ_DEFAULT_TIMEOUT = getattr(configuration, 'RQ_DEFAULT_TIMEOUT', 300) SCRIPTS_ROOT = getattr(configuration, 'SCRIPTS_ROOT', os.path.join(BASE_DIR, 'scripts')).rstrip('/') SENTRY_DSN = getattr(configuration, 'SENTRY_DSN', DEFAULT_SENTRY_DSN) SENTRY_ENABLED = getattr(configuration, 'SENTRY_ENABLED', False) +SENTRY_SAMPLE_RATE = getattr(configuration, 'SENTRY_SAMPLE_RATE', 1.0) +SENTRY_TRACES_SAMPLE_RATE = getattr(configuration, 'SENTRY_TRACES_SAMPLE_RATE', 0) SENTRY_TAGS = getattr(configuration, 'SENTRY_TAGS', {}) SESSION_FILE_PATH = getattr(configuration, 'SESSION_FILE_PATH', None) SESSION_COOKIE_NAME = getattr(configuration, 'SESSION_COOKIE_NAME', 'sessionid') @@ -442,23 +447,27 @@ EXEMPT_PATHS = ( if SENTRY_ENABLED: if not SENTRY_DSN: raise ImproperlyConfigured("SENTRY_ENABLED is True but SENTRY_DSN has not been defined.") + # If using the default DSN, force sampling rates + if SENTRY_DSN == DEFAULT_SENTRY_DSN: + SENTRY_SAMPLE_RATE = 1.0 + SENTRY_TRACES_SAMPLE_RATE = 0 + # Initialize the SDK sentry_sdk.init( dsn=SENTRY_DSN, release=VERSION, integrations=[DjangoIntegration()], - traces_sample_rate=1.0, + sample_rate=SENTRY_SAMPLE_RATE, + traces_sample_rate=SENTRY_TRACES_SAMPLE_RATE, send_default_pii=True, http_proxy=HTTP_PROXIES.get('http') if HTTP_PROXIES else None, https_proxy=HTTP_PROXIES.get('https') if HTTP_PROXIES else None ) + # Assign any configured tags for k, v in SENTRY_TAGS.items(): sentry_sdk.set_tag(k, v) # If using the default DSN, append a unique deployment ID tag for error correlation if SENTRY_DSN == DEFAULT_SENTRY_DSN: - sentry_sdk.set_tag( - 'netbox.deployment_id', - hashlib.sha256(SECRET_KEY.encode('utf-8')).hexdigest()[:16] - ) + sentry_sdk.set_tag('netbox.deployment_id', DEPLOYMENT_ID) #