Features Pricing Docs Blog

Log levels, mapped across languages

Syslog counts down from 7, Python counts up in tens, Log4j counts down in hundreds and Go starts below zero. Look up any level name or number, or read the whole table, and see where it lands on the one scale OpenTelemetry uses for all of them.

Syslog (RFC 5424)

Level Value OpenTelemetry
debug 7 DEBUG · 5
informational 6 INFO · 9
notice 5 INFO2 · 10
warning 4 WARN · 13
error 3 ERROR · 17
critical 2 ERROR2 · 18
alert 1 ERROR3 · 19
emergency 0 FATAL · 21

PHP — PSR-3 / Monolog

Level Value OpenTelemetry
debug 100 DEBUG · 5
info 200 INFO · 9
notice 250 INFO2 · 10
warning 300 WARN · 13
error 400 ERROR · 17
critical 500 ERROR2 · 18
alert 550 ERROR3 · 19
emergency 600 FATAL · 21

Python — logging

Level Value OpenTelemetry
DEBUG 10 DEBUG · 5
INFO 20 INFO · 9
WARNING 30 WARN · 13
ERROR 40 ERROR · 17
CRITICAL 50 ERROR2 · 18

Java — Log4j 2

Level Value OpenTelemetry
TRACE 600 TRACE · 1
DEBUG 500 DEBUG · 5
INFO 400 INFO · 9
WARN 300 WARN · 13
ERROR 200 ERROR · 17
FATAL 100 FATAL · 21

Go — log/slog

Level Value OpenTelemetry
DEBUG -4 DEBUG · 5
INFO 0 INFO · 9
WARN 4 WARN · 13
ERROR 8 ERROR · 17

Node.js — pino

Level Value OpenTelemetry
trace 10 TRACE · 1
debug 20 DEBUG · 5
info 30 INFO · 9
warn 40 WARN · 13
error 50 ERROR · 17
fatal 60 FATAL · 21

.NET — Microsoft.Extensions.Logging

Level Value OpenTelemetry
Trace 0 TRACE · 1
Debug 1 DEBUG · 5
Information 2 INFO · 9
Warning 3 WARN · 13
Error 4 ERROR · 17
Critical 5 ERROR2 · 18

Ruby — Logger

Level Value OpenTelemetry
DEBUG 0 DEBUG · 5
INFO 1 INFO · 9
WARN 2 WARN · 13
ERROR 3 ERROR · 17
FATAL 4 FATAL · 21

The OpenTelemetry severity scale

OpenTelemetry gives every log record a SeverityNumber from 1 to 24, in six ranges of four, and an optional SeverityText holding whatever the source called the level. Within a range, a higher number is more severe — ERROR2 (18) is worse than ERROR (17). Zero means unspecified.

RangeNumbersMeaning
TRACE1–4Step-by-step detail, usually off in production.
DEBUG5–8Diagnostics a developer reads while chasing a bug.
INFO9–12Normal events worth a record: a request served, a job done.
WARN13–16Something unexpected that the system recovered from.
ERROR17–20An operation failed; someone may need to look.
FATAL21–24The process or service cannot continue.

Why the native numbers disagree

Each system picked its own direction and spacing. Syslog (RFC 5424) numbers from 0, Emergency, down to 7, Debug, because lower meant more urgent on the wire. Log4j kept that direction in hundreds. Python and pino count up in tens, PSR-3 implementations such as Monolog count up in hundreds with half-steps for Notice and Alert, and Go's slog puts Info at 0 so that Debug is negative. None of those numbers can be compared directly, which is exactly the problem a shared scale solves.

How the right-hand column is decided

When a record arrives with only a level name, the name is matched case-insensitively against a list of aliases — warning and warn are both 13, critical is 18, alert 19, emergency and fatal 21. The column above is computed by that same function in Bilis's ingest path, so it is what Bilis stores. An SDK that sends SeverityNumber itself always wins: if your exporter maps Python's CRITICAL to FATAL, that is what you will see.

Choosing a level

Log at ERROR when something failed and the failure is not handled further up; WARN when it was handled but should not keep happening; INFO for the events you would want in a timeline of an incident; DEBUG for what you need only while fixing one. Most alerting and most noise both come from getting the first two wrong.