├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.rst ├── docs └── images │ └── options.png ├── setup.py └── src └── sentry_statsd ├── __init__.py ├── forms.py └── plugin.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Python compiles files 2 | *.pyc 3 | *.pyo 4 | 5 | # Hate OS X 6 | .DS_Store 7 | 8 | # Some editors files 9 | ._* 10 | *.swp 11 | 12 | # hidden files 13 | .* 14 | # except these 15 | !/.gitignore 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2013 Vladimir Rudnyh 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include setup.py README.rst MANIFEST.in LICENSE 2 | recursive-include sentry_statsd * 3 | global-exclude *~ 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | sentry-statsd 2 | ============= 3 | 4 | An extension for Sentry to send errors metrics to StatsD. 5 | 6 | Install 7 | ------- 8 | 9 | Install the package with ``pip``:: 10 | 11 | pip install sentry-statsd 12 | 13 | 14 | Configuration 15 | ------------- 16 | 17 | Go to your project's configuration page (Projects -> [Project]) and select the 18 | "StatsD" tab. Enter the StatsS host, port and prefix for metrics: 19 | 20 | .. image:: https://github.com/dreadatour/sentry-statsd/raw/master/docs/images/options.png 21 | 22 | 23 | After installing and configuring, make sure to restart sentry-worker for the 24 | changes to take into effect. 25 | -------------------------------------------------------------------------------- /docs/images/options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dreadatour/sentry-statsd/82716c4e3024ace3cf40167af5d2191a866a9358/docs/images/options.png -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from setuptools import setup, find_packages 3 | 4 | install_requires = [ 5 | 'sentry>=5.3.3', 6 | 'statsd', 7 | ] 8 | 9 | f = open('README.rst') 10 | readme = f.read() 11 | f.close() 12 | 13 | setup( 14 | name='sentry-statsd', 15 | version='0.0.2', 16 | author='Vladimir Rudnyh', 17 | author_email='dreadatour@gmail.com', 18 | url='http://github.com/dreadatour/sentry-statsd', 19 | description='A Sentry extension which send errors stats to StatsD', 20 | long_description=readme, 21 | license='WTFPL', 22 | package_dir={'': 'src'}, 23 | packages=find_packages('src'), 24 | install_requires=install_requires, 25 | entry_points={ 26 | 'sentry.plugins': [ 27 | 'sentry_statsd = sentry_statsd.plugin:StatsdPlugin' 28 | ], 29 | }, 30 | include_package_data=True, 31 | zip_safe=False, 32 | classifiers=[ 33 | 'Intended Audience :: Developers', 34 | 'Intended Audience :: System Administrators', 35 | 'Operating System :: OS Independent', 36 | 'Programming Language :: Python', 37 | 'Framework :: Django', 38 | 'Topic :: Software Development' 39 | ], 40 | keywords='sentry statsd', 41 | ) 42 | -------------------------------------------------------------------------------- /src/sentry_statsd/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | sentry_statsd 4 | """ 5 | 6 | VERSION = '0.0.2' 7 | -------------------------------------------------------------------------------- /src/sentry_statsd/forms.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | sentry_statsd.forms 4 | """ 5 | from django import forms 6 | 7 | 8 | class StatsdOptionsForm(forms.Form): 9 | host = forms.CharField( 10 | max_length=255, 11 | help_text='StatsD host (for example: "localhost")' 12 | ) 13 | port = forms.IntegerField( 14 | max_value=65535, 15 | help_text='StatsD port (for example: "8125")' 16 | ) 17 | prefix = forms.CharField( 18 | max_length=255, 19 | help_text='Prefix for Sentry metrics in StatsD (for example: "sentry")' 20 | ) 21 | add_loggers = forms.BooleanField( 22 | required=False, 23 | help_text='Add loggers names to StatsD metrics (otherwise only project names will be used)' 24 | ) 25 | track_only_new = forms.BooleanField( 26 | required=False, 27 | help_text='Add statsd count to only new exceptions') 28 | -------------------------------------------------------------------------------- /src/sentry_statsd/plugin.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | """ 3 | sentry_statsd.plugin 4 | """ 5 | import statsd 6 | from sentry.plugins import Plugin 7 | 8 | import sentry_statsd 9 | from sentry_statsd.forms import StatsdOptionsForm 10 | 11 | 12 | class StatsdPlugin(Plugin): 13 | """ 14 | Sentry plugin to send errors stats to StatsD. 15 | """ 16 | author = 'Vladimir Rudnyh' 17 | author_url = 'https://github.com/dreadatour/sentry-statsd' 18 | version = sentry_statsd.VERSION 19 | description = 'Send errors stats to StatsD.' 20 | slug = 'statsd' 21 | title = 'StatsD' 22 | conf_key = slug 23 | conf_title = title 24 | resource_links = [ 25 | ('Source', 'https://github.com/dreadatour/sentry-statsd'), 26 | ('Bug Tracker', 'https://github.com/dreadatour/sentry-statsd/issues'), 27 | ('README', 'https://github.com/dreadatour/sentry-statsd/blob/master/README.rst'), 28 | ] 29 | project_conf_form = StatsdOptionsForm 30 | 31 | def is_configured(self, project, **kwargs): 32 | """ 33 | Check if plugin is configured. 34 | """ 35 | params = self.get_option 36 | return bool(params('host', project) and params('port', project)) 37 | 38 | def post_process(self, group, event, is_new, is_sample, **kwargs): 39 | """ 40 | Process error. 41 | """ 42 | if not self.is_configured(group.project): 43 | return 44 | 45 | host = self.get_option('host', group.project) 46 | port = self.get_option('port', group.project) 47 | prefix = self.get_option('prefix', group.project) 48 | add_loggers = self.get_option('add_loggers', group.project) 49 | track_only_new = self.get_option('track_only_new', group.project) 50 | 51 | metric = [] 52 | metric.append(group.project.slug.replace('-', '_')) 53 | if add_loggers: 54 | metric.append(group.logger) 55 | metric.append(group.get_level_display()) 56 | 57 | client = statsd.StatsClient(host, port, prefix=prefix) 58 | 59 | if not track_only_new or (is_new and track_only_new): 60 | client.incr('.'.join(metric)) 61 | --------------------------------------------------------------------------------