Docs

Structured log severity

Alien can normalize severity from common structured application logs captured from container stdout and stderr. This makes level filters work for applications that emit JSON without requiring every framework to produce OpenTelemetry logs directly.

Parsing is intentionally limited to well-known severity conventions. Alien does not run user-defined Grok patterns, regular expressions, remappers, or per-service pipelines.

No configuration is required. Alien applies this normalization automatically when it captures application stdout and stderr. System logs and logs sent directly over OTLP are not parsed.

What Alien parses

The entire application payload, after surrounding whitespace and container-runtime framing are removed, must be a JSON object. Each captured line is considered independently. Non-JSON lines take a fast path and retain the existing stdout/stderr fallback.

String levels are recognized in these locations:

  • level, severity, severityText, severity_text
  • levelname, level_name, logLevel, log_level
  • ECS log.level, as either a literal key or a nested field
  • Loguru record.level.name

Values are trimmed and matched case-insensitively:

ResultAccepted values
TRACEtrace
DEBUGdebug, verbose, silly
INFOinfo, information, informational, notice, http, success
WARNwarn, warning
ERRORerror, err, exception
FATALfatal, critical, crit, alert, emergency, emerg, panic, dpanic

This covers JSON output from common Winston, structlog, Go slog, zap, zerolog, logrus, Rust tracing-subscriber, ECS-compatible, and Caddy configurations when they use one of these fields.

OpenTelemetry severity numbers

Numeric severityNumber and severity_number follow the OpenTelemetry ranges:

ValuesResult
1–4TRACE
5–8DEBUG
9–12INFO
13–16WARN
17–20ERROR
21–24FATAL

Values outside 1–24 are ignored.

Python logging numbers

Numeric levelno and level_number recognize Python's common levels: 5 TRACE, 10 DEBUG, 20 INFO, 30 WARN, 40 ERROR, and 50 FATAL. Custom numeric levels are ignored.

Pino and Bunyan

Pino and Bunyan use a numeric level: 10 TRACE, 20 DEBUG, 30 INFO, 40 WARN, 50 ERROR, and 60 FATAL.

Because a bare numeric level is ambiguous, Alien accepts it only when the record also has a recognizable logger signature:

  • Pino: string msg, numeric pid, and a numeric or string time.
  • Bunyan: string msg, v: 0, and string name and hostname fields.
Pino
{"level":30,"time":1573664685466,"pid":78742,"hostname":"api","msg":"ready"}
Python JSON formatter
{"levelname":"ERROR","levelno":40,"message":"request failed"}
Rust tracing JSON
{"timestamp":"2026-08-21T12:00:00Z","level":"WARN","fields":{"message":"retrying"},"target":"service"}

Conflicts and fallback

Alien inspects every recognized severity location in the object:

  • If all recognized candidates agree, that level is used.
  • If recognized candidates disagree, none wins by precedence. Alien uses the existing stdout/stderr fallback.
  • An unknown value does not override a separate recognized value.
  • If no supported value is present, existing capture behavior is unchanged.

For example, {"level":"warn","severity":"warning"} is WARN, while {"level":"error","severity":"info"} falls back.

Alien does not infer severity from message, msg, exception objects, HTTP status codes, or fields such as status and statusCode. A numeric level without a Pino or Bunyan signature is also ignored.

Body, timestamps, and attributes

Severity parsing changes only severity metadata:

  • The application JSON remains the log body. Alien does not replace it with message or msg.
  • JSON properties are not promoted into indexed log attributes.
  • The container capture timestamp remains the event timestamp; embedded JSON timestamps are not substituted.
  • Multiline output and stack traces are handled one captured line at a time.
  • Parsing does not add exposure for fields inside the JSON body; apply the same sensitive-data rules you already use for application logs.

Logs sent directly over OTLP bypass this parser because their telemetry producer is responsible for setting native OpenTelemetry severity fields.

Unsupported text output

Common default text output from Node console, Next.js, Hono's logger, Morgan, Python's standard formatter, Uvicorn/FastAPI, Flask/Werkzeug, Rust env_logger, Nginx, and Apache is not structurally parsed. Configure a JSON formatter or emit native OpenTelemetry logs when reliable level filtering is required.

On this page