Coverage for gwcelery/sentry/__init__.py: 100%
28 statements
« prev ^ index » next coverage.py v7.4.4, created at 2024-11-14 05:52 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2024-11-14 05:52 +0000
1"""Error telemetry for `Sentry <https://sentry.io>`_."""
2from urllib.parse import urlparse, urlunparse
4import sentry_sdk
5from celery.utils.log import get_logger
6from safe_netrc import NetrcParseError, netrc
7from sentry_sdk.integrations import celery, flask, logging, redis, tornado
9from .. import _version
10from ..util import SPHINX
11from .integrations import condor, requests, subprocess
13log = get_logger(__name__)
15__all__ = ('configure', 'DSN')
17DSN = 'https://sentry.io/1425216'
18"""Sentry data source name (DSN)."""
21def configure():
22 """Configure Sentry logging integration for Celery.
24 See the `official instructions for Celery integration
25 <https://docs.sentry.io/platforms/python/celery/>`_.
27 Notes
28 -----
29 Add the API key username/pasword pair to your netrc file.
31 """
32 # Catching NetrcParseError confuses sphinx.
33 if SPHINX: # pragma: no cover
34 return
36 # Delayed import
37 from .. import app
39 scheme, netloc, *rest = urlparse(DSN)
41 try:
42 auth = netrc().authenticators(netloc)
43 if not auth:
44 raise ValueError('No netrc entry found for {}'.format(netloc))
45 except (NetrcParseError, OSError, ValueError):
46 log.exception('Disabling Sentry integration because we could not load '
47 'the username and password for %s from the netrc file',
48 netloc)
49 return
51 # Ignore noisy log but harmless messsages from adc-streaming.
52 #
53 # FIXME: Remove once https://git.ligo.org/emfollow/gwcelery/-/issues/457
54 # is fixed.
55 logging.ignore_logger('adc-streaming')
57 # The "legacy" Sentry DSN requires a "public key" and a "private key",
58 # which are transmitted as the username and password in the URL.
59 # However, as of Sentry 9, then "private key" part is no longer required.
60 username, _, _ = auth
61 dsn = urlunparse(
62 (scheme, '{}@{}'.format(username, netloc), *rest))
63 version = 'gwcelery-{}'.format(_version.get_versions()['version'])
64 environment = app.conf['sentry_environment']
65 sentry_sdk.init(dsn, environment=environment, release=version,
66 integrations=[celery.CeleryIntegration(),
67 condor.CondorIntegration(),
68 flask.FlaskIntegration(),
69 redis.RedisIntegration(),
70 requests.RequestsIntegration(),
71 subprocess.SubprocessIntegration(),
72 tornado.TornadoIntegration()])