Skip to content

Disable a log destination after repeated consecutive emit failures - #21

Merged
anth-volk merged 3 commits into
mainfrom
fix/gcl-destination-circuit-breaker
Jul 3, 2026
Merged

Disable a log destination after repeated consecutive emit failures#21
anth-volk merged 3 commits into
mainfrom
fix/gcl-destination-circuit-breaker

Conversation

@anth-volk

Copy link
Copy Markdown
Contributor

What

Adds a per-destination circuit breaker to LogDestinationManager.emit: after DESTINATION_FAILURE_LIMIT (3) consecutive emit failures, the destination is disabled for the rest of the process, with a logging.destination_disabled internal record. A successful emit resets the counter. If the last destination is disabled, a stdout destination is restored so logs keep flowing.

Why

Emission is synchronous on the caller's request path. In the PolicyEngine/policyengine-uk-chat#142 outage, a WIF attribute-mapping error (google.subject > 127 bytes) made the Google Cloud Logging destination's credential exchange fail after ~25 seconds of internal google-auth/gRPC retries — per log write, on every request, forever, taking the service down. Creation-time failures already fall back to stdout; this closes the same hole for emit-time failures. An observability sink must never be able to degrade its host service.

The breaker deliberately trips on consecutive failures only, so a transient GCL blip doesn't permanently disable the destination; a tripped destination returns naturally with the next container.

Not included (follow-up candidate)

The materialized WIF token file is written once at credential creation and never refreshed. Modal identity tokens live 48h (measured), so this only affects containers outliving that window — with this breaker the failure mode degrades to lost logs plus internal records rather than an outage. Worth a follow-up (re-materialize on refresh or a subject-token supplier).

Verification

Full suite: 126 passed (3 new circuit-breaker tests: disable-after-consecutive-failures with a healthy destination unaffected, success-resets-counter, sole-destination-falls-back-to-stdout).

🤖 Generated with Claude Code

anth-volk and others added 2 commits July 4, 2026 01:23
Emission is synchronous on the caller's request path, and a destination
whose credential exchange fails after long internal retries previously
charged that cost to every request forever (policyengine-uk-chat#142
outage: a WIF attribute-mapping error turned every log write into ~25s
of failing STS retries). After DESTINATION_FAILURE_LIMIT consecutive
failures a destination is now disabled for the process, with an
internal record emitted; if no destination remains, stdout is restored
so logs keep flowing. Success resets the counter.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@anth-volk
anth-volk marked this pull request as ready for review July 3, 2026 23:34
@anth-volk
anth-volk merged commit 9e3b086 into main Jul 3, 2026
3 checks passed
@anth-volk
anth-volk deleted the fix/gcl-destination-circuit-breaker branch July 3, 2026 23:34
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.

1 participant