Parse operators

Parser expressions extract fields from the log line at query time and add them to the label set, where later stages can filter, group, or unwrap them. If extraction fails for a line, the line flows through unchanged and the __error__ label is set on it.

json

Parses the log line as JSON and adds every property as a label. Nested properties are flattened with underscores, and characters that are not valid in label names (such as dots) are replaced with underscores — log.level becomes log_level. Pass expressions to extract only specific fields.

Syntax

| json [<label>="<expression>", ...]
none

Parameters

Parameter Required Description

<expression>

Optional

One or more label="field" pairs that extract only the named fields. Without expressions, all JSON properties become labels.

Example

Parse Filebeat’s ECS-JSON log lines and keep only entries whose log.level property (flattened to log_level) is info.

{source="filebeat"} | json | log_level="info"
Expected output
{"log.level":"info","@timestamp":"2026-07-04T15:37:52.411Z","log.logger":"monitoring","log.origin":{"file.name ...
{"log.level":"info","@timestamp":"2026-07-04T15:34:52.411Z","log.logger":"monitoring","log.origin":{"file.name ...
{"log.level":"info","@timestamp":"2026-07-04T15:36:22.411Z","log.logger":"monitoring","log.origin":{"file.name ...
none

Lines that are not valid JSON pass through unchanged with the __error__ label set to JSONParserErr. Filter them out with | __error__="" or keep only them with | __error__!="".

Extracting all properties from large JSON objects creates many labels; prefer expressions such as | json level="log.level", msg="message" on wide events.

logfmt

Parses the log line as logfmt — the space-separated key=value format used by Grafana, Heroku, and many Go services — and adds every key as a label. Quoted values may contain spaces; keys are sanitized to valid label names.

Syntax

| logfmt [<label>="<key>", ...]
none

Parameters

Parameter Required Description

<expression>

Optional

One or more label="key" pairs that extract only the named keys. Without expressions, all keys become labels.

Example

Parse Grafana’s own logfmt output and keep only datasource requests that completed with HTTP status 200. The extracted statusCode label comes from the statusCode=200 token in each line.

{source="grafana"} |= "duration=" | logfmt | statusCode="200"
Expected output
logger=tsdb.loki endpoint=queryData pluginId=loki dsName=KfuseLogsDatasource dsUID=P10239062BE9ED4EF uname=gra ...
logger=tsdb.loki endpoint=queryData pluginId=loki dsName=KfuseLogsDatasource dsUID=P10239062BE9ED4EF uname=gra ...
logger=tsdb.loki endpoint=queryData pluginId=loki dsName=KfuseLogsDatasource dsUID=P10239062BE9ED4EF uname=gra ...
none

Malformed logfmt lines flow through with __error__ set to LogfmtParserErr.

The |= "duration=" line filter before the parser cheaply restricts parsing to the lines that carry the fields of interest.

pattern

Extracts fields by matching the line against a template made of literal text and capture placeholders: <name> captures text into a label, <_> matches and discards. The pattern parser is faster and far easier to read than an equivalent regular expression, and is the recommended parser for fixed-shape plain-text formats such as nginx access logs.

Syntax

| pattern "<pattern-expression>"
none

Parameters

Parameter Required Description

<pattern-expression>

Required

Literal text with <name> captures and <_> wildcards. Literals must match the line exactly; two captures cannot be adjacent.

Example

Parse the leading fields of each access-log entry from the delegate service — client IP, timestamp, method, path, status, and response bytes — then keep only GET requests.

{source="delegate"}
| pattern "<client_ip> - - [<ts>] \"<method> <path> <_>\" <status> <bytes> <_>"
| method="GET"
Expected output
10.16.4.33 - - [04/Jul/2026:15:48:08 +0000] "GET /api/metrics HTTP/1.1" 200 463 "-" "Datadog Agent/7.53.0" 1
10.16.4.33 - - [04/Jul/2026:15:48:23 +0000] "GET /api/metrics HTTP/1.1" 200 463 "-" "Datadog Agent/7.53.0" 0
10.16.4.33 - - [04/Jul/2026:15:48:39 +0000] "GET /api/metrics HTTP/1.1" 200 463 "-" "Datadog Agent/7.53.0" 0
none

Escape double quotes that are part of the log line as \" inside the double-quoted pattern.

The pattern must match from the start of the line; trailing content is covered by the final <_>.

regexp

Extracts fields using an RE2 regular expression with named capture groups: each (?P<name>…​) group becomes a label. Reach for regexp when the line shape is too irregular for the pattern parser — optional fields, repeated separators, or matches that anchor mid-line.

Syntax

| regexp "<re2-expression>"
none

Parameters

Parameter Required Description

<re2-expression>

Required

An RE2 regular expression containing at least one named capture group (?P<name>…​). Unnamed groups are not extracted.

Example

Extract the HTTP method, path, and status code from nginx access-log lines, then keep successful requests only.

{source="nginx"}
| regexp "\"(?P<method>[A-Z]+) (?P<path>[^ ]+) [^\"]*\" (?P<status>[0-9]+)"
| status="200"
Expected output
10.2.134.241 - - [04/Jul/2026:15:41:27 +0000] "POST /ingester/otlp/v1/logs HTTP/1.1" 200 2 "-" "OpenTelemetry  ...
10.2.140.116 - - [04/Jul/2026:15:41:27 +0000] "POST /ingester/v1/fluent_bit HTTP/1.1" 200 0 "-" "Fluent-Bit" 1 ...
10.2.140.70 - - [04/Jul/2026:15:41:27 +0000] "POST /ingester/v1/fluent_bit HTTP/1.1" 200 0 "-" "Fluent-Bit" 69 ...
none

Backslashes must be doubled inside double-quoted strings (\\d); character classes such as [0-9] avoid the escaping entirely.

RE2 does not support look-ahead or back-references.

unpack

Unpacks log lines that an agent packed with Promtail’s pack stage, which wraps the original line in a JSON envelope together with extra labels. unpack restores the embedded labels and replaces the line with the original _entry content. Lines that were not packed pass through unchanged.

Syntax

| unpack
none

Example

Apply unpack to a stream. Filebeat lines are not packed, so they flow through unmodified — demonstrating that unpack is safe to apply even when only part of the stream is packed.

{source="filebeat"} | unpack
Expected output
{"log.level":"info","@timestamp":"2026-07-04T15:41:22.410Z","log.logger":"monitoring","log.origin":{"file.name ...
{"log.level":"info","@timestamp":"2026-07-04T15:40:52.410Z","log.logger":"monitoring","log.origin":{"file.name ...
{"log.level":"info","@timestamp":"2026-07-04T15:40:22.411Z","log.logger":"monitoring","log.origin":{"file.name ...
none

unpack only restores envelopes with the _entry property produced by the pack stage; it is not a general JSON parser — use json for that.