From 9e97d48012cea235b3cae6b7b1fc061612e85c48 Mon Sep 17 00:00:00 2001 From: Daniel Welch Date: Thu, 30 Mar 2017 21:51:57 -0400 Subject: [PATCH 1/3] registering entry points for sentry and rollbar plugins, maintained in seperate repos. start of a generic error handling implementation --- django_q/conf.py | 56 +++++++++++++++++++++++++++++++++++++----------- setup.py | 12 ++++++++++- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/django_q/conf.py b/django_q/conf.py index 9bfbe71..9dffaf5 100644 --- a/django_q/conf.py +++ b/django_q/conf.py @@ -9,6 +9,7 @@ from django.conf import settings # external import os +import pkg_resources # optional try: @@ -141,8 +142,8 @@ class Conf(object): # The redis stats key Q_STAT = 'django_q:{}:cluster'.format(PREFIX) - # Optional Rollbar key - ROLLBAR = conf.get('rollbar', {}) + # Optional error reporting setup + ERROR_REPORTER = conf.get('error_reporter', {}) # OSX doesn't implement qsize because of missing sem_getvalue() try: @@ -177,17 +178,48 @@ if not logger.handlers: handler.setFormatter(formatter) logger.addHandler(handler) -# rollbar -if Conf.ROLLBAR: - rollbar_conf = deepcopy(Conf.ROLLBAR) - try: - import rollbar - rollbar.init(rollbar_conf.pop('access_token'), environment=rollbar_conf.pop('environment'), **rollbar_conf) - except ImportError: - rollbar = None -else: - rollbar = None +# Error Reporting Interface +class ErrorReporter(object): + + # initialize with iterator of reporters (better name, targets?) + def __init__(self, reporters): + self.targets = [target for target in reporters] + + # report error to all configured targets + def report(self): + for t in self.targets: + t.report() + + +# error reporting setup (sentry or rollbar) +if Conf.ERROR_REPORTER: + error_conf = deepcopy(Conf.ERROR_REPORTER) + try: + reporters = [] + # iterate through the configured error reporters, + # and instantiate an ErrorReporter using the provided config + for name, conf in error_conf.items(): + Reporter = pkg_resources.iter_entry_points( + 'djangoq.errorreporters', name).load() + e = Reporter(**conf) + reporters.append(e) + error_reporter = ErrorReporter(reporters) + except ImportError: + error_reporter = None + +# # rollbar +# if Conf.ROLLBAR: +# rollbar_conf = deepcopy(Conf.ROLLBAR) +# try: +# import rollbar +# rollbar.init(rollbar_conf.pop('access_token'), environment=rollbar_conf.pop('environment'), **rollbar_conf) +# except ImportError: +# rollbar = None + +# else: +# rollbar = None + # get parent pid compatibility diff --git a/setup.py b/setup.py index ee94ecb..2be17c7 100644 --- a/setup.py +++ b/setup.py @@ -55,5 +55,15 @@ setup( 'Programming Language :: Python :: 3.5', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Software Development :: Libraries :: Python Modules', - ] + ], + entry_points={ + 'djangoq.errorreporters': [ + 'rollbar = django_q_rollbar.Rollbar', + 'sentry = django_q_sentry.Sentry', + ] + }, + extras_require={ + 'rollbar': ["django-q-rollbar>=0.1"], + 'sentry': ["django-q-sentry>=0.1"], + } ) From aac6984ec3d100f604eccaa9c4a9ee612280f392 Mon Sep 17 00:00:00 2001 From: Daniel Welch Date: Thu, 30 Mar 2017 22:02:31 -0400 Subject: [PATCH 2/3] replace rollbar reporting with generic error_reporter reporting in cluster.py --- django_q/cluster.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/django_q/cluster.py b/django_q/cluster.py index 3810b15..ba50bcc 100644 --- a/django_q/cluster.py +++ b/django_q/cluster.py @@ -30,7 +30,7 @@ from django import db import signing import tasks -from django_q.conf import Conf, logger, psutil, get_ppid, rollbar +from django_q.conf import Conf, logger, psutil, get_ppid, error_reporter from django_q.models import Task, Success, Schedule from django_q.status import Stat, Status from django_q.brokers import get_broker @@ -368,8 +368,8 @@ def worker(task_queue, result_queue, timer, timeout=Conf.TIMEOUT): f = getattr(m, func) except (ValueError, ImportError, AttributeError) as e: result = (e, False) - if rollbar: - rollbar.report_exc_info() + if error_reporter: + error_reporter.report() # We're still going if not result: db.close_old_connections() @@ -380,8 +380,8 @@ def worker(task_queue, result_queue, timer, timeout=Conf.TIMEOUT): result = (res, True) except Exception as e: result = ('{}'.format(e), False) - if rollbar: - rollbar.report_exc_info() + if error_reporter: + error_reporter.report() # Process result task['result'] = result[0] task['success'] = result[1] From c82ef6a1770827fc791900cf35fd4617b185000f Mon Sep 17 00:00:00 2001 From: Daniel Welch Date: Thu, 30 Mar 2017 22:12:31 -0400 Subject: [PATCH 3/3] fixing export from conf --- django_q/conf.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/django_q/conf.py b/django_q/conf.py index 9dffaf5..bf62a17 100644 --- a/django_q/conf.py +++ b/django_q/conf.py @@ -207,6 +207,8 @@ if Conf.ERROR_REPORTER: error_reporter = ErrorReporter(reporters) except ImportError: error_reporter = None +else: + error_reporter = None # # rollbar # if Conf.ROLLBAR: