Snippets · Sources
Map your log levels to OpenTelemetry severity
Severity filters, error dashboards and alert rules read severity_number, a number from 1 to 24. This config sets it from the application's level field with the severity_parser operator; the mapping adds level names the defaults do not know (warning, err, crit, emerg).
- Signals
- Logs
- Category
- CollectionParsing
- Source
- Log files (JSON lines)
- Components
- filelogbatchmemory_limiterotlphttp
- Destination
- OTLP/HTTP endpoint
OpenTelemetry Collector
extensions:
file_storage:
directory: /var/lib/otelcol/storage
create_directory: true
receivers:
filelog:
include: [/var/log/myapp/*.json.log]
start_at: end
storage: file_storage
operators:
- type: json_parser
parse_from: body
parse_to: attributes
on_error: send
# Sets severity_number and severity_text from the level field. The
# mapping adds the values this application uses that the defaults miss.
- type: severity_parser
parse_from: attributes.level
mapping:
warn: warning
error: [err, crit]
fatal: emerg
processors:
memory_limiter:
check_interval: 1s
limit_percentage: 80
spike_limit_percentage: 25
batch:
timeout: 5s
exporters:
otlphttp:
endpoint: https://your-backend:4318
service:
extensions: [file_storage]
pipelines:
logs:
receivers: [filelog]
processors: [memory_limiter, batch]
exporters: [otlphttp]
LinkMesh
LinkMesh has no built-in template for this job. Add it as a custom source in raw mode, with filelog as the component type and this body - the same lines as under filelog in the collector config:
include: [/var/log/myapp/*.json.log]
start_at: end
storage: file_storage
operators:
- type: json_parser
parse_from: body
parse_to: attributes
on_error: send
- type: severity_parser
parse_from: attributes.level
mapping:
warn: warning
error: [err, crit]
fatal: emerg
How custom components are validated and rolled out: create a custom source.
Download config.yamlValidated with otelcol-contrib v0.161.0 on 2026-10-26
Complete config files, each checked with the collector's own validate command (otelcol-contrib v0.161.0). Replace https://your-backend:4318 with your own OTLP endpoint before you run it.
Before and after
Example telemetry in, and what this exact config sent out when we ran it in otelcol-contrib v0.161.0. CI re-runs it on every change and fails if the output differs. Changed values are highlighted.
6 log records in, 6 log records out
Before
- body
- {"level":"debug","msg":"cache miss"}
After
- body
- {"level":"debug","msg":"cache miss"}
- severity
- debug
- severity_number
- 5
- attributes.log.file.name
- input.log
- attributes.level
- debug
- attributes.msg
- cache miss
Before
- body
- {"level":"info","msg":"order accepted"}
After
- body
- {"level":"info","msg":"order accepted"}
- severity
- info
- severity_number
- 9
- attributes.log.file.name
- input.log
- attributes.level
- info
- attributes.msg
- order accepted
Before
- body
- {"level":"warning","msg":"slow provider"}
After
- body
- {"level":"warning","msg":"slow provider"}
- severity
- warning
- severity_number
- 13
- attributes.log.file.name
- input.log
- attributes.msg
- slow provider
- attributes.level
- warning
Before
- body
- {"level":"err","msg":"payment timeout"}
After
- body
- {"level":"err","msg":"payment timeout"}
- severity
- err
- severity_number
- 17
- attributes.level
- err
- attributes.log.file.name
- input.log
- attributes.msg
- payment timeout
Before
- body
- {"level":"crit","msg":"disk full"}
After
- body
- {"level":"crit","msg":"disk full"}
- severity
- crit
- severity_number
- 17
- attributes.msg
- disk full
- attributes.log.file.name
- input.log
- attributes.level
- crit
Before
- body
- {"level":"notice","msg":"config reloaded"}
After
- body
- {"level":"notice","msg":"config reloaded"}
- severity
- notice
- attributes.log.file.name
- input.log
- attributes.level
- notice
- attributes.msg
- config reloaded
The gotcha
A level the mapping does not know keeps its text and gets no number. In our test "notice" arrived with severity_text notice and no severity_number, so to a severity filter it is a record without severity - which the keep-error-logs config drops and the filter-by-severity config keeps. List every level your application writes.
Manage this across a fleet
LinkMesh manages collector configuration across a fleet from one self-hosted control plane, so a change like this is made once rather than host by host. The first 25 Collectors are free after a no-card registration in the OpenSight Customer Portal (5 without one).
Doing this in LinkMesh: Sources
Related snippets
- Parse Apache access logs into semantic conventionsTurn Apache combined-format access log lines into semantic-convention attributes, with typed status codes and sizes.
- Parse JSON log lines into attributesTurn each JSON log line into attributes you can filter and group by, keeping the original line as the body.
- Parse key=value log linesTurn logfmt-style key=value lines into attributes, quoted values with spaces included.
- Parse nginx access logs into semantic conventionsTurn nginx combined-format access log lines into OpenTelemetry semantic-convention attributes, with typed status codes.