Skip to content

Commit 52549d3

Browse files
feat(sync-service): cap logger handler OLP mailboxes (#4456)
## What Cap the overload-protection (OLP) mailboxes of the three logger handlers used by `sync-service` so that error/log bursts shed messages instead of blocking `Logger` callers or letting processes' mailboxes grow unbounded. Three sites, all inside `packages/sync-service/`: 1. **Default console handler** (`config/runtime.exs`) — `sync_mode_qlen: 2000, drop_mode_qlen: 2000, flush_qlen: 5000`. Matches the stratovolt `cloud-sync-service` precedent. 2. **`OtelMetricExporter.LogHandler`** (`config/runtime.exs`) — extends the existing `:config` map with `drop_mode_qlen: 2000, flush_qlen: 5000`. `sync_mode_qlen` is intentionally **not** set: the handler module forces `sync_mode_qlen == drop_mode_qlen`, so it would be a no-op. This handler had no caps anywhere before. 3. **Sentry handler** (`lib/electric/application.ex`) — passes `discard_threshold: 2000, sync_threshold: nil` to `Electric.Telemetry.Sentry.add_logger_handler/2` (the function already accepts opts; only the call site changed). Matches the stratovolt precedent. ## Why During the 2026-05-21 pod-replacement spikes, `logger_olp` mailboxes peaked at ~76K/~59K. Capping these mailboxes protects the leading edge of redeployment-shock overload. `overload_kill_enable` is deliberately **not** set on either OLP handler: for the console handler it would terminate the handler and lose all subsequent logs until restart; for `OtelMetricExporter.LogHandler` it would tear down the entire `LogHandlerSupervisor`, creating a restart-amplification loop.
1 parent fcf9749 commit 52549d3

3 files changed

Lines changed: 30 additions & 1 deletion

File tree

.changeset/logger-handler-caps.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@core/sync-service': patch
3+
---
4+
5+
Cap the overload-protection (OLP) mailboxes of the default console, OpenTelemetry, and Sentry logger handlers so error/log bursts shed messages instead of blocking Logger callers or growing unbounded.
6+
7+
This is **leading-edge protection only**: it shields against the early phase of a redeployment/error burst but is **not sufficient under deep scheduler starvation** — the real fix for that is upstream (request-proxy admission control and snapshot-pool sizing).
8+
9+
Note: `sync_mode_qlen` is intentionally not set on the OpenTelemetry log handler — its module forces `sync_mode_qlen == drop_mode_qlen`, so the option would be a no-op there.

packages/sync-service/config/runtime.exs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ config :logger, :default_formatter,
2424
metadata: [:pid, :shape_handle, :request_id],
2525
colors: [enabled: env!("ELECTRIC_LOG_COLORS", :boolean!, true)]
2626

27+
# The default logger_std_h handler writes application logs to stdout. Cap its
28+
# OLP mailbox so error bursts shed stdout logs instead of blocking Logger
29+
# callers (sync mode) or letting the queue grow unbounded.
30+
config :logger, :default_handler,
31+
config: %{sync_mode_qlen: 2000, drop_mode_qlen: 2000, flush_qlen: 5000}
32+
2733
# Enable this to get **very noisy** but useful messages from BEAM about
2834
# processes being started, stopped and crashes.
2935
# https://www.erlang.org/doc/apps/sasl/error_logging#sasl-reports
@@ -374,6 +380,12 @@ if Electric.telemetry_enabled?() do
374380
%{
375381
config: %{
376382
resource: %{name: "logs"},
383+
# Cap the OLP mailbox so log bursts shed events instead of letting
384+
# the queue grow unbounded. `sync_mode_qlen` is intentionally omitted:
385+
# OtelMetricExporter.LogHandler forces `sync_mode_qlen == drop_mode_qlen`,
386+
# so setting it is a no-op.
387+
drop_mode_qlen: 2000,
388+
flush_qlen: 5000,
377389
metadata_map: %{
378390
request_id: "http.request_id",
379391
stack_id: "source_id",

packages/sync-service/lib/electric/application.ex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,15 @@ defmodule Electric.Application do
4343
Logger.add_handlers(:electric)
4444

4545
if Code.ensure_loaded?(Electric.Telemetry.Sentry) do
46-
Electric.Telemetry.Sentry.add_logger_handler()
46+
# Cap the Sentry transport sender backlog to shed load instead of letting
47+
# queued Sentry events grow unbounded during error bursts. `sync_threshold:
48+
# nil` disables the default sync-mode switch (which would block the logging
49+
# process) so we rely solely on discard.
50+
Electric.Telemetry.Sentry.add_logger_handler(
51+
Electric.Telemetry.Sentry.default_handler_id(),
52+
discard_threshold: 2000,
53+
sync_threshold: nil
54+
)
4755
end
4856

4957
config = configuration()

0 commit comments

Comments
 (0)