mirror of
https://github.com/inventree/InvenTree.git
synced 2025-04-28 19:46:46 +00:00
sentry.io improvements (#4712)
* Write function to catch sentry.io events before sending - Will let us ignore certain types of errors which we are not interested in * Cleanup * Include release info * Allow sentry reporting in debug mode * Consolidate DRF sentry code into InvenTree/sentry.py * Add more error types to ignore * update docs
This commit is contained in:
parent
8d28fc06be
commit
f6021c4749
@ -18,6 +18,8 @@ from rest_framework import serializers
|
|||||||
from rest_framework.exceptions import ValidationError as DRFValidationError
|
from rest_framework.exceptions import ValidationError as DRFValidationError
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
|
||||||
|
import InvenTree.sentry
|
||||||
|
|
||||||
logger = logging.getLogger('inventree')
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
@ -61,18 +63,12 @@ def exception_handler(exc, context):
|
|||||||
"""
|
"""
|
||||||
response = None
|
response = None
|
||||||
|
|
||||||
if settings.SENTRY_ENABLED and settings.SENTRY_DSN and not settings.DEBUG:
|
# Pass exception to sentry.io handler
|
||||||
# Report this exception to sentry.io
|
try:
|
||||||
from sentry_sdk import capture_exception
|
InvenTree.sentry.report_exception(exc)
|
||||||
|
except Exception:
|
||||||
# The following types of errors are ignored, they are "expected"
|
# If sentry.io fails, we don't want to crash the server!
|
||||||
do_not_report = [
|
pass
|
||||||
DjangoValidationError,
|
|
||||||
DRFValidationError,
|
|
||||||
]
|
|
||||||
|
|
||||||
if not any([isinstance(exc, err) for err in do_not_report]):
|
|
||||||
capture_exception(exc)
|
|
||||||
|
|
||||||
# Catch any django validation error, and re-throw a DRF validation error
|
# Catch any django validation error, and re-throw a DRF validation error
|
||||||
if isinstance(exc, DjangoValidationError):
|
if isinstance(exc, DjangoValidationError):
|
||||||
|
68
InvenTree/InvenTree/sentry.py
Normal file
68
InvenTree/InvenTree/sentry.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
"""Configuration for Sentry.io error reporting."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core.exceptions import ValidationError
|
||||||
|
from django.http import Http404
|
||||||
|
|
||||||
|
import rest_framework.exceptions
|
||||||
|
import sentry_sdk
|
||||||
|
from sentry_sdk.integrations.django import DjangoIntegration
|
||||||
|
|
||||||
|
from InvenTree.version import INVENTREE_SW_VERSION
|
||||||
|
|
||||||
|
logger = logging.getLogger('inventree')
|
||||||
|
|
||||||
|
|
||||||
|
def default_sentry_dsn():
|
||||||
|
"""Return the default Sentry.io DSN for InvenTree"""
|
||||||
|
|
||||||
|
return 'https://3928ccdba1d34895abde28031fd00100@o378676.ingest.sentry.io/6494600'
|
||||||
|
|
||||||
|
|
||||||
|
def sentry_ignore_errors():
|
||||||
|
"""Return a list of error types to ignore.
|
||||||
|
|
||||||
|
These error types will *not* be reported to sentry.io.
|
||||||
|
"""
|
||||||
|
|
||||||
|
return [
|
||||||
|
Http404,
|
||||||
|
ValidationError,
|
||||||
|
rest_framework.exceptions.AuthenticationFailed,
|
||||||
|
rest_framework.exceptions.PermissionDenied,
|
||||||
|
rest_framework.exceptions.ValidationError,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def init_sentry(dsn, sample_rate, tags):
|
||||||
|
"""Initialize sentry.io error reporting"""
|
||||||
|
|
||||||
|
logger.info("Initializing sentry.io integration")
|
||||||
|
|
||||||
|
sentry_sdk.init(
|
||||||
|
dsn=dsn,
|
||||||
|
integrations=[DjangoIntegration()],
|
||||||
|
traces_sample_rate=sample_rate,
|
||||||
|
send_default_pii=True,
|
||||||
|
ignore_errors=sentry_ignore_errors(),
|
||||||
|
release=INVENTREE_SW_VERSION,
|
||||||
|
)
|
||||||
|
|
||||||
|
for key, val in tags.items():
|
||||||
|
sentry_sdk.set_tag(f'inventree_{key}', val)
|
||||||
|
|
||||||
|
|
||||||
|
def report_exception(exc):
|
||||||
|
"""Report an exception to sentry.io"""
|
||||||
|
|
||||||
|
if settings.SENTRY_ENABLED and settings.SENTRY_DSN:
|
||||||
|
|
||||||
|
if not any([isinstance(exc, e) for e in sentry_ignore_errors()]):
|
||||||
|
logger.info(f"Reporting exception to sentry.io: {exc}")
|
||||||
|
|
||||||
|
try:
|
||||||
|
sentry_sdk.capture_exception(exc)
|
||||||
|
except Exception:
|
||||||
|
logger.warning("Failed to report exception to sentry.io")
|
@ -21,12 +21,12 @@ from django.http import Http404
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
import moneyed
|
import moneyed
|
||||||
import sentry_sdk
|
|
||||||
from sentry_sdk.integrations.django import DjangoIntegration
|
from InvenTree.config import get_boolean_setting, get_custom_file, get_setting
|
||||||
|
from InvenTree.sentry import default_sentry_dsn, init_sentry
|
||||||
|
from InvenTree.version import inventreeApiVersion
|
||||||
|
|
||||||
from . import config
|
from . import config
|
||||||
from .config import get_boolean_setting, get_custom_file, get_setting
|
|
||||||
from .version import inventreeApiVersion
|
|
||||||
|
|
||||||
INVENTREE_NEWS_URL = 'https://inventree.org/news/feed.atom'
|
INVENTREE_NEWS_URL = 'https://inventree.org/news/feed.atom'
|
||||||
|
|
||||||
@ -573,29 +573,21 @@ REMOTE_LOGIN_HEADER = get_setting('INVENTREE_REMOTE_LOGIN_HEADER', 'remote_login
|
|||||||
|
|
||||||
# sentry.io integration for error reporting
|
# sentry.io integration for error reporting
|
||||||
SENTRY_ENABLED = get_boolean_setting('INVENTREE_SENTRY_ENABLED', 'sentry_enabled', False)
|
SENTRY_ENABLED = get_boolean_setting('INVENTREE_SENTRY_ENABLED', 'sentry_enabled', False)
|
||||||
|
|
||||||
# Default Sentry DSN (can be overriden if user wants custom sentry integration)
|
# Default Sentry DSN (can be overriden if user wants custom sentry integration)
|
||||||
INVENTREE_DSN = 'https://3928ccdba1d34895abde28031fd00100@o378676.ingest.sentry.io/6494600'
|
SENTRY_DSN = get_setting('INVENTREE_SENTRY_DSN', 'sentry_dsn', default_sentry_dsn())
|
||||||
SENTRY_DSN = get_setting('INVENTREE_SENTRY_DSN', 'sentry_dsn', INVENTREE_DSN)
|
|
||||||
SENTRY_SAMPLE_RATE = float(get_setting('INVENTREE_SENTRY_SAMPLE_RATE', 'sentry_sample_rate', 0.1))
|
SENTRY_SAMPLE_RATE = float(get_setting('INVENTREE_SENTRY_SAMPLE_RATE', 'sentry_sample_rate', 0.1))
|
||||||
|
|
||||||
if SENTRY_ENABLED and SENTRY_DSN: # pragma: no cover
|
if SENTRY_ENABLED and SENTRY_DSN: # pragma: no cover
|
||||||
|
|
||||||
logger.info("Running with sentry.io integration enabled")
|
|
||||||
|
|
||||||
sentry_sdk.init(
|
|
||||||
dsn=SENTRY_DSN,
|
|
||||||
integrations=[DjangoIntegration(), ],
|
|
||||||
traces_sample_rate=1.0 if DEBUG else SENTRY_SAMPLE_RATE,
|
|
||||||
send_default_pii=True
|
|
||||||
)
|
|
||||||
inventree_tags = {
|
inventree_tags = {
|
||||||
'testing': TESTING,
|
'testing': TESTING,
|
||||||
'docker': DOCKER,
|
'docker': DOCKER,
|
||||||
'debug': DEBUG,
|
'debug': DEBUG,
|
||||||
'remote': REMOTE_LOGIN,
|
'remote': REMOTE_LOGIN,
|
||||||
}
|
}
|
||||||
for key, val in inventree_tags.items():
|
|
||||||
sentry_sdk.set_tag(f'inventree_{key}', val)
|
init_sentry(SENTRY_DSN, SENTRY_SAMPLE_RATE, inventree_tags)
|
||||||
|
|
||||||
# Cache configuration
|
# Cache configuration
|
||||||
cache_host = get_setting('INVENTREE_CACHE_HOST', 'cache.host', None)
|
cache_host = get_setting('INVENTREE_CACHE_HOST', 'cache.host', None)
|
||||||
|
@ -27,3 +27,7 @@ A list of error logs is presented.
|
|||||||
## Reporting Errors
|
## Reporting Errors
|
||||||
|
|
||||||
Errors should be reported to the [InvenTree GitHub page](https://github.com/inventree/inventree/issues), and include the full error output as recorded to the error log.
|
Errors should be reported to the [InvenTree GitHub page](https://github.com/inventree/inventree/issues), and include the full error output as recorded to the error log.
|
||||||
|
|
||||||
|
### Sentry Integration
|
||||||
|
|
||||||
|
If [sentry.io integration](../start/config.md#sentry-integration) is enabled, some error logs are automatically reported to sentry.io
|
||||||
|
Loading…
x
Reference in New Issue
Block a user