The Logstash dissect filter parses strings into fields using literal delimiters and %{field_name} placeholders, with no regex involved. For consistent, fixed-format logs - application logs you control, well-formed access logs, structured syslog - dissect is typically 2-5x faster than equivalent grok patterns. The trade-off is rigidity: dissect cannot handle variable-width fields, optional fields, or pattern alternation. When the input shape drifts, dissect fails or misaligns fields.
Syntax
filter {
dissect {
mapping => {
"message" => "%{ts} %{+ts} %{level} %{logger}: %{msg}"
}
convert_datatype => {
"duration_ms" => "int"
}
tag_on_failure => [ "_dissectfailure" ]
}
}
Each %{field} captures up to the next literal delimiter. Special modifiers extend the basic syntax:
%{+field}appends to a previous capture (joins date/time parts).%{?skipname}captures and discards (useful as a named padding placeholder).%{&field}indirects - uses the value of an earlier capture as the destination field name.%{field->}allows runs of repeated delimiters between this field and the next.%{field/2}orders appends explicitly when using+.
Parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
mapping |
hash | yes | none | Map of source field to dissect pattern. |
convert_datatype |
hash | no | {} |
Map of field name to type (int, float). Applied after dissection. |
tag_on_failure |
array | no | ["_dissectfailure"] |
Tags added when the pattern does not match. |
add_field |
hash | no | {} |
Fields to add on success. |
add_tag |
array | no | [] |
Tags to add on success. |
Examples
Parse a structured application log line with a timestamp split across two captures:
Input: 2024-08-12 10:30:15.123 INFO com.example.Service: User login succeeded
filter {
dissect {
mapping => {
"message" => "%{ts} %{+ts} %{level} %{logger}: %{msg}"
}
}
date {
match => [ "ts", "yyyy-MM-dd HH:mm:ss.SSS" ]
}
}
Skip uninteresting padding with %{?skip} and capture numeric fields with type conversion:
filter {
dissect {
mapping => {
"message" => "%{ip} %{?ident} %{user} [%{ts}] \"%{verb} %{request} %{httpver}\" %{status} %{bytes}"
}
convert_datatype => {
"status" => "int"
"bytes" => "int"
}
}
}
Handle repeated whitespace delimiters with ->:
filter {
dissect {
mapping => {
"message" => "%{ts->} %{level} %{message}"
}
}
}
Common Issues
Dissect is order-sensitive and field-count-sensitive. If your input occasionally has an extra space, an unexpected token, or a missing field, the pattern fails and the event is tagged _dissectfailure. The classic failure mode is "works on 99% of logs, breaks silently on the long-tail formats." Always route _dissectfailure events to a debug index and inspect them weekly.
Dissect does not parse types - everything is extracted as a string. Use convert_datatype for numeric coercion, or follow dissect with a mutate filter. Type conversion happens after extraction, so convert_datatype for a missing field silently does nothing.
Multiple consecutive whitespace delimiters are not collapsed by default. "a b" (two spaces) parsed with "%{x} %{y}" produces x => "a" and y => " b". Use %{x->} %{y} to collapse runs.
Dissect can extract one event per line; it does not iterate over arrays or split. Pair with the split filter for multiline payloads.
Performance Notes
Dissect's edge over grok comes from avoiding regex. It is essentially a character-by-character delimiter scanner: O(n) on input length with very low constant factors. Benchmarks against typical application logs show 2-5x throughput improvement for equivalent extraction. The gap widens for patterns with many fields or repeated alternation in grok.
The optimal pattern is "dissect first, grok only the variable-shape field." For example, dissect can split a syslog envelope into timestamp / hostname / program / payload, and a small grok pattern then parses just the payload. This combines dissect's speed on the structured part with grok's flexibility on the irregular part.
When dissect is the bottleneck (rare), it usually means the source field is enormous - thousands of characters - and the pattern has many captures. Trim the source field first or move to a json filter if the upstream can be changed.
Monitoring Logstash dissect Pipelines with Pulse
Pulse is the only tool built specifically for monitoring and optimizing Logstash pipelines. Dissect fails silently when upstream log formats drift even slightly, and the resulting _dissectfailure tag is easy to miss until reports stop populating. Pulse tracks per-pipeline _dissectfailure rates, alerts on regressions tied to recent deploys upstream, and surfaces the sample failing lines so you can fix the pattern (or push back on the source) in the same hour the format changed.
Frequently Asked Questions
Q: How is the Logstash dissect filter different from grok?
A: Dissect uses literal delimiters and no regex; grok uses regex patterns. Dissect is 2-5x faster but cannot handle variable-width fields, optional fields, or alternation. Use dissect for application logs you control and grok for irregular formats like syslog from heterogeneous sources.
Q: Can the Logstash dissect filter convert field types?
A: Yes, via the convert_datatype parameter, which accepts int and float. For string transformations (uppercase, gsub), follow dissect with a mutate filter.
Q: How do I handle optional fields with the Logstash dissect filter?
A: Dissect does not natively support optional fields. Two options: define multiple dissect filters in conditional branches that match different formats, or fall back to grok for the variable section after dissecting the fixed parts.
Q: What is the Logstash dissect filter + modifier used for?
A: The + modifier appends to an earlier capture. %{ts} %{+ts} parses two adjacent tokens into a single ts field, joined by a space. Useful for date-time pairs that have a fixed space in between.
Q: Why does the Logstash dissect filter add _dissectfailure to my events?
A: The pattern did not match the entire source string - typically because the field count or delimiter sequence is off. Inspect a failed event's message field and verify it has the exact number of tokens and delimiters the pattern expects.
Q: When should I use Logstash dissect instead of grok?
A: Use dissect when the log format is fixed, you control the producer (or it is well-documented), and you need throughput. Use grok when the format varies, fields are optional, or you need to anchor on regex-matched substrings.
Related Reading
- Logstash Grok Filter Plugin: regex-based alternative for irregular formats.
- Logstash JSON Filter Plugin: use first when the upstream emits JSON.
- Logstash KV Filter Plugin: the right tool for
key=valuepayloads. - Logstash Mutate Filter Plugin: post-dissect type conversion and field cleanup.
- Logstash Date Filter Plugin: parse the timestamp captured by dissect.