Skip to content

Fix duplicate Celery logs via after_setup_logger - #347

Merged
cahillsf merged 4 commits into
masterfrom
stephen.cahill/CLOUDR-2097-fix-duplicate-logging
Jul 24, 2026
Merged

Fix duplicate Celery logs via after_setup_logger#347
cahillsf merged 4 commits into
masterfrom
stephen.cahill/CLOUDR-2097-fix-duplicate-logging

Conversation

@cahillsf

@cahillsf cahillsf commented Jul 22, 2026

Copy link
Copy Markdown

What

Stops Celery task logs from being written twice. make_celery clears app.logger's own handlers once Celery sets up its root logger, leaving only the clean copy Celery's hijacked root handler emits.

Fixes https://datadoghq.atlassian.net/browse/CLOUDR-2132.

Why

Celery's worker log setup hijacks the root logger. Since app.logger propagates by default, every current_app.logger call inside a task was emitted twice: once through Lemur's bare, unformatted stream_handler (which Datadog's agent mangled into mislabeled, multiline-duplicated entries), and once cleanly through Celery's hijacked root handler.

Pulled actual pre-fix log lines from staging Datadog to confirm which copy to keep — Lemur's own handler was the messy one; Celery's was clean and correctly leveled.

Approach

make_celery connects an after_setup_logger receiver that clears app.logger's handlers, leaving the propagated/Celery-formatted copy as the sole output. This signal only fires during real worker/beat startup, not when the web process lazily imports lemur.common.celery to submit a task — so web logging is untouched.

Changes

  • lemur/common/celery.py — clear app.logger handlers via after_setup_logger.
  • lemur/tests/test_factory.py, lemur/tests/test_dcv_celery.py — updated/new coverage.
  • local/supervisor.conf — local Celery worker to reproduce this in dev.

Testing

  • Compared pre-fix log lines from staging Datadog (kube_namespace:cert-orchestration source:celery-worker).
  • make test-python passes.

cahillsf and others added 2 commits July 22, 2026 15:28
Celery's worker log setup hijacks the root logger and attaches its own
plain-text handler. Since Flask's app.logger propagates to root, every
current_app.logger call (e.g. report_revoked_task) was emitted twice —
once through Lemur's structured JSON handler, once through Celery's
plain-text root handler that Datadog can't parse a level out of.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Celery's worker log setup hijacks the root logger. Because app.logger
propagates by default, every current_app.logger call inside a task was
emitted twice - once through Lemur's own handler and once through
Celery's root handler.

Set app.logger.propagate = False in configure_logging instead of
disabling Celery's root-logger hijack (worker_hijack_root_logger). This
is more targeted: it stops Lemur's records from being re-emitted through
root while leaving Celery's own task logging untouched.

Also add a Celery worker to the local supervisor config so the behaviour
can be reproduced in local dev.

CLOUDR-2097

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cahillsf cahillsf changed the title Disable Celery root logger hijack to stop duplicate revoked-task logs Fix duplicate Celery logs via app.logger.propagate = False Jul 23, 2026
@cahillsf

cahillsf commented Jul 23, 2026

Copy link
Copy Markdown
Author

deployed in staging at DEBUG log level, can see here with latest master image we get ~2x the logs from the celery-worker

before:

  • 2 Datadog logs (app root [has a separate problem where it's also duplicating within itself] + celery log)

after:

app.logger.propagate = False kept Lemur's own unformatted StreamHandler
output (which Datadog's agent was mangling into mislabeled, duplicated
multiline entries) and dropped the clean copy that flows through
Celery's root-hijacked handler.

Instead, drop app.logger's own handlers once Celery actually sets up
its root logger (via the after_setup_logger signal), so only the
clean, propagated copy remains. This only fires during real
worker/beat startup - not when the web process lazily imports this
module to submit a task.

CLOUDR-2097

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cahillsf cahillsf changed the title Fix duplicate Celery logs via app.logger.propagate = False Fix duplicate Celery logs via after_setup_logger Jul 23, 2026
Comment thread local/supervisor.conf

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

local dev only

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@cahillsf
cahillsf marked this pull request as ready for review July 24, 2026 13:08
@cahillsf
cahillsf requested review from a team as code owners July 24, 2026 13:08
@cahillsf
cahillsf merged commit c673198 into master Jul 24, 2026
9 checks passed
@cahillsf
cahillsf deleted the stephen.cahill/CLOUDR-2097-fix-duplicate-logging branch July 24, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants