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_textlevelname,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:
| Result | Accepted values |
|---|---|
| TRACE | trace |
| DEBUG | debug, verbose, silly |
| INFO | info, information, informational, notice, http, success |
| WARN | warn, warning |
| ERROR | error, err, exception |
| FATAL | fatal, 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:
| Values | Result |
|---|---|
| 1–4 | TRACE |
| 5–8 | DEBUG |
| 9–12 | INFO |
| 13–16 | WARN |
| 17–20 | ERROR |
| 21–24 | FATAL |
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, numericpid, and a numeric or stringtime. - Bunyan: string
msg,v: 0, and stringnameandhostnamefields.
{"level":30,"time":1573664685466,"pid":78742,"hostname":"api","msg":"ready"}{"levelname":"ERROR","levelno":40,"message":"request failed"}{"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
messageormsg. - 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.