From 6813eef08cb4de119157e73d1589e75ab3738bba Mon Sep 17 00:00:00 2001 From: ryan-s Date: Thu, 18 Jan 2018 17:36:44 -0500 Subject: [PATCH 1/5] update celery context --- raven/contrib/celery/__init__.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/raven/contrib/celery/__init__.py b/raven/contrib/celery/__init__.py index 02f3ab00e..df28b2165 100644 --- a/raven/contrib/celery/__init__.py +++ b/raven/contrib/celery/__init__.py @@ -8,6 +8,7 @@ from __future__ import absolute_import import logging +import inspect from celery.exceptions import SoftTimeLimitExceeded from celery.signals import ( @@ -27,7 +28,7 @@ def filter(self, record): def register_signal(client, ignore_expected=False): - SentryCeleryHandler(client, ignore_expected=ignore_expected).install() + SentryCeleryHandler(client, ignore_expected=ignore_expected, context_args=[]).install() def register_logger_signal(client, logger=None, loglevel=logging.ERROR): @@ -53,9 +54,10 @@ def process_logger_event(sender, logger, loglevel, logfile, format, class SentryCeleryHandler(object): - def __init__(self, client, ignore_expected=False): + def __init__(self, client, ignore_expected=False, context_args=None): self.client = client self.ignore_expected = ignore_expected + self.context_args = context_args def install(self): task_prerun.connect(self.handle_task_prerun, weak=False) @@ -89,6 +91,16 @@ def process_failure_signal(self, sender, task_id, args, kwargs, einfo, **kw): def handle_task_prerun(self, sender, task_id, task, **kw): self.client.context.activate() + if self.context_args: + args = inspect.getargspec(task.run) + # first arg is going to be self + args.pop(0) + tags = {} + for i, arg in enumerate(args): + if arg in self.context_args: + tags.update({arg, kw['args'][i]}) + context = {'tags': tags} + self.client.context.merge(context) self.client.transaction.push(task.name) def handle_task_postrun(self, sender, task_id, task, **kw): From 43daa98f1cb8eecc8544d9e9161528285568966d Mon Sep 17 00:00:00 2001 From: ryan-s Date: Fri, 19 Jan 2018 09:19:18 -0500 Subject: [PATCH 2/5] add support for kwargs --- raven/contrib/celery/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/raven/contrib/celery/__init__.py b/raven/contrib/celery/__init__.py index df28b2165..e0dba970a 100644 --- a/raven/contrib/celery/__init__.py +++ b/raven/contrib/celery/__init__.py @@ -99,6 +99,9 @@ def handle_task_prerun(self, sender, task_id, task, **kw): for i, arg in enumerate(args): if arg in self.context_args: tags.update({arg, kw['args'][i]}) + for k, v in kw['kwargs'].iteritems(): + if k in self.context_args: + tags.update({k, v}) context = {'tags': tags} self.client.context.merge(context) self.client.transaction.push(task.name) From a1b333f102bb9c74fa30426697b17e836169f519 Mon Sep 17 00:00:00 2001 From: ryan-s Date: Fri, 19 Jan 2018 09:32:55 -0500 Subject: [PATCH 3/5] update register signal --- raven/contrib/celery/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/raven/contrib/celery/__init__.py b/raven/contrib/celery/__init__.py index e0dba970a..b9e5939da 100644 --- a/raven/contrib/celery/__init__.py +++ b/raven/contrib/celery/__init__.py @@ -27,7 +27,7 @@ def filter(self, record): return extra_data.get('internal', record.funcName != '_log_error') -def register_signal(client, ignore_expected=False): +def register_signal(client, ignore_expected=False, context_args=None): SentryCeleryHandler(client, ignore_expected=ignore_expected, context_args=[]).install() From 909eb7fc8adc3ac92019ca091cb1958a4ae9814f Mon Sep 17 00:00:00 2001 From: ryan-s Date: Fri, 19 Jan 2018 14:39:48 -0500 Subject: [PATCH 4/5] bug fixes and setting the context on the proper client --- raven/contrib/celery/__init__.py | 41 +++++++++++++++++++------------- tests/contrib/test_celery.py | 16 ++++++++++++- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/raven/contrib/celery/__init__.py b/raven/contrib/celery/__init__.py index b9e5939da..e5aaf5686 100644 --- a/raven/contrib/celery/__init__.py +++ b/raven/contrib/celery/__init__.py @@ -12,7 +12,7 @@ from celery.exceptions import SoftTimeLimitExceeded from celery.signals import ( - after_setup_logger, task_failure, task_prerun, task_postrun + after_setup_logger, task_failure, task_prerun, task_postrun, after_setup_task_logger ) from raven.handlers.logging import SentryHandler @@ -28,12 +28,11 @@ def filter(self, record): def register_signal(client, ignore_expected=False, context_args=None): - SentryCeleryHandler(client, ignore_expected=ignore_expected, context_args=[]).install() + SentryCeleryHandler(client, ignore_expected=ignore_expected, context_args=context_args).install() def register_logger_signal(client, logger=None, loglevel=logging.ERROR): filter_ = CeleryFilter() - handler = SentryHandler(client) handler.setLevel(loglevel) handler.addFilter(filter_) @@ -47,7 +46,7 @@ def process_logger_event(sender, logger, loglevel, logfile, format, if isinstance(h, SentryHandler): h.addFilter(filter_) return False - + handler.client.tags_context({'woah': 'nelly'}) logger.addHandler(handler) after_setup_logger.connect(process_logger_event, weak=False) @@ -92,20 +91,30 @@ def process_failure_signal(self, sender, task_id, args, kwargs, einfo, **kw): def handle_task_prerun(self, sender, task_id, task, **kw): self.client.context.activate() if self.context_args: - args = inspect.getargspec(task.run) - # first arg is going to be self - args.pop(0) - tags = {} - for i, arg in enumerate(args): - if arg in self.context_args: - tags.update({arg, kw['args'][i]}) - for k, v in kw['kwargs'].iteritems(): - if k in self.context_args: - tags.update({k, v}) - context = {'tags': tags} - self.client.context.merge(context) + context = self.infer_context(task, **kw) + self.set_logger_context(context) self.client.transaction.push(task.name) def handle_task_postrun(self, sender, task_id, task, **kw): self.client.transaction.pop(task.name) self.client.context.clear() + + def infer_context(self, task, **kw): + args = inspect.getargspec(task.run).args + # first arg is going to be self + args.pop(0) + tags = {} + for i, arg in enumerate(args): + if arg in self.context_args: + value = kw['args'][i] + tags.update({arg: value}) + for k, v in kw['kwargs'].iteritems(): + if k in self.context_args: + tags.update({k, v}) + return {'tags': tags} + + def set_logger_context(self, context): + logger = logging.getLogger() + for h in logger.handlers: + if isinstance(h, SentryHandler): + h.client.context.merge(context) diff --git a/tests/contrib/test_celery.py b/tests/contrib/test_celery.py index cfa5b0ff8..d6c2ff6fa 100644 --- a/tests/contrib/test_celery.py +++ b/tests/contrib/test_celery.py @@ -19,7 +19,7 @@ def setUp(self): self.celery.conf.CELERY_ALWAYS_EAGER = True self.client = InMemoryClient() - self.handler = SentryCeleryHandler(self.client, ignore_expected=True) + self.handler = SentryCeleryHandler(self.client, ignore_expected=True, context_args=['foo', 'kw_bar']) self.handler.install() self.addCleanup(self.handler.uninstall) @@ -45,6 +45,20 @@ def dummy_task(x, y): dummy_task.delay(1, 0) assert len(self.client.events) == 0 + def test_context_args(self): + @self.celery.task(name='dummy_task') + def dummy_task(foo, bar): + return foo / bar + dummy_task.delay(1, 2) + assert self.client.context + + def test_context_kwargs(self): + @self.celery.task(name='dummy_task') + def dummy_task(foo, kw_bar=2): + return foo / kw_bar + dummy_task.delay(1, kw_bar=2) + assert self.client.context + class CeleryLoggingHandlerTestCase(TestCase): def setUp(self): From 65a2c97b498e469c57e2532d62d42125de686651 Mon Sep 17 00:00:00 2001 From: ryan-s Date: Fri, 19 Jan 2018 15:03:50 -0500 Subject: [PATCH 5/5] Clean up --- raven/contrib/celery/__init__.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/raven/contrib/celery/__init__.py b/raven/contrib/celery/__init__.py index e5aaf5686..22f13c681 100644 --- a/raven/contrib/celery/__init__.py +++ b/raven/contrib/celery/__init__.py @@ -12,7 +12,7 @@ from celery.exceptions import SoftTimeLimitExceeded from celery.signals import ( - after_setup_logger, task_failure, task_prerun, task_postrun, after_setup_task_logger + after_setup_logger, task_failure, task_prerun, task_postrun ) from raven.handlers.logging import SentryHandler @@ -46,7 +46,6 @@ def process_logger_event(sender, logger, loglevel, logfile, format, if isinstance(h, SentryHandler): h.addFilter(filter_) return False - handler.client.tags_context({'woah': 'nelly'}) logger.addHandler(handler) after_setup_logger.connect(process_logger_event, weak=False) @@ -101,8 +100,8 @@ def handle_task_postrun(self, sender, task_id, task, **kw): def infer_context(self, task, **kw): args = inspect.getargspec(task.run).args - # first arg is going to be self - args.pop(0) + if task._app: + args.pop(0) tags = {} for i, arg in enumerate(args): if arg in self.context_args: