+
+
+
+
+
+ 03 · Pipeline
+ Parse logs in the OpenTelemetry Collector
+
+ The OpenTelemetry Collector is a free, open-source program that receives logs, metrics and traces, processes them and sends them on to a backend. It is the usual place to parse logs:
+
+
+ - One config parses the logs of every app on the host, so no app needs its own parsing code.
+ - It works for software you can't change, such as nginx, databases and vendor daemons.
+ - It is vendor-neutral. Switching backends means changing the exporter, not rewriting the parsers.
+ - Your logs already pass through it on the way to the backend, so parsing there adds no extra hop.
+
+
+
+
+ Most apps and servers write their logs to a file. The Collector's file log receiver, file_log in the config, watches that file and picks up each new line as it is written. A list of operators parses the line into fields, and an exporter sends the finished record to your backend.
+
+
+ {pipeline.map((p) => (
+ - {p.name}{p.detail}
+ ))}
+
+
+ The receiver ships in otelcol-contrib, the Collector build published as the Docker image otel/opentelemetry-collector-contrib. Older versions name it filelog and the exporter otlphttp; the configs here use the current names.
+
+
+
+
+ Each tab has a sample line, a complete config.yaml for that format, and the record Collector 0.164.0 printed for the line in a test run.
+
+ ({ id, label }))}>
+ {formatTabs.map((t) => (
+
+ Sample line
+ {t.line}
+ config.yaml
+
+ Parsed record
+
+
+
+ ))}
+
+
+ The exporter at the bottom of each config sends the records over OTLP, the OpenTelemetry protocol, to Maple in this example. For another backend, change endpoint and headers; the receiver and its operators stay the same. For Maple, the key is the private ingest key (maple_sk_...) from the Ingestion page in Maple's settings, and organizations in the EU region use https://ingest.eu.maple.dev.
+
+
+
+
+ Check the parsing before anything is sent. debug.yaml swaps the exporter for one that prints each record; the Collector merges every --config file it is given, so config.yaml stays unchanged:
+
+
+
+ Start the Collector with Docker from the folder that holds both files. Mount the folder your log file is in at the path the config's include names; for nginx, that is /var/log/nginx:
+
+
+
+ The receiver reads lines written after it starts, so send a request to nginx. A 502 from /api/checkout prints as:
+
+
+
+ When the records look right, start it in the background with your ingest key and without debug.yaml:
+
+
+
+
If nothing arrives
+
+ permission denied in docker logs otelcol: the container can't read the file. On Debian and Ubuntu, nginx logs belong to the adm group, group ID 4, so add --group-add 4.
+ - Older lines are missing: add
start_at: beginning under the receiver to read the whole file first.
+
+
+
+
+
+ Backends that accept OTLP store the parsed fields as log attributes. In Maple, for example:
+
+
+ -
+ 01
+
Filter and open a record
Open Logs and pick nginx under Service. Excluding INFO under Severity leaves the 4xx and 5xx responses. Open a record: its Attributes tab lists the parsed fields under Log Attributes.
+

+
+ -
+ 02
+
Pin fields as columns
Use Columns in the table toolbar to pin url.path and http.response.status_code next to the message. For charts, a dashboard's Query Builder over Logs can group by attr.url.path (Build dashboards).
+

+
+
+
+
+
Parsed logs in Maple
+
Send your parsed logs to Maple
+
The Logs docs cover search, the sidebar filters, pinned columns and moving from a log to its trace.
+
+
+
+
+
+
+
+
+
+
+
+ Sources and further reading
+
+
+