Skip to content

bug: Some webapp loggers ignore APP_LOG_LEVEL setting #3617

@imajus

Description

@imajus

Provide environment information

System:
OS: Linux 6.8 Debian GNU/Linux 11 (bullseye) 11 (bullseye)
CPU: (4) x64 Intel(R) Xeon(R) Gold 6230R CPU @ 2.10GHz
Memory: 2.66 GB / 10.83 GB
Container: Yes
Shell: 5.1.4 - /bin/bash
Binaries:
Node: 20.20.0 - /usr/local/bin/node
Yarn: 1.22.22 - /usr/local/bin/yarn
npm: 10.8.2 - /usr/local/bin/npm
pnpm: 10.33.2 - /usr/local/bin/pnpm

Describe the bug

On a self-hosted @trigger.dev/webapp@4.4.6 two distinct log sources flood stdout regardless of APP_LOG_LEVEL=info.

Reproduction repo

N/A

To reproduce

Just run self-hosted instance of Trigger.dev with DEBUG=0 and APP_LOG_LEVEL=info set and see the log output flooded with useless lines:

2026-05-14T08:06:06.086Z {"operations":{},"timestamp":"2026-05-14T08:06:06.085Z","name":"UpdateMetadataService","message":"[UpdateMetadataService] Flushing operations","level":"debug"}
2026-05-14T08:06:07.087Z {"operations":{},"timestamp":"2026-05-14T08:06:07.087Z","name":"UpdateMetadataService","message":"[UpdateMetadataService] Flushing operations","level":"debug"}
2026-05-14T08:06:08.089Z {"operations":{},"timestamp":"2026-05-14T08:06:08.089Z","name":"UpdateMetadataService","message":"[UpdateMetadataService] Flushing operations","level":"debug"}
2026-05-14T08:06:09.089Z {"operations":{},"timestamp":"2026-05-14T08:06:09.089Z","name":"UpdateMetadataService","message":"[UpdateMetadataService] Flushing operations","level":"debug"}
2026-05-14T08:06:10.091Z {"operations":{},"timestamp":"2026-05-14T08:06:10.090Z","name":"UpdateMetadataService","message":"[UpdateMetadataService] Flushing operations","level":"debug"}
2026-05-14T08:06:10.091Z {"utilization":0.14515204685126162,"timestamp":"2026-05-14T08:06:10.091Z","name":"webapp","message":"nodejs.event_loop.utilization","level":"info"}
2026-05-14T08:06:10.597Z POST /engine/v1/worker-actions/dequeue 200 - - 10076.882 ms
2026-05-14T08:06:10.598Z POST /engine/v1/worker-actions/dequeue 200 - - 10030.495 ms
2026-05-14T08:06:10.599Z POST /engine/v1/worker-actions/dequeue 200 - - 10054.939 ms
2026-05-14T08:06:10.924Z POST /engine/v1/worker-actions/dequeue 200 - - 10038.383 ms
2026-05-14T08:06:11.055Z POST /engine/v1/worker-actions/dequeue 200 - - 10042.529 ms
2026-05-14T08:06:11.092Z {"operations":{},"timestamp":"2026-05-14T08:06:11.092Z","name":"UpdateMetadataService","message":"[UpdateMetadataService] Flushing operations","level":"debug"}
2026-05-14T08:06:11.257Z POST /engine/v1/worker-actions/dequeue 200 - - 10050.793 ms
2026-05-14T08:06:11.259Z POST /engine/v1/worker-actions/dequeue 200 - - 10074.525 ms
2026-05-14T08:06:11.330Z POST /engine/v1/worker-actions/dequeue 200 - - 10031.380 ms
2026-05-14T08:06:11.388Z POST /engine/v1/worker-actions/dequeue 200 - - 10040.259 ms

Additional information

Only the three loggers in apps/webapp/app/services/logger.server.ts (logger, workerLogger, socketLogger) honour APP_LOG_LEVEL; everything else bypasses it.

1. UpdateMetadataService — service-local logger pinned to debug by an env-flag default. Stdout fills with [UpdateMetadataService] Flushing operations lines at ~1 Hz, tagged "level":"debug", and the line is emitted unconditionally per tick — the operations map is usually empty. The service builds its own Logger and reads a service-specific env var defaulted to "1":

// apps/webapp/app/services/metadata/updateMetadataInstance.server.ts:15
logLevel: env.BATCH_METADATA_OPERATIONS_FLUSH_LOGGING_ENABLED === "1" ? "debug" : "info",
// apps/webapp/app/env.server.ts:662
BATCH_METADATA_OPERATIONS_FLUSH_LOGGING_ENABLED: z.string().default("1"),

Workaround needs the undocumented BATCH_METADATA_OPERATIONS_FLUSH_LOGGING_ENABLED=0 and/or TRIGGER_LOG_LEVEL=info, neither of which surfaces in the self-hosted env reference.

2. morgan("tiny") access log — no env knob at all. Express logs every HTTP request at info-equivalent level, unconditional. The /engine/v1/worker-actions/dequeue route is a ~10s long-poll called by every worker, so the log volume scales linearly with worker count (~83% of all log lines on an idle instance with a handful of workers):

// apps/webapp/server.ts:107
app.use(morgan("tiny"));

No skip function, no env guard, no integration with APP_LOG_LEVEL. There's no operator-visible way to filter healthcheck / engine / heartbeat noise short of patching the source.

Proposed fix

Make all webapp loggers consult APP_LOG_LEVEL by default — have UpdateMetadataService (and any similar service-local logger) inherit from logger.server.ts; let the existing BATCH_METADATA_* flag gate verbose payload dumps inside the log, not the threshold; skip the per-tick Flushing operations entry when there are no operations.

For morgan, wrap the middleware in an env gate (e.g. ACCESS_LOG_ENABLED, default "1") and add a skip that drops /healthcheck, /engine/v1/worker-actions/dequeue, and /engine/v1/worker-actions/heartbeat when an ACCESS_LOG_QUIET_PATHS flag is set. The underlying theme is the same in both cases: today, "silence debug noise on a self-hosted instance" requires reading the source.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions