|
1 | 1 | --- |
2 | | -description: This filter allows you to concatenate multiline or stacktrace messages |
| 2 | +description: >- |
| 3 | + Concatenate Multiline or Stack trace log messages. Available on Fluent Bit >= |
| 4 | + v1.8.2. |
3 | 5 | --- |
4 | 6 |
|
5 | 7 | # Multiline |
6 | 8 |
|
| 9 | +The Multiline Filter helps to concatenate messages that originally belong to one context but were split across multiple records or log lines. Common examples are stack traces or applications that print logs in multiple lines. |
| 10 | + |
| 11 | +As part of the built-in functionality, without major configuration effort, you can enable one of ours built-in parsers with auto detection and multi format support: |
| 12 | + |
| 13 | +* go |
| 14 | +* python |
| 15 | +* ruby |
| 16 | +* java \(Google Cloud Platform Java stacktrace format\) |
| 17 | + |
| 18 | +Some comments about this filter: |
| 19 | + |
| 20 | +* The usage of this filter depends on a previous configuration of a [Multiline Parser](../../administration/configuring-fluent-bit/multiline-parsing.md) definition. |
| 21 | +* If you aim to concatenate messages split originally by Docker or CRI container engines, we recommend doing the concatenation on [Tail plugin](https://docs.fluentbit.io/manual/pipeline/inputs/tail#multiline-support), this same functionality exists there. |
| 22 | + |
| 23 | +## Configuration Parameters |
| 24 | + |
| 25 | +The plugin supports the following configuration parameters: |
| 26 | + |
| 27 | +| Property | Description | |
| 28 | +| :--- | :--- | |
| 29 | +| multiline.parser | Specify one or multiple [Multiline Parser definitions](../../administration/configuring-fluent-bit/multiline-parsing.md) to apply to the content. You can specify multiple multiline parsers to detect different formats by separating them with a comma. | |
| 30 | +| multiline.key\_content | Key name that holds the content to process. Note that a Multiline Parser definition can already specify the `key_content` to use, but this option allows to overwrite that value for the purpose of the filter. | |
| 31 | + |
| 32 | +## Configuration Example |
| 33 | + |
| 34 | +The following example aims to parse a log file called `test.log` that contains some full lines, a custom Java stacktrace and a Go stacktrace. |
| 35 | + |
| 36 | +{% hint style="info" %} |
| 37 | +The following example files can be located at: |
| 38 | + |
| 39 | +[https://github.com/fluent/fluent-bit/tree/master/documentation/examples/multiline/filter\_multiline](https://github.com/fluent/fluent-bit/tree/master/documentation/examples/multiline/filter_multiline) |
| 40 | +{% endhint %} |
| 41 | + |
| 42 | +Example files content: |
| 43 | + |
| 44 | +{% tabs %} |
| 45 | +{% tab title="fluent-bit.conf" %} |
| 46 | +This is the primary Fluent Bit configuration file. It includes the `parsers_multiline.conf` and tails the file `test.log` by applying the multiline parsers `multiline-regex-test` and `go`. Then it sends the processing to the standard output. |
| 47 | + |
| 48 | +```text |
| 49 | +[SERVICE] |
| 50 | + flush 1 |
| 51 | + log_level info |
| 52 | + parsers_file parsers_multiline.conf |
| 53 | +
|
| 54 | +[INPUT] |
| 55 | + name tail |
| 56 | + path test.log |
| 57 | + read_from_head true |
| 58 | +
|
| 59 | +[FILTER] |
| 60 | + name multiline |
| 61 | + match * |
| 62 | + multiline.key_content log |
| 63 | + multiline.parser go, multiline-regex-test |
| 64 | +
|
| 65 | +[OUTPUT] |
| 66 | + name stdout |
| 67 | + match * |
| 68 | + |
| 69 | +``` |
| 70 | +{% endtab %} |
| 71 | + |
| 72 | +{% tab title="parsers\_multiline.conf" %} |
| 73 | +This second file defines a multiline parser for the example. Note that a second multiline parser called `go` is used in **fluent-bit.conf**, but this one is a built-in parser. |
| 74 | + |
| 75 | +```text |
| 76 | +[MULTILINE_PARSER] |
| 77 | + name multiline-regex-test |
| 78 | + type regex |
| 79 | + flush_timeout 1000 |
| 80 | + # |
| 81 | + # Regex rules for multiline parsing |
| 82 | + # --------------------------------- |
| 83 | + # |
| 84 | + # configuration hints: |
| 85 | + # |
| 86 | + # - first state always has the name: start_state |
| 87 | + # - every field in the rule must be inside double quotes |
| 88 | + # |
| 89 | + # rules | state name | regex pattern | next state |
| 90 | + # ------|---------------|-------------------------------------------- |
| 91 | + rule "start_state" "/(Dec \d+ \d+\:\d+\:\d+)(.*)/" "cont" |
| 92 | + rule "cont" "/^\s+at.*/" "cont" |
| 93 | + |
| 94 | +``` |
| 95 | +{% endtab %} |
| 96 | + |
| 97 | +{% tab title="test.log" %} |
| 98 | +An example file with multiline and multiformat content: |
| 99 | + |
| 100 | +```text |
| 101 | +single line... |
| 102 | +Dec 14 06:41:08 Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting! |
| 103 | + at com.myproject.module.MyProject.badMethod(MyProject.java:22) |
| 104 | + at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18) |
| 105 | + at com.myproject.module.MyProject.anotherMethod(MyProject.java:14) |
| 106 | + at com.myproject.module.MyProject.someMethod(MyProject.java:10) |
| 107 | + at com.myproject.module.MyProject.main(MyProject.java:6) |
| 108 | +another line... |
| 109 | +panic: my panic |
| 110 | +
|
| 111 | +goroutine 4 [running]: |
| 112 | +panic(0x45cb40, 0x47ad70) |
| 113 | + /usr/local/go/src/runtime/panic.go:542 +0x46c fp=0xc42003f7b8 sp=0xc42003f710 pc=0x422f7c |
| 114 | +main.main.func1(0xc420024120) |
| 115 | + foo.go:6 +0x39 fp=0xc42003f7d8 sp=0xc42003f7b8 pc=0x451339 |
| 116 | +runtime.goexit() |
| 117 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x44b4d1 |
| 118 | +created by main.main |
| 119 | + foo.go:5 +0x58 |
| 120 | +
|
| 121 | +goroutine 1 [chan receive]: |
| 122 | +runtime.gopark(0x4739b8, 0xc420024178, 0x46fcd7, 0xc, 0xc420028e17, 0x3) |
| 123 | + /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc420053e30 sp=0xc420053e00 pc=0x42503c |
| 124 | +runtime.goparkunlock(0xc420024178, 0x46fcd7, 0xc, 0x1000f010040c217, 0x3) |
| 125 | + /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc420053e70 sp=0xc420053e30 pc=0x42512e |
| 126 | +runtime.chanrecv(0xc420024120, 0x0, 0xc420053f01, 0x4512d8) |
| 127 | + /usr/local/go/src/runtime/chan.go:506 +0x304 fp=0xc420053f20 sp=0xc420053e70 pc=0x4046b4 |
| 128 | +runtime.chanrecv1(0xc420024120, 0x0) |
| 129 | + /usr/local/go/src/runtime/chan.go:388 +0x2b fp=0xc420053f50 sp=0xc420053f20 pc=0x40439b |
| 130 | +main.main() |
| 131 | + foo.go:9 +0x6f fp=0xc420053f80 sp=0xc420053f50 pc=0x4512ef |
| 132 | +runtime.main() |
| 133 | + /usr/local/go/src/runtime/proc.go:185 +0x20d fp=0xc420053fe0 sp=0xc420053f80 pc=0x424bad |
| 134 | +runtime.goexit() |
| 135 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420053fe8 sp=0xc420053fe0 pc=0x44b4d1 |
| 136 | +
|
| 137 | +goroutine 2 [force gc (idle)]: |
| 138 | +runtime.gopark(0x4739b8, 0x4ad720, 0x47001e, 0xf, 0x14, 0x1) |
| 139 | + /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003e768 sp=0xc42003e738 pc=0x42503c |
| 140 | +runtime.goparkunlock(0x4ad720, 0x47001e, 0xf, 0xc420000114, 0x1) |
| 141 | + /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003e7a8 sp=0xc42003e768 pc=0x42512e |
| 142 | +runtime.forcegchelper() |
| 143 | + /usr/local/go/src/runtime/proc.go:238 +0xcc fp=0xc42003e7e0 sp=0xc42003e7a8 pc=0x424e5c |
| 144 | +runtime.goexit() |
| 145 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x44b4d1 |
| 146 | +created by runtime.init.4 |
| 147 | + /usr/local/go/src/runtime/proc.go:227 +0x35 |
| 148 | +
|
| 149 | +goroutine 3 [GC sweep wait]: |
| 150 | +runtime.gopark(0x4739b8, 0x4ad7e0, 0x46fdd2, 0xd, 0x419914, 0x1) |
| 151 | + /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003ef60 sp=0xc42003ef30 pc=0x42503c |
| 152 | +runtime.goparkunlock(0x4ad7e0, 0x46fdd2, 0xd, 0x14, 0x1) |
| 153 | + /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003efa0 sp=0xc42003ef60 pc=0x42512e |
| 154 | +runtime.bgsweep(0xc42001e150) |
| 155 | + /usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc42003efd8 sp=0xc42003efa0 pc=0x419973 |
| 156 | +runtime.goexit() |
| 157 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003efe0 sp=0xc42003efd8 pc=0x44b4d1 |
| 158 | +created by runtime.gcenable |
| 159 | + /usr/local/go/src/runtime/mgc.go:216 +0x58 |
| 160 | +one more line, no multiline |
| 161 | +
|
| 162 | +``` |
| 163 | +{% endtab %} |
| 164 | +{% endtabs %} |
| 165 | + |
| 166 | +By running Fluent Bit with the given configuration file you will obtain: |
| 167 | + |
| 168 | +```text |
| 169 | +$ fluent-bit -c fluent-bit.conf |
| 170 | +
|
| 171 | +[0] tail.0: [1626736433.143567481, {"log"=>"single line..."}] |
| 172 | +[1] tail.0: [1626736433.143570538, {"log"=>"Dec 14 06:41:08 Exception in thread "main" java.lang.RuntimeException: Something has gone wrong, aborting! |
| 173 | + at com.myproject.module.MyProject.badMethod(MyProject.java:22) |
| 174 | + at com.myproject.module.MyProject.oneMoreMethod(MyProject.java:18) |
| 175 | + at com.myproject.module.MyProject.anotherMethod(MyProject.java:14) |
| 176 | + at com.myproject.module.MyProject.someMethod(MyProject.java:10) |
| 177 | + at com.myproject.module.MyProject.main(MyProject.java:6)"}] |
| 178 | +[2] tail.0: [1626736433.143572538, {"log"=>"another line..."}] |
| 179 | +[3] tail.0: [1626736433.143572894, {"log"=>"panic: my panic |
| 180 | +
|
| 181 | +goroutine 4 [running]: |
| 182 | +panic(0x45cb40, 0x47ad70) |
| 183 | + /usr/local/go/src/runtime/panic.go:542 +0x46c fp=0xc42003f7b8 sp=0xc42003f710 pc=0x422f7c |
| 184 | +main.main.func1(0xc420024120) |
| 185 | + foo.go:6 +0x39 fp=0xc42003f7d8 sp=0xc42003f7b8 pc=0x451339 |
| 186 | +runtime.goexit() |
| 187 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003f7e0 sp=0xc42003f7d8 pc=0x44b4d1 |
| 188 | +created by main.main |
| 189 | + foo.go:5 +0x58 |
| 190 | +
|
| 191 | +goroutine 1 [chan receive]: |
| 192 | +runtime.gopark(0x4739b8, 0xc420024178, 0x46fcd7, 0xc, 0xc420028e17, 0x3) |
| 193 | + /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc420053e30 sp=0xc420053e00 pc=0x42503c |
| 194 | +runtime.goparkunlock(0xc420024178, 0x46fcd7, 0xc, 0x1000f010040c217, 0x3) |
| 195 | + /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc420053e70 sp=0xc420053e30 pc=0x42512e |
| 196 | +runtime.chanrecv(0xc420024120, 0x0, 0xc420053f01, 0x4512d8) |
| 197 | + /usr/local/go/src/runtime/chan.go:506 +0x304 fp=0xc420053f20 sp=0xc420053e70 pc=0x4046b4 |
| 198 | +runtime.chanrecv1(0xc420024120, 0x0) |
| 199 | + /usr/local/go/src/runtime/chan.go:388 +0x2b fp=0xc420053f50 sp=0xc420053f20 pc=0x40439b |
| 200 | +main.main() |
| 201 | + foo.go:9 +0x6f fp=0xc420053f80 sp=0xc420053f50 pc=0x4512ef |
| 202 | +runtime.main() |
| 203 | + /usr/local/go/src/runtime/proc.go:185 +0x20d fp=0xc420053fe0 sp=0xc420053f80 pc=0x424bad |
| 204 | +runtime.goexit() |
| 205 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc420053fe8 sp=0xc420053fe0 pc=0x44b4d1 |
| 206 | +
|
| 207 | +goroutine 2 [force gc (idle)]: |
| 208 | +runtime.gopark(0x4739b8, 0x4ad720, 0x47001e, 0xf, 0x14, 0x1) |
| 209 | + /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003e768 sp=0xc42003e738 pc=0x42503c |
| 210 | +runtime.goparkunlock(0x4ad720, 0x47001e, 0xf, 0xc420000114, 0x1) |
| 211 | + /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003e7a8 sp=0xc42003e768 pc=0x42512e |
| 212 | +runtime.forcegchelper() |
| 213 | + /usr/local/go/src/runtime/proc.go:238 +0xcc fp=0xc42003e7e0 sp=0xc42003e7a8 pc=0x424e5c |
| 214 | +runtime.goexit() |
| 215 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003e7e8 sp=0xc42003e7e0 pc=0x44b4d1 |
| 216 | +created by runtime.init.4 |
| 217 | + /usr/local/go/src/runtime/proc.go:227 +0x35 |
| 218 | +
|
| 219 | +goroutine 3 [GC sweep wait]: |
| 220 | +runtime.gopark(0x4739b8, 0x4ad7e0, 0x46fdd2, 0xd, 0x419914, 0x1) |
| 221 | + /usr/local/go/src/runtime/proc.go:280 +0x12c fp=0xc42003ef60 sp=0xc42003ef30 pc=0x42503c |
| 222 | +runtime.goparkunlock(0x4ad7e0, 0x46fdd2, 0xd, 0x14, 0x1) |
| 223 | + /usr/local/go/src/runtime/proc.go:286 +0x5e fp=0xc42003efa0 sp=0xc42003ef60 pc=0x42512e |
| 224 | +runtime.bgsweep(0xc42001e150) |
| 225 | + /usr/local/go/src/runtime/mgcsweep.go:52 +0xa3 fp=0xc42003efd8 sp=0xc42003efa0 pc=0x419973 |
| 226 | +runtime.goexit() |
| 227 | + /usr/local/go/src/runtime/asm_amd64.s:2337 +0x1 fp=0xc42003efe0 sp=0xc42003efd8 pc=0x44b4d1 |
| 228 | +created by runtime.gcenable |
| 229 | + /usr/local/go/src/runtime/mgc.go:216 +0x58"}] |
| 230 | +[4] tail.0: [1626736433.143585473, {"log"=>"one more line, no multiline"}] |
| 231 | +
|
| 232 | +``` |
| 233 | + |
| 234 | +The lines that did not match a pattern are not considered as part of the multiline message, while the ones that matched the rules were concatenated properly. |
| 235 | + |
0 commit comments