Răsfoiți Sursa

Enable & document Sentry integration

jeremystretch 3 ani în urmă
părinte
comite
6f5c2f1e29

+ 27 - 0
docs/administration/error-reporting.md

@@ -0,0 +1,27 @@
+# Error Reporting
+
+## Sentry
+
+NetBox v3.2.3 and later support native integration with [Sentry](https://sentry.io/) for automatic error reporting. To enable this feature, begin by creating a new project in Sentry to represent your NetBox deployment and obtain its corresponding data source name (DSN). This looks like a URL similar to the example below:
+
+```
+https://examplePublicKey@o0.ingest.sentry.io/0
+```
+
+Once you have obtained a DSN, configure Sentry in NetBox's `configuration.py` file with the following parameters:
+
+```python
+SENTRY_ENABLED = True
+SENTRY_DSN = "https://YourDSNgoesHere@o0.ingest.sentry.io/0"
+```
+
+You can optionally attach one or more arbitrary tags to the outgoing error reports if desired by setting the `SENTRY_TAGS` parameter:
+
+```python
+SENTRY_TAGS = {
+    "custom.foo": "123",
+    "custom.bar": "abc",
+}
+```
+
+Once the configuration has been saved, restart the NetBox service.

+ 33 - 0
docs/configuration/optional-settings.md

@@ -404,6 +404,39 @@ 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 tags 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",
+}
+```
+
+---
+
 ## SESSION_COOKIE_NAME
 ## SESSION_COOKIE_NAME
 
 
 Default: `sessionid`
 Default: `sessionid`

+ 1 - 0
docs/release-notes/version-3.2.md

@@ -11,6 +11,7 @@
 * [#9278](https://github.com/netbox-community/netbox/issues/9278) - Linkify device types count under manufacturers list
 * [#9278](https://github.com/netbox-community/netbox/issues/9278) - Linkify device types count under manufacturers list
 * [#9280](https://github.com/netbox-community/netbox/issues/9280) - Allow adopting existing components when installing a module
 * [#9280](https://github.com/netbox-community/netbox/issues/9280) - Allow adopting existing components when installing a module
 * [#9314](https://github.com/netbox-community/netbox/issues/9314) - Add device and VM filters for FHRP group assignments
 * [#9314](https://github.com/netbox-community/netbox/issues/9314) - Add device and VM filters for FHRP group assignments
+* [#9340](https://github.com/netbox-community/netbox/issues/9340) - Introduce support for error reporting via Sentry
 
 
 ### Bug Fixes
 ### Bug Fixes
 
 

+ 1 - 0
mkdocs.yml

@@ -123,6 +123,7 @@ nav:
             - Microsoft Azure AD: 'administration/authentication/microsoft-azure-ad.md'
             - Microsoft Azure AD: 'administration/authentication/microsoft-azure-ad.md'
             - Okta: 'administration/authentication/okta.md'
             - Okta: 'administration/authentication/okta.md'
         - Permissions: 'administration/permissions.md'
         - Permissions: 'administration/permissions.md'
+        - Error Reporting: 'administration/error-reporting.md'
         - Housekeeping: 'administration/housekeeping.md'
         - Housekeeping: 'administration/housekeeping.md'
         - Replicating NetBox: 'administration/replicating-netbox.md'
         - Replicating NetBox: 'administration/replicating-netbox.md'
         - NetBox Shell: 'administration/netbox-shell.md'
         - NetBox Shell: 'administration/netbox-shell.md'

+ 25 - 0
netbox/netbox/settings.py

@@ -8,9 +8,11 @@ import sys
 import warnings
 import warnings
 from urllib.parse import urlsplit
 from urllib.parse import urlsplit
 
 
+import sentry_sdk
 from django.contrib.messages import constants as messages
 from django.contrib.messages import constants as messages
 from django.core.exceptions import ImproperlyConfigured, ValidationError
 from django.core.exceptions import ImproperlyConfigured, ValidationError
 from django.core.validators import URLValidator
 from django.core.validators import URLValidator
+from sentry_sdk.integrations.django import DjangoIntegration
 
 
 from netbox.config import PARAMS
 from netbox.config import PARAMS
 
 
@@ -113,6 +115,9 @@ REMOTE_AUTH_GROUP_SEPARATOR = getattr(configuration, 'REMOTE_AUTH_GROUP_SEPARATO
 REPORTS_ROOT = getattr(configuration, 'REPORTS_ROOT', os.path.join(BASE_DIR, 'reports')).rstrip('/')
 REPORTS_ROOT = getattr(configuration, 'REPORTS_ROOT', os.path.join(BASE_DIR, 'reports')).rstrip('/')
 RQ_DEFAULT_TIMEOUT = getattr(configuration, 'RQ_DEFAULT_TIMEOUT', 300)
 RQ_DEFAULT_TIMEOUT = getattr(configuration, 'RQ_DEFAULT_TIMEOUT', 300)
 SCRIPTS_ROOT = getattr(configuration, 'SCRIPTS_ROOT', os.path.join(BASE_DIR, 'scripts')).rstrip('/')
 SCRIPTS_ROOT = getattr(configuration, 'SCRIPTS_ROOT', os.path.join(BASE_DIR, 'scripts')).rstrip('/')
+SENTRY_DSN = getattr(configuration, 'SENTRY_DSN', None)
+SENTRY_ENABLED = getattr(configuration, 'SENTRY_ENABLED', False)
+SENTRY_TAGS = getattr(configuration, 'SENTRY_TAGS', {})
 SESSION_FILE_PATH = getattr(configuration, 'SESSION_FILE_PATH', None)
 SESSION_FILE_PATH = getattr(configuration, 'SESSION_FILE_PATH', None)
 SESSION_COOKIE_NAME = getattr(configuration, 'SESSION_COOKIE_NAME', 'sessionid')
 SESSION_COOKIE_NAME = getattr(configuration, 'SESSION_COOKIE_NAME', 'sessionid')
 SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d')
 SHORT_DATE_FORMAT = getattr(configuration, 'SHORT_DATE_FORMAT', 'Y-m-d')
@@ -428,6 +433,26 @@ EXEMPT_PATHS = (
 )
 )
 
 
 
 
+#
+# Sentry
+#
+
+if SENTRY_ENABLED:
+    if not SENTRY_DSN:
+        raise ImproperlyConfigured("SENTRY_ENABLED is True but SENTRY_DSN has not been defined.")
+    sentry_sdk.init(
+        dsn=SENTRY_DSN,
+        release=VERSION,
+        integrations=[DjangoIntegration()],
+        traces_sample_rate=1.0,
+        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
+    )
+    for k, v in SENTRY_TAGS.items():
+        sentry_sdk.set_tag(k, v)
+
+
 #
 #
 # Django social auth
 # Django social auth
 #
 #