-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from thread/logging-plugins
Logging plugin infrastructure
- Loading branch information
Showing
53 changed files
with
963 additions
and
120 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,7 @@ nosetests.xml | |
coverage.xml | ||
*.cover | ||
.hypothesis/ | ||
.pytest_cache/ | ||
|
||
# Translations | ||
*.mo | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
include README.md | ||
include routemaster/config/schema.yaml | ||
include version.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
include README.md | ||
include version.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
### routemaster-sentry | ||
|
||
Usage, in your Routemaster configuration file: | ||
|
||
```yaml | ||
plugins: | ||
logging: | ||
- class: routemaster_sentry.logger:SentryLogger | ||
kwargs: | ||
dsn: https://xxxxxxx:xxxxxxx@sentry.io/xxxxxxx | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
""" | ||
Sentry logger for Routemaster. | ||
This package provides a Routemaster logging plugin that interfaces to Raven, | ||
Sentry's Python reporting package. | ||
It adds per-request exception reporting to Flask for the API, and also wraps | ||
the cron, webhook request, and feed request processes with Sentry reporting. | ||
All wrapping re-raises exceptions, as Routemaster/Flask/the cron subsystem will | ||
all handle exceptions appropriately. | ||
""" | ||
import contextlib | ||
|
||
from raven import Client | ||
from raven.contrib.flask import Sentry | ||
|
||
from routemaster.logging import BaseLogger | ||
from routemaster.version import get_version | ||
|
||
|
||
class SentryLogger(BaseLogger): | ||
"""Instruments Routemaster with Sentry.""" | ||
|
||
def __init__(self, *args, dsn): | ||
version = get_version() | ||
|
||
self.client = Client( | ||
dsn, | ||
release=version, | ||
sample_rate=0 if 'dev' in version else 1, | ||
include_paths=[ | ||
'routemaster', | ||
], | ||
) | ||
|
||
super().__init__(*args) | ||
|
||
def init_flask(self, flask_app): | ||
"""Instrument Flask with Sentry.""" | ||
Sentry(flask_app, client=self.client) | ||
|
||
@contextlib.contextmanager | ||
def process_cron(self, state_machine, state, fn_name): | ||
"""Send cron exceptions to Sentry.""" | ||
try: | ||
yield | ||
except Exception: | ||
self.client.captureException() | ||
raise | ||
|
||
@contextlib.contextmanager | ||
def process_webhook(self, state_machine, state): | ||
"""Send webhook request exceptions to Sentry.""" | ||
try: | ||
yield | ||
except Exception: | ||
self.client.captureException() | ||
raise | ||
|
||
@contextlib.contextmanager | ||
def process_feed(self, state_machine, state, feed_url): | ||
"""Send feed request exceptions to Sentry.""" | ||
try: | ||
yield | ||
except Exception: | ||
self.client.captureException() | ||
raise |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
"""Package setup.""" | ||
|
||
import version | ||
from setuptools import setup, find_packages | ||
|
||
with open('README.md', 'r', encoding='utf-8') as f: | ||
long_description = f.read() | ||
|
||
try: | ||
from m2r import convert | ||
long_description = convert(long_description) | ||
except ImportError: | ||
# Fall back to markdown formatted readme when no m2r package. | ||
pass | ||
|
||
|
||
setup( | ||
name='routemaster_sentry', | ||
version=version.get_version(), | ||
url='https://github.com/thread/routemaster', | ||
description="Sentry error reporting for Routemaster.", | ||
long_description=long_description, | ||
|
||
author="Thread", | ||
author_email="tech@thread.com", | ||
|
||
keywords=( | ||
), | ||
license='MIT', | ||
|
||
zip_safe=False, | ||
|
||
packages=find_packages(), | ||
include_package_data=True, | ||
|
||
classifiers=( | ||
'Development Status :: 2 - Pre-Alpha', | ||
'Environment :: Console', | ||
'Natural Language :: English', | ||
'Operating System :: POSIX', | ||
'Programming Language :: Python', | ||
'Programming Language :: Python :: 3 :: Only', | ||
'Programming Language :: Python :: 3.6', | ||
'Topic :: Office/Business', | ||
), | ||
|
||
install_requires=( | ||
'routemaster', | ||
'raven[flask]', | ||
), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
""" | ||
Versioning utils. | ||
""" | ||
|
||
__all__ = ('get_version') | ||
|
||
import os | ||
import re | ||
import logging | ||
import os.path | ||
import subprocess | ||
from os.path import dirname | ||
|
||
import pkg_resources | ||
|
||
version_re = re.compile('^Version: (.+)$', re.M) | ||
|
||
logger = logging.getLogger(__file__) | ||
|
||
|
||
def find_git_root(test): | ||
prev, test = None, os.path.abspath(test) | ||
while prev != test: | ||
if os.path.isdir(os.path.join(test, '.git')): | ||
return test | ||
prev, test = test, os.path.abspath(os.path.join(test, os.pardir)) | ||
return None | ||
|
||
|
||
def get_version(): | ||
""" | ||
Gets the current version number. | ||
If in a git repository, it is the current git tag. | ||
Otherwise it is the one contained in the PKG-INFO file. | ||
To use this script, simply import it in your setup.py file | ||
and use the results of get_version() as your package version: | ||
from version import * | ||
setup( | ||
... | ||
version=get_version(), | ||
... | ||
) | ||
""" | ||
git_root = find_git_root(dirname(__file__)) | ||
|
||
if git_root is not None: | ||
# Get the version using "git describe". | ||
cmd = 'git describe --tags --match [0-9]*'.split() | ||
try: | ||
version = subprocess.check_output(cmd).decode().strip() | ||
except subprocess.CalledProcessError: | ||
logger.exception('Unable to get version number from git tags') | ||
exit(1) | ||
|
||
# PEP 386 compatibility | ||
if '-' in version: | ||
version = '.post'.join(version.split('-')[:2]) | ||
|
||
# Don't declare a version "dirty" merely because a time stamp has | ||
# changed. If it is dirty, append a ".dev1" suffix to indicate a | ||
# development revision after the release. | ||
with open(os.devnull, 'w') as fd_devnull: | ||
subprocess.call( | ||
['git', 'status'], | ||
stdout=fd_devnull, | ||
stderr=fd_devnull, | ||
) | ||
|
||
cmd = 'git diff-index --name-only HEAD'.split() | ||
try: | ||
dirty = subprocess.check_output(cmd).decode().strip() | ||
except subprocess.CalledProcessError: | ||
logger.exception('Unable to get git index status') | ||
exit(1) | ||
|
||
if dirty != '': | ||
version += '.dev1' | ||
|
||
return version | ||
|
||
else: | ||
try: | ||
return pkg_resources.working_set.by_key[ | ||
'routemaster_sentry' | ||
].version | ||
except KeyError: | ||
return '0.0.0-unreleased' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.