Skip to content

LISTENARR_LOG_LEVEL=Trace silently falls back to Information instead of raising verbosity #996

Description

@m4bard

Summary

Setting LISTENARR_LOG_LEVEL=Trace does not increase log verbosity. It silently drops to Information, so it produces less detail than a valid level while looking like it took effect. "Turn on trace logging" is usually the first thing a maintainer asks a bug reporter to do, which is what makes the silent part costly.

Where it comes from

ConfigureSerilog in listenarr.api/Startup/ListenarrBuilderFactory.cs:158-176 parses both the env var and the config value with Enum.TryParse<LogEventLevel>:

var logLevelEnv = Environment.GetEnvironmentVariable("LISTENARR_LOG_LEVEL");   // line 161
...
if (!string.IsNullOrWhiteSpace(logLevelEnv) && Enum.TryParse<LogEventLevel>(logLevelEnv, ignoreCase: true, out var parsedFromEnv))  // line 165
    minimumLevel = parsedFromEnv;
else if (...config...)                                                          // line 169
    minimumLevel = parsedFromConfig;
else
    minimumLevel = LogEventLevel.Information;                                    // line 175

Serilog's LogEventLevel has no Trace member. Its levels are Verbose, Debug, Information, Warning, Error, Fatal. So Trace fails Enum.TryParse, the env branch is skipped, and (absent a valid config value) execution falls through to minimumLevel = LogEventLevel.Information. Nothing is logged to say the requested level was not understood. (Read: ListenarrBuilderFactory.cs:158-176.)

The trap is that Trace reads like a legitimate, more-verbose-than-Debug level to anyone coming from .NET's Microsoft.Extensions.Logging, where Trace is exactly that. Serilog just spells the equivalent Verbose.

Effect

Measured while working the #890 case on stock ghcr.io/listenarrs/listenarr:canary at a630572: a synthetic import run logged 124 lines with LISTENARR_LOG_LEVEL=Trace versus 205 lines at a valid Serilog level. The lines lost in the Trace run included the ones naming the cause of the import failure, so the setting most likely to be requested during triage actively removed the detail being asked for.

Suggested fix

Small and self-contained:

  1. Map Trace to Verbose before/inside the parse, since Verbose is what a user typing Trace intends.
  2. When a level string is non-empty but unrecognized, log a warning naming the value and the levels that are accepted, rather than falling silently to Information. That way the next person who mistypes a level finds out immediately.

This file is not touched by #993, so the change does not collide with that work.

I am happy to open a PR for this if useful.

Environment

Reproduced on stock ghcr.io/listenarrs/listenarr:canary at commit a630572.


Disclosure: drafted with Claude Code at my direction; I read the cited code at the stated commit and reviewed this before posting.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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