diff --git a/src/pretix/celery_app.py b/src/pretix/celery_app.py
index f140aefc71..d971e1f9f7 100644
--- a/src/pretix/celery_app.py
+++ b/src/pretix/celery_app.py
@@ -19,14 +19,55 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# .
#
+import logging
import os
-from celery import Celery
+from celery import Celery, signals
+from django.dispatch import receiver
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pretix.settings")
+logger = logging.getLogger(__name__)
from django.conf import settings
app = Celery('pretix')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
+
+
+@receiver(signals.before_task_publish)
+def on_before_task_publish(sender, body, exchange, routing_key, headers, properties, declare, retry_policy, **kwargs):
+ from pretix.helpers.logs import local
+
+ trace = getattr(local, 'trace', [])
+ request_id = getattr(local, 'request_id', None)
+ if request_id:
+ trace.append(request_id)
+
+ headers["X-Pretix-Trace"] = " ".join(trace)
+
+
+@receiver(signals.task_received)
+def on_task_received(sender, request, **kwargs):
+ trace = request._request_dict.get("X-Pretix-Trace")
+ if trace:
+ logger.info(f"Task {request.id} has trace {trace}")
+
+
+@receiver(signals.task_prerun)
+def on_task_prerun(sender, task_id, task, **kwargs):
+ from pretix.helpers.logs import local
+
+ if "X-Pretix-Trace" in task.request.headers:
+ local.trace = task.request.headers["X-Pretix-Trace"].split(" ")
+ else:
+ local.trace = []
+ local.trace.append(task_id)
+
+
+@receiver(signals.task_postrun)
+def on_task_postrun(sender, task_id, task, **kwargs):
+ from pretix.helpers.logs import local
+
+ local.request_id = None
+ local.trace = []
diff --git a/src/pretix/helpers/logs.py b/src/pretix/helpers/logs.py
index 82f098f5f6..82bbad4b70 100644
--- a/src/pretix/helpers/logs.py
+++ b/src/pretix/helpers/logs.py
@@ -20,6 +20,7 @@
# .
#
import logging
+import uuid
from django.core.signals import request_finished
from django.dispatch import receiver
@@ -65,7 +66,9 @@ class RequestIdMiddleware:
import sentry_sdk
sentry_sdk.set_tag("request_id", request.request_id)
else:
- local.request_id = request.request_id = None
+ # Web server did not pass a request ID, we still generate one to correlate between django logs and
+ # celery logs
+ local.request_id = request.request_id = str(uuid.uuid4())
return self.get_response(request)