Structured log severity
Normalize levels from common JSON logs while preserving the original body.
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.
Enable parsing
Set logs.parseApplicationLevels in the deployment's stack settings:
{
"logs": {
"parseApplicationLevels": true
}
}The setting defaults to false. It applies to newly captured application stdout/stderr records after the deployment is reconciled; existing stored logs are not reprocessed.
For an Operator installed through a custom integration, pass the same stack settings JSON through the Operator's stack-settings configuration. This is deployment configuration rather than a project-creation choice.
What Alien parses
The entire application payload, after container-runtime framing is removed, must be a JSON object. Each captured line is considered independently.
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.