fluent-plugin-concat 2.4.0 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.yml +67 -0
- data/.github/ISSUE_TEMPLATE/config.yml +5 -0
- data/.github/ISSUE_TEMPLATE/feature_request.yml +35 -0
- data/.github/workflows/add-to-project.yml +17 -0
- data/.github/workflows/linux.yml +33 -0
- data/.github/workflows/windows.yml +27 -0
- data/NEWS.md +12 -0
- data/README.md +98 -67
- data/fluent-plugin-concat.gemspec +2 -1
- data/lib/fluent/plugin/filter_concat.rb +150 -24
- metadata +23 -8
- data/.github/ISSUE_TEMPLATE.md +0 -19
- data/.travis.yml +0 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31897cab290a08b88945f1a78571bc4bfac24affae42aa2fb79eee0c6a5df937
|
4
|
+
data.tar.gz: 689b42a5ec25b1400d51af0c4f59961023e4fd01dd9b56c2d87b6ff83a2c3ddd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 501acf92258e36fbb603c27bd4a861fff446304b33b3ccb425fb2fa281bc4b6ab05c357cc051196b17da66fd57c4de4e2e7d55999b194adfc3ce4dac9694b130
|
7
|
+
data.tar.gz: 369632414f573689ca37ea34c2f17b88a74476dab41ea7edfe9d8ee394d42b20fed5d27bef7306489729b7eb9ee96f8a1429adaca88bf1b0066d7ccbcc25b22a
|
@@ -0,0 +1,67 @@
|
|
1
|
+
name: Bug Report
|
2
|
+
description: Create a report with a procedure for reproducing the bug
|
3
|
+
labels: "waiting-for-triage"
|
4
|
+
body:
|
5
|
+
- type: textarea
|
6
|
+
id: description
|
7
|
+
attributes:
|
8
|
+
label: Describe the bug
|
9
|
+
description: A clear and concise description of what the bug is
|
10
|
+
validations:
|
11
|
+
required: true
|
12
|
+
- type: textarea
|
13
|
+
id: reproduce
|
14
|
+
attributes:
|
15
|
+
label: To Reproduce
|
16
|
+
description: Steps to reproduce the behavior
|
17
|
+
validations:
|
18
|
+
required: true
|
19
|
+
- type: textarea
|
20
|
+
id: expected
|
21
|
+
attributes:
|
22
|
+
label: Expected behavior
|
23
|
+
description: A clear and concise description of what you expected to happen
|
24
|
+
validations:
|
25
|
+
required: true
|
26
|
+
- type: textarea
|
27
|
+
id: environment
|
28
|
+
attributes:
|
29
|
+
label: Your Environment
|
30
|
+
description: |
|
31
|
+
- Fluentd or its package version: `fluentd --version` (Fluentd, fluent-package) or `td-agent --version` (td-agent)
|
32
|
+
- Operating system: `cat /etc/os-release`
|
33
|
+
- Kernel version: `uname -r`
|
34
|
+
|
35
|
+
Tip: If you hit the problem with older fluent-plugin-concat version, try latest version first.
|
36
|
+
value: |
|
37
|
+
- Fluentd version:
|
38
|
+
- Package version:
|
39
|
+
- Operating system:
|
40
|
+
- Kernel version:
|
41
|
+
render: markdown
|
42
|
+
validations:
|
43
|
+
required: true
|
44
|
+
- type: textarea
|
45
|
+
id: configuration
|
46
|
+
attributes:
|
47
|
+
label: Your Configuration
|
48
|
+
description: |
|
49
|
+
Write your configuration here. Minimum reproducible fluentd.conf is recommended.
|
50
|
+
render: apache
|
51
|
+
validations:
|
52
|
+
required: true
|
53
|
+
- type: textarea
|
54
|
+
id: logs
|
55
|
+
attributes:
|
56
|
+
label: Your Error Log
|
57
|
+
description: Write your ALL error log here
|
58
|
+
render: shell
|
59
|
+
validations:
|
60
|
+
required: true
|
61
|
+
- type: textarea
|
62
|
+
id: addtional-context
|
63
|
+
attributes:
|
64
|
+
label: Additional context
|
65
|
+
description: Add any other context about the problem here.
|
66
|
+
validations:
|
67
|
+
required: false
|
@@ -0,0 +1,35 @@
|
|
1
|
+
name: Feature request
|
2
|
+
description: Suggest an idea for this project
|
3
|
+
labels: ["waiting-for-triage", "enhancement"]
|
4
|
+
body:
|
5
|
+
- type: textarea
|
6
|
+
id: description
|
7
|
+
attributes:
|
8
|
+
label: Is your feature request related to a problem? Please describe.
|
9
|
+
description: |
|
10
|
+
A clear and concise description of what the problem is.
|
11
|
+
Ex. I'm always frustrated when [...]
|
12
|
+
validations:
|
13
|
+
required: true
|
14
|
+
- type: textarea
|
15
|
+
id: solution
|
16
|
+
attributes:
|
17
|
+
label: Describe the solution you'd like
|
18
|
+
description: A clear and concise description of what you want to happen.
|
19
|
+
validations:
|
20
|
+
required: true
|
21
|
+
- type: textarea
|
22
|
+
id: alternative
|
23
|
+
attributes:
|
24
|
+
label: Describe alternatives you've considered
|
25
|
+
description: A clear and concise description of any alternative solutions or features you've considered.
|
26
|
+
validations:
|
27
|
+
required: true
|
28
|
+
- type: textarea
|
29
|
+
id: addtional-context
|
30
|
+
attributes:
|
31
|
+
label: Additional context
|
32
|
+
description: Add any other context or screenshots about the feature request here.
|
33
|
+
validations:
|
34
|
+
required: false
|
35
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
name: Add bugs to fluent project
|
2
|
+
|
3
|
+
on:
|
4
|
+
issues:
|
5
|
+
types:
|
6
|
+
- opened
|
7
|
+
|
8
|
+
jobs:
|
9
|
+
add-to-project:
|
10
|
+
name: Add issue to project
|
11
|
+
runs-on: ubuntu-latest
|
12
|
+
steps:
|
13
|
+
- uses: actions/add-to-project@v1.0.2
|
14
|
+
with:
|
15
|
+
project-url: https://github.com/orgs/fluent/projects/4
|
16
|
+
github-token: ${{ secrets.ADD_TO_PROJECT_PAT }}
|
17
|
+
labeled: waiting-for-triage
|
@@ -0,0 +1,33 @@
|
|
1
|
+
name: Testing on Ubuntu
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
- pull_request
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ${{ matrix.os }}
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby:
|
12
|
+
- 2.7
|
13
|
+
- '3.0'
|
14
|
+
- 3.1
|
15
|
+
- 3.2
|
16
|
+
- 3.3
|
17
|
+
- 3.4
|
18
|
+
os:
|
19
|
+
- ubuntu-latest
|
20
|
+
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
21
|
+
steps:
|
22
|
+
- uses: actions/checkout@v4
|
23
|
+
- uses: ruby/setup-ruby@v1
|
24
|
+
with:
|
25
|
+
ruby-version: ${{ matrix.ruby }}
|
26
|
+
rubygems: latest
|
27
|
+
- name: unit testing
|
28
|
+
env:
|
29
|
+
CI: true
|
30
|
+
run: |
|
31
|
+
gem install bundler rake
|
32
|
+
bundle install --jobs 4 --retry 3
|
33
|
+
bundle exec rake test
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Testing on Windows
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
- pull_request
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ${{ matrix.os }}
|
8
|
+
strategy:
|
9
|
+
fail-fast: false
|
10
|
+
matrix:
|
11
|
+
ruby: [ '2.7', '3.0', '3.1', '3.2', '3.3', '3.4' ]
|
12
|
+
os:
|
13
|
+
- windows-latest
|
14
|
+
name: Ruby ${{ matrix.ruby }} unit testing on ${{ matrix.os }}
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v4
|
17
|
+
- uses: ruby/setup-ruby@v1
|
18
|
+
with:
|
19
|
+
ruby-version: ${{ matrix.ruby }}
|
20
|
+
rubygems: latest
|
21
|
+
- name: unit testing
|
22
|
+
env:
|
23
|
+
CI: true
|
24
|
+
run: |
|
25
|
+
gem install bundler rake
|
26
|
+
bundle install --jobs 4 --retry 3
|
27
|
+
bundle exec rake test
|
data/NEWS.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
+
## next
|
4
|
+
|
5
|
+
### Improvements
|
6
|
+
|
7
|
+
* adds `partial_metadata_format` to support Docker 20.10 journald log driver improvements [moby/moby#41407](https://github.com/moby/moby/pull/41407)
|
8
|
+
|
9
|
+
## v2.6.0
|
10
|
+
|
11
|
+
### Improvements
|
12
|
+
|
13
|
+
* Support `buffer_limit_size`, `buffer_overflow_method` to change behavior when buffer overflow. See #68
|
14
|
+
|
3
15
|
## v2.3.0
|
4
16
|
|
5
17
|
### Improvements
|
data/README.md
CHANGED
@@ -27,75 +27,79 @@ Or install it yourself as:
|
|
27
27
|
|
28
28
|
$ gem install fluent-plugin-concat
|
29
29
|
|
30
|
-
##
|
31
|
-
|
32
|
-
**key** (string) (required)
|
33
|
-
|
34
|
-
The key for part of multiline log.
|
35
|
-
|
36
|
-
**separator** (string) (optional)
|
37
|
-
|
38
|
-
The separator of lines.
|
39
|
-
Default value is `"\n"`.
|
40
|
-
|
41
|
-
**n\_lines** (integer) (optional)
|
42
|
-
|
43
|
-
The number of lines.
|
44
|
-
This is exclusive with `multiline_start_regex`.
|
45
|
-
|
46
|
-
**multiline\_start\_regexp** (string) (optional)
|
47
|
-
|
48
|
-
The regexp to match beginning of multiline.
|
49
|
-
This is exclusive with `n_lines.`
|
50
|
-
|
51
|
-
**multiline\_end\_regexp** (string) (optional)
|
52
|
-
|
53
|
-
The regexp to match ending of multiline.
|
54
|
-
This is exclusive with `n_lines.`
|
55
|
-
|
56
|
-
**continuous\_line\_regexp** (string) (optional)
|
57
|
-
|
58
|
-
The regexp to match continuous lines.
|
59
|
-
This is exclusive with `n_lines.`
|
60
|
-
|
61
|
-
**stream\_identity\_key** (string) (optional)
|
30
|
+
## Plugin helpers
|
62
31
|
|
63
|
-
|
32
|
+
* [timer](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-timer)
|
33
|
+
* [event_emitter](https://docs.fluentd.org/v1.0/articles/api-plugin-helper-event_emitter)
|
64
34
|
|
65
|
-
|
35
|
+
* See also: [Filter Plugin Overview](https://docs.fluentd.org/filter#overview)
|
66
36
|
|
67
|
-
|
68
|
-
If specified 0, wait for next line forever.
|
69
|
-
|
70
|
-
**timeout\_label** (string) (optional)
|
71
|
-
|
72
|
-
The label name to handle events caused by timeout.
|
73
|
-
|
74
|
-
**use\_first\_timestamp** (bool) (optional)
|
75
|
-
|
76
|
-
Use timestamp of first record when buffer is flushed.
|
77
|
-
Default value is `false`.
|
78
|
-
|
79
|
-
**partial\_key** (string) (optional)
|
80
|
-
|
81
|
-
The field name that is the reference to concatenate records
|
82
|
-
|
83
|
-
**partial\_value** (string) (optional)
|
84
|
-
|
85
|
-
The value stored in the field specified by partial_key that represent partial log
|
86
|
-
|
87
|
-
**keep\_partial\_key** (bool) (optional)
|
88
|
-
|
89
|
-
If true, keep partial_key in concatenated records
|
90
|
-
Default value is `false`.
|
91
|
-
|
92
|
-
**use\_partial\_metadata** (bool) (optional)
|
37
|
+
## Configuration
|
93
38
|
|
94
|
-
|
39
|
+
### Example
|
95
40
|
|
96
|
-
|
41
|
+
```
|
42
|
+
<filter docker.log>
|
43
|
+
@type concat
|
44
|
+
key loga
|
45
|
+
#separator "\n"
|
46
|
+
n_lines 10
|
47
|
+
#multiline_start_regexp /^Start/
|
48
|
+
#multiline_end_regexp /^End/
|
49
|
+
#continuous_line_regexp nil
|
50
|
+
#stream_identity_key nil
|
51
|
+
#flush_interval 60
|
52
|
+
#timeout_label nil
|
53
|
+
#use_first_timestamp false
|
54
|
+
#partial_key nil
|
55
|
+
#partial_value nil
|
56
|
+
#keep_partial_key false
|
57
|
+
#use_partial_metadata false
|
58
|
+
#keep_partial_metadata false
|
59
|
+
#partial\_metadata\_format docker-fluentd
|
60
|
+
#use\_partial\_cri\_logtag false
|
61
|
+
#partial\_cri\_logtag\_key nil
|
62
|
+
#partial\_cri\_stream\_key stream
|
63
|
+
</filter>
|
64
|
+
```
|
97
65
|
|
98
|
-
|
66
|
+
### Parameter
|
67
|
+
|
68
|
+
|parameter|description|default|
|
69
|
+
|---|---|---|
|
70
|
+
|key|The key for part of multiline log||
|
71
|
+
|separator|The separator of lines|`"\n"`|
|
72
|
+
|n\_lines|The number of lines. This is exclusive with `multiline_start_regex`|nil|
|
73
|
+
|multiline\_start\_regexp|The regexp to match beginning of multiline. This is exclusive with `n_lines`|nil|
|
74
|
+
|multiline\_end\_regexp|The regexp to match ending of multiline.This is exclusive with `n_lines`|nil|
|
75
|
+
|continuous\_line\_regexp|The regexp to match continuous lines.This is exclusive with `n_lines`|nil|
|
76
|
+
|stream\_identity\_key|The key to determine which stream an event belongs to|nil|
|
77
|
+
|flush\_interval|The number of seconds after which the last received event log will be flushed.If specified 0, wait for next line forever|60|
|
78
|
+
|timeout\_label|The label name to handle events caused by timeout|nil|
|
79
|
+
|use\_first\_timestamp|Use timestamp of first record when buffer is flushed|`false`|
|
80
|
+
|partial\_key|The field name that is the reference to concatenate records|nil|
|
81
|
+
|partial\_value|The value stored in the field specified by partial_key that represent partial log|nil|
|
82
|
+
|keep\_partial\_key|If true, keep partial_key in concatenated records|`false`|
|
83
|
+
|use\_partial\_metadata|Use partial metadata to concatenate multiple records|`false`|
|
84
|
+
|keep\_partial\_metadata|If true, keep partial metadata|`false`|
|
85
|
+
|partial\_metadata\_format|Input format of the partial metadata (fluentd or journald docker log driver) ( `docker-fluentd`, `docker-journald`, `docker-journald-lowercase`)<br>Configure based on the input plugin, that is used. <br>The docker fluentd and journald log drivers are behaving differently, so the plugin needs to know, what to look for.<br>Use `docker-journald-lowercase`, if you have `fields_lowercase true` in the `journald` source config |`docker-fluentd`|
|
86
|
+
|use\_partial\_cri\_logtag|bool (optional)|Use cri log tag to concatenate multiple records||
|
87
|
+
|partial\_cri\_logtag\_key|string (optional)|The key name that is referred to concatenate records on cri log||
|
88
|
+
|partial\_cri\_stream\_key|string (optional)|The key name that is referred to detect stream name on cri log|`stream`|
|
89
|
+
|buffer\_limit\_size|The max size of each buffer|`512000`|
|
90
|
+
|
91
|
+
|parameter|description|available values|default|
|
92
|
+
|---|---|---|---|
|
93
|
+
|buffer\_overflow\_method|The method if overflow buffer|`ignore`, `truncate`, `drop`, `new`|`ignore`|
|
94
|
+
|
95
|
+
* `ignore`
|
96
|
+
* Concatenate the current record in the buffer
|
97
|
+
* `truncate`
|
98
|
+
* Drop the current record and flush the buffer
|
99
|
+
* `drop`
|
100
|
+
* Drop the current record and clear the buffer
|
101
|
+
* `new`
|
102
|
+
* Flush the buffer and store the current record in next buffer
|
99
103
|
|
100
104
|
## Usage
|
101
105
|
|
@@ -168,13 +172,38 @@ Handle Docker logs splitted in several parts (using `partial_message`), and do n
|
|
168
172
|
```aconf
|
169
173
|
<filter>
|
170
174
|
@type concat
|
171
|
-
key
|
175
|
+
key log
|
172
176
|
partial_key partial_message
|
173
177
|
partial_value true
|
174
178
|
separator ""
|
175
179
|
</filter>
|
176
180
|
```
|
177
181
|
|
182
|
+
(Docker v19.03+) Handle Docker logs splitted in several parts (using `use_partial_metadata`), and do not add new line between parts.
|
183
|
+
|
184
|
+
```aconf
|
185
|
+
<filter>
|
186
|
+
@type concat
|
187
|
+
key log
|
188
|
+
use_partial_metadata true
|
189
|
+
separator ""
|
190
|
+
</filter>
|
191
|
+
```
|
192
|
+
|
193
|
+
(Docker v20.10+) Handle Docker logs splitted in several parts (using `use_partial_metadata`), and do not add new line between parts.
|
194
|
+
|
195
|
+
Docker v20.10 improved partial message handling by adding better metadata in the journald log driver, this works now similarily to the fluentd log driver, but requires one additional setting
|
196
|
+
|
197
|
+
```aconf
|
198
|
+
<filter>
|
199
|
+
@type concat
|
200
|
+
key log
|
201
|
+
use_partial_metadata true
|
202
|
+
partial_metadata_format docker-journald
|
203
|
+
separator ""
|
204
|
+
</filter>
|
205
|
+
```
|
206
|
+
|
178
207
|
Handle Docker logs splitted in several parts (using newline detection), and do not add new line between parts (prior to Docker 18.06).
|
179
208
|
|
180
209
|
```aconf
|
@@ -194,7 +223,8 @@ Handle containerd/cri in Kubernetes.
|
|
194
223
|
path /var/log/containers/*.log
|
195
224
|
<parse>
|
196
225
|
@type regexp
|
197
|
-
expression /^(?<
|
226
|
+
expression /^(?<time>[^ ]+) (?<stream>stdout|stderr) (?<logtag>[^ ]*) (?<message>.*)$/
|
227
|
+
time_format %Y-%m-%dT%H:%M:%S.%L%z
|
198
228
|
</parse>
|
199
229
|
tag k8s
|
200
230
|
@label @CONCAT
|
@@ -204,8 +234,9 @@ Handle containerd/cri in Kubernetes.
|
|
204
234
|
<filter k8s>
|
205
235
|
@type concat
|
206
236
|
key message
|
207
|
-
|
208
|
-
|
237
|
+
use_partial_cri_logtag true
|
238
|
+
partial_cri_logtag_key logtag
|
239
|
+
partial_cri_stream_key stream
|
209
240
|
</filter>
|
210
241
|
<match k8s>
|
211
242
|
@type relabel
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "fluent-plugin-concat"
|
7
|
-
spec.version = "2.
|
7
|
+
spec.version = "2.6.0"
|
8
8
|
spec.authors = ["Kenji Okimoto"]
|
9
9
|
spec.email = ["okimoto@clear-code.com"]
|
10
10
|
|
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
|
|
22
22
|
spec.add_development_dependency "test-unit", ">= 3.1.0"
|
23
23
|
spec.add_development_dependency "test-unit-rr"
|
24
24
|
spec.add_development_dependency "appraisal"
|
25
|
+
spec.add_development_dependency "webrick"
|
25
26
|
end
|
@@ -22,7 +22,7 @@ module Fluent::Plugin
|
|
22
22
|
config_param :stream_identity_key, :string, default: nil
|
23
23
|
desc "The interval between data flushes, 0 means disable timeout"
|
24
24
|
config_param :flush_interval, :time, default: 60
|
25
|
-
desc "The label name to handle timeout"
|
25
|
+
desc "The label name to handle events caused by timeout"
|
26
26
|
config_param :timeout_label, :string, default: nil
|
27
27
|
desc "Use timestamp of first record when buffer is flushed"
|
28
28
|
config_param :use_first_timestamp, :bool, default: false
|
@@ -34,8 +34,20 @@ module Fluent::Plugin
|
|
34
34
|
config_param :keep_partial_key, :bool, default: false
|
35
35
|
desc "Use partial metadata to concatenate multiple records"
|
36
36
|
config_param :use_partial_metadata, :bool, default: false
|
37
|
+
desc "Input format of the partial metadata (fluentd or journald docker log driver)"
|
38
|
+
config_param :partial_metadata_format, :enum, list: [:"docker-fluentd", :"docker-journald", :"docker-journald-lowercase"], default: :"docker-fluentd"
|
37
39
|
desc "If true, keep partial metadata"
|
38
40
|
config_param :keep_partial_metadata, :bool, default: false
|
41
|
+
desc "Use cri log tag to concatenate multiple records"
|
42
|
+
config_param :use_partial_cri_logtag, :bool, default: false
|
43
|
+
desc "The key name that is referred to concatenate records on cri log"
|
44
|
+
config_param :partial_cri_logtag_key, :string, default: nil
|
45
|
+
desc "The key name that is referred to detect stream name on cri log"
|
46
|
+
config_param :partial_cri_stream_key, :string, default: "stream"
|
47
|
+
desc "The max size of each buffer"
|
48
|
+
config_param :buffer_limit_size, :size, default: 500 * 1024 # 500k
|
49
|
+
desc "The method if overflow buffer"
|
50
|
+
config_param :buffer_overflow_method, :enum, list: [:ignore, :truncate, :drop, :new], default: :ignore
|
39
51
|
|
40
52
|
class TimeoutError < StandardError
|
41
53
|
end
|
@@ -44,17 +56,25 @@ module Fluent::Plugin
|
|
44
56
|
super
|
45
57
|
|
46
58
|
@buffer = Hash.new {|h, k| h[k] = [] }
|
59
|
+
@buffer_size = Hash.new(0)
|
47
60
|
@timeout_map_mutex = Thread::Mutex.new
|
48
61
|
@timeout_map_mutex.synchronize do
|
49
62
|
@timeout_map = Hash.new {|h, k| h[k] = Fluent::Engine.now }
|
50
63
|
end
|
51
64
|
end
|
52
65
|
|
66
|
+
def required_params
|
67
|
+
params = [@n_lines.nil?, @multiline_start_regexp.nil?, @multiline_end_regexp.nil?, @partial_key.nil?, !@use_partial_metadata, !@use_partial_cri_logtag]
|
68
|
+
names = ["n_lines", "multiline_start_regexp", "multiline_end_regexp", "partial_key", "use_partial_metadata", "use_partial_cri_logtag"]
|
69
|
+
return params, names
|
70
|
+
end
|
71
|
+
|
53
72
|
def configure(conf)
|
54
73
|
super
|
55
74
|
|
56
|
-
|
57
|
-
|
75
|
+
params, names = required_params
|
76
|
+
if params.all?
|
77
|
+
raise Fluent::ConfigError, "Either #{[names[0..-2].join(", "), names[-1]].join(" or ")} is required"
|
58
78
|
end
|
59
79
|
if @n_lines && (@multiline_start_regexp || @multiline_end_regexp)
|
60
80
|
raise Fluent::ConfigError, "n_lines and multiline_start_regexp/multiline_end_regexp are exclusive"
|
@@ -69,13 +89,22 @@ module Fluent::Plugin
|
|
69
89
|
raise Fluent::ConfigError, "partial_value is required when partial_key is specified"
|
70
90
|
end
|
71
91
|
if @use_partial_metadata && @n_lines
|
72
|
-
raise Fluent::ConfigError, "
|
92
|
+
raise Fluent::ConfigError, "use_partial_metadata and n_lines are exclusive"
|
73
93
|
end
|
74
94
|
if @use_partial_metadata && (@multiline_start_regexp || @multiline_end_regexp)
|
75
|
-
raise Fluent::ConfigError, "
|
95
|
+
raise Fluent::ConfigError, "use_partial_metadata and multiline_start_regexp/multiline_end_regexp are exclusive"
|
76
96
|
end
|
77
97
|
if @use_partial_metadata && @partial_key
|
78
|
-
raise Fluent::ConfigError, "
|
98
|
+
raise Fluent::ConfigError, "use_partial_metadata and partial_key are exclusive"
|
99
|
+
end
|
100
|
+
if @use_partial_cri_logtag && @n_lines
|
101
|
+
raise Fluent::ConfigError, "use_partial_cri_logtag and n_lines are exclusive"
|
102
|
+
end
|
103
|
+
if @use_partial_cri_logtag && (@multiline_start_regexp || @multiline_end_regexp)
|
104
|
+
raise Fluent::ConfigError, "use_partial_cri_logtag and multiline_start_regexp/multiline_end_regexp are exclusive"
|
105
|
+
end
|
106
|
+
if @use_partial_cri_logtag && @partial_key
|
107
|
+
raise Fluent::ConfigError, "use_partial_cri_logtag and partial_key are exclusive"
|
79
108
|
end
|
80
109
|
|
81
110
|
@mode = nil
|
@@ -86,6 +115,33 @@ module Fluent::Plugin
|
|
86
115
|
@mode = :partial
|
87
116
|
when @use_partial_metadata
|
88
117
|
@mode = :partial_metadata
|
118
|
+
case @partial_metadata_format
|
119
|
+
when :"docker-fluentd"
|
120
|
+
@partial_message_field = "partial_message".freeze
|
121
|
+
@partial_id_field = "partial_id".freeze
|
122
|
+
@partial_ordinal_field = "partial_ordinal".freeze
|
123
|
+
@partial_last_field = "partial_last".freeze
|
124
|
+
@partial_message_indicator = @partial_message_field
|
125
|
+
when :"docker-journald"
|
126
|
+
@partial_message_field = "CONTAINER_PARTIAL_MESSAGE".freeze
|
127
|
+
@partial_id_field = "CONTAINER_PARTIAL_ID".freeze
|
128
|
+
@partial_ordinal_field = "CONTAINER_PARTIAL_ORDINAL".freeze
|
129
|
+
@partial_last_field = "CONTAINER_PARTIAL_LAST".freeze
|
130
|
+
# the journald log driver does not add CONTAINER_PARTIAL_MESSAGE to the last message
|
131
|
+
# so we help ourself by using another indicator
|
132
|
+
@partial_message_indicator = @partial_id_field
|
133
|
+
when :"docker-journald-lowercase"
|
134
|
+
@partial_message_field = "container_partial_message".freeze
|
135
|
+
@partial_id_field = "container_partial_id".freeze
|
136
|
+
@partial_ordinal_field = "container_partial_ordinal".freeze
|
137
|
+
@partial_last_field = "container_partial_last".freeze
|
138
|
+
@partial_message_indicator = @partial_id_field
|
139
|
+
end
|
140
|
+
when @use_partial_cri_logtag
|
141
|
+
@mode = :partial_cri
|
142
|
+
@partial_logtag_delimiter = ":".freeze
|
143
|
+
@partial_logtag_continue = "P".freeze
|
144
|
+
@partial_logtag_full = "F".freeze
|
89
145
|
when @multiline_start_regexp || @multiline_end_regexp
|
90
146
|
@mode = :regexp
|
91
147
|
if @multiline_start_regexp
|
@@ -113,12 +169,12 @@ module Fluent::Plugin
|
|
113
169
|
end
|
114
170
|
|
115
171
|
def filter_stream(tag, es)
|
172
|
+
if /\Afluent\.(?:trace|debug|info|warn|error|fatal)\z/ =~ tag
|
173
|
+
return es
|
174
|
+
end
|
175
|
+
|
116
176
|
new_es = Fluent::MultiEventStream.new
|
117
177
|
es.each do |time, record|
|
118
|
-
if /\Afluent\.(?:trace|debug|info|warn|error|fatal)\z/ =~ tag
|
119
|
-
new_es.add(time, record)
|
120
|
-
next
|
121
|
-
end
|
122
178
|
unless record.key?(@key)
|
123
179
|
new_es.add(time, record)
|
124
180
|
next
|
@@ -130,7 +186,7 @@ module Fluent::Plugin
|
|
130
186
|
end
|
131
187
|
end
|
132
188
|
if @mode == :partial_metadata
|
133
|
-
unless record.key?(
|
189
|
+
unless record.key?(@partial_message_indicator)
|
134
190
|
new_es.add(time, record)
|
135
191
|
next
|
136
192
|
end
|
@@ -146,11 +202,14 @@ module Fluent::Plugin
|
|
146
202
|
merged_record.delete(@partial_key) unless @keep_partial_key
|
147
203
|
when :partial_metadata
|
148
204
|
unless @keep_partial_metadata
|
149
|
-
merged_record.delete(
|
150
|
-
merged_record.delete(
|
151
|
-
merged_record.delete(
|
152
|
-
merged_record.delete(
|
205
|
+
merged_record.delete(@partial_message_field)
|
206
|
+
merged_record.delete(@partial_id_field)
|
207
|
+
merged_record.delete(@partial_ordinal_field)
|
208
|
+
merged_record.delete(@partial_last_field)
|
153
209
|
end
|
210
|
+
when :partial_cri
|
211
|
+
merged_record.delete(@partial_cri_logtag_key) unless @keep_partial_key
|
212
|
+
merged_record.delete(@partial_cri_stream_key)
|
154
213
|
end
|
155
214
|
new_es.add(time, merged_record)
|
156
215
|
end
|
@@ -175,9 +234,9 @@ module Fluent::Plugin
|
|
175
234
|
def process(tag, time, record)
|
176
235
|
if @mode == :partial_metadata
|
177
236
|
if @stream_identity_key
|
178
|
-
stream_identity = %Q(#{tag}:#{record[@stream_identity_key]}#{record[
|
237
|
+
stream_identity = %Q(#{tag}:#{record[@stream_identity_key]}#{record[@partial_id_field]})
|
179
238
|
else
|
180
|
-
stream_identity = %Q(#{tag}:#{record[
|
239
|
+
stream_identity = %Q(#{tag}:#{record[@partial_id_field]})
|
181
240
|
end
|
182
241
|
else
|
183
242
|
if @stream_identity_key
|
@@ -196,6 +255,8 @@ module Fluent::Plugin
|
|
196
255
|
process_partial(stream_identity, tag, time, record)
|
197
256
|
when :partial_metadata
|
198
257
|
process_partial_metadata(stream_identity, tag, time, record)
|
258
|
+
when :partial_cri
|
259
|
+
process_partial_cri(stream_identity, tag, time, record)
|
199
260
|
when :regexp
|
200
261
|
process_regexp(stream_identity, tag, time, record)
|
201
262
|
end
|
@@ -214,20 +275,58 @@ module Fluent::Plugin
|
|
214
275
|
|
215
276
|
def process_partial(stream_identity, tag, time, record)
|
216
277
|
new_es = Fluent::MultiEventStream.new
|
217
|
-
|
218
|
-
|
278
|
+
force_flush = false
|
279
|
+
if overflow?(stream_identity, record)
|
280
|
+
force_flush = case @buffer_overflow_method
|
281
|
+
when :ignore
|
282
|
+
@buffer[stream_identity] << [tag, time, record]
|
283
|
+
false
|
284
|
+
when :truncate
|
285
|
+
true
|
286
|
+
when :drop
|
287
|
+
@buffer[stream_identity] = []
|
288
|
+
false
|
289
|
+
when :new
|
290
|
+
true
|
291
|
+
end
|
292
|
+
else
|
293
|
+
@buffer[stream_identity] << [tag, time, record]
|
294
|
+
end
|
295
|
+
if force_flush || @partial_value != record[@partial_key]
|
219
296
|
new_time, new_record = flush_buffer(stream_identity)
|
220
297
|
time = new_time if @use_first_timestamp
|
221
298
|
new_record.delete(@partial_key)
|
222
299
|
new_es.add(time, new_record)
|
223
300
|
end
|
301
|
+
if force_flush && @buffer_overflow_method == :new
|
302
|
+
@buffer[stream_identity] << [tag, time, record]
|
303
|
+
@buffer_size[stream_identity] = record.keys.sum(&:bytesize) + record.values.sum(&:bytesize)
|
304
|
+
if @partial_value != record[@partial_key]
|
305
|
+
new_time, new_record = flush_buffer(stream_identity)
|
306
|
+
time = new_time if @use_first_timestamp
|
307
|
+
new_record.delete(@partial_key)
|
308
|
+
new_es.add(time, new_record)
|
309
|
+
end
|
310
|
+
end
|
311
|
+
new_es
|
312
|
+
end
|
313
|
+
|
314
|
+
def process_partial_cri(stream_identity, tag, time, record)
|
315
|
+
new_es = Fluent::MultiEventStream.new
|
316
|
+
@buffer[stream_identity] << [tag, time, record]
|
317
|
+
if record[@partial_cri_logtag_key].split(@partial_logtag_delimiter)[0] == @partial_logtag_full
|
318
|
+
new_time, new_record = flush_buffer(stream_identity)
|
319
|
+
time = new_time if @use_first_timestamp
|
320
|
+
new_record.delete(@partial_cri_logtag_key)
|
321
|
+
new_es.add(time, new_record)
|
322
|
+
end
|
224
323
|
new_es
|
225
324
|
end
|
226
325
|
|
227
326
|
def process_partial_metadata(stream_identity, tag, time, record)
|
228
327
|
new_es = Fluent::MultiEventStream.new
|
229
328
|
@buffer[stream_identity] << [tag, time, record]
|
230
|
-
if record[
|
329
|
+
if record[@partial_last_field] == "true"
|
231
330
|
new_time, new_record = flush_buffer(stream_identity)
|
232
331
|
time = new_time if @use_first_timestamp
|
233
332
|
new_record.delete(@partial_key)
|
@@ -288,25 +387,36 @@ module Fluent::Plugin
|
|
288
387
|
end
|
289
388
|
|
290
389
|
def firstline?(text)
|
291
|
-
@multiline_start_regexp &&
|
390
|
+
@multiline_start_regexp && @multiline_start_regexp.match?(text)
|
292
391
|
end
|
293
392
|
|
294
393
|
def lastline?(text)
|
295
|
-
@multiline_end_regexp &&
|
394
|
+
@multiline_end_regexp && @multiline_end_regexp.match?(text)
|
296
395
|
end
|
297
396
|
|
298
397
|
def continuous_line?(text)
|
299
398
|
if @continuous_line_regexp
|
300
|
-
|
399
|
+
@continuous_line_regexp.match?(text)
|
301
400
|
else
|
302
401
|
true
|
303
402
|
end
|
304
403
|
end
|
305
404
|
|
405
|
+
def overflow?(stream_identity, record)
|
406
|
+
size = record.keys.sum(&:bytesize) + record.values.sum(&:bytesize)
|
407
|
+
if @buffer_size[stream_identity] + size > @buffer_limit_size
|
408
|
+
@buffer_size[stream_identity] = 0
|
409
|
+
true
|
410
|
+
else
|
411
|
+
@buffer_size[stream_identity] += size
|
412
|
+
false
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
306
416
|
def flush_buffer(stream_identity, new_element = nil)
|
307
417
|
lines = if @mode == :partial_metadata
|
308
418
|
@buffer[stream_identity]
|
309
|
-
.sort_by {|_tag, _time, record| record[
|
419
|
+
.sort_by {|_tag, _time, record| record[@partial_ordinal_field].to_i }
|
310
420
|
.map {|_tag, _time, record| record[@key] }
|
311
421
|
else
|
312
422
|
@buffer[stream_identity].map {|_tag, _time, record| record[@key] }
|
@@ -317,6 +427,7 @@ module Fluent::Plugin
|
|
317
427
|
}
|
318
428
|
@buffer[stream_identity] = []
|
319
429
|
@buffer[stream_identity] << new_element if new_element
|
430
|
+
@buffer_size[stream_identity] = 0
|
320
431
|
[time, first_record.merge(new_record)]
|
321
432
|
end
|
322
433
|
|
@@ -366,3 +477,18 @@ module Fluent::Plugin
|
|
366
477
|
end
|
367
478
|
end
|
368
479
|
end
|
480
|
+
|
481
|
+
class Array
|
482
|
+
# Support Ruby 2.3 or earlier
|
483
|
+
unless [].respond_to?(:sum)
|
484
|
+
def sum
|
485
|
+
inject(0) do |memo, value|
|
486
|
+
if block_given?
|
487
|
+
memo + yield(value)
|
488
|
+
else
|
489
|
+
memo + value
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-concat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenji Okimoto
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: fluentd
|
@@ -100,6 +99,20 @@ dependencies:
|
|
100
99
|
- - ">="
|
101
100
|
- !ruby/object:Gem::Version
|
102
101
|
version: '0'
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: webrick
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
type: :development
|
110
|
+
prerelease: false
|
111
|
+
version_requirements: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
103
116
|
description: Fluentd Filter plugin to concat multiple event messages
|
104
117
|
email:
|
105
118
|
- okimoto@clear-code.com
|
@@ -107,10 +120,14 @@ executables: []
|
|
107
120
|
extensions: []
|
108
121
|
extra_rdoc_files: []
|
109
122
|
files:
|
110
|
-
- ".github/ISSUE_TEMPLATE.
|
123
|
+
- ".github/ISSUE_TEMPLATE/bug_report.yml"
|
124
|
+
- ".github/ISSUE_TEMPLATE/config.yml"
|
125
|
+
- ".github/ISSUE_TEMPLATE/feature_request.yml"
|
126
|
+
- ".github/workflows/add-to-project.yml"
|
127
|
+
- ".github/workflows/linux.yml"
|
128
|
+
- ".github/workflows/windows.yml"
|
111
129
|
- ".gitignore"
|
112
130
|
- ".rubocop.yml"
|
113
|
-
- ".travis.yml"
|
114
131
|
- Appraisals
|
115
132
|
- Gemfile
|
116
133
|
- LICENSE.txt
|
@@ -123,7 +140,6 @@ homepage: https://github.com/fluent-plugins-nursery/fluent-plugin-concat
|
|
123
140
|
licenses:
|
124
141
|
- MIT
|
125
142
|
metadata: {}
|
126
|
-
post_install_message:
|
127
143
|
rdoc_options: []
|
128
144
|
require_paths:
|
129
145
|
- lib
|
@@ -138,8 +154,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
154
|
- !ruby/object:Gem::Version
|
139
155
|
version: '0'
|
140
156
|
requirements: []
|
141
|
-
rubygems_version: 3.
|
142
|
-
signing_key:
|
157
|
+
rubygems_version: 3.6.8
|
143
158
|
specification_version: 4
|
144
159
|
summary: Fluentd Filter plugin to concat multiple event messages
|
145
160
|
test_files: []
|
data/.github/ISSUE_TEMPLATE.md
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
#### Problem
|
2
|
-
|
3
|
-
...
|
4
|
-
|
5
|
-
#### Steps to replicate
|
6
|
-
|
7
|
-
Provide example config and message
|
8
|
-
|
9
|
-
#### Expected Behavior
|
10
|
-
|
11
|
-
...
|
12
|
-
|
13
|
-
#### Your environment
|
14
|
-
|
15
|
-
* OS version
|
16
|
-
* paste result of ``fluentd --version`` or ``td-agent --version``
|
17
|
-
* plugin version
|
18
|
-
* paste boot log of fluentd or td-agent
|
19
|
-
* paste result of ``fluent-gem list``, ``td-agent-gem list`` or your Gemfile.lock
|
data/.travis.yml
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
sudo: false
|
2
|
-
language: ruby
|
3
|
-
|
4
|
-
notifications:
|
5
|
-
webhooks:
|
6
|
-
urls:
|
7
|
-
secure: NhOBulc3nFAnJrCr9G0/3IGd1pOb/Zk0Wyk9Jqrf7PHnI4mZOIgttGnewZx1sG96NWrs0Braue5vXwFBTrJ60J6EW3+Q33XzhaZR+Q95jEb+5vcdIP69TYs0TgOIiOouo69Y4rIE1ANYuF/1cBfCKxGulpOIKUCW5LYPkyUEwQy+7VccULctCYCha2OYHQau5SUITCQQqZMfYCvZ+9FRubhR+OiiAnwduuzixKm5b2sa2K4lCKy2vsz3JZtjvQ6/7WM5JsipErtuUY2fDlrWSr/9SehRu8LCD119FjV/HcaAffFMokX+8vJm6RLGcyx/0mAejEqaBofqf9vi1KQJKsKuEe8N9IUpoLrl36RYVfDDRNDqm0pSkrz/KaNxSSe5sDNsCFY+uEFhtiPMHJiSlyEA+BVqnUeoM9pSWp3pcTsIHAjq5VGfQ6u9IooUODCASBlOsLuPu+FYEWG3dC3oiOLEIqQ+WywJg2P7I4dJNhyivti5j61czipTGj28ReFiydp5macKabkvAFBvOW8q07QBO4cvjixhr8hiUgMEVdo5y5dqNhLvS182by3OpmtaSQfpuI8QXytiN9629lWzB7qu0Q7Pji/5wSqEuCdaEHjF5uCVYLFE2LaGJdlTLBg9n0vFfFpJXnP1q0nehq2qRs30pNcgkcCKfEIPJgFgCac=
|
8
|
-
on_success: change
|
9
|
-
on_failure: always
|
10
|
-
on_start: never
|
11
|
-
|
12
|
-
matrix:
|
13
|
-
include:
|
14
|
-
- rvm: 2.4.5
|
15
|
-
gemfile: Gemfile
|
16
|
-
- rvm: 2.5.5
|
17
|
-
gemfile: Gemfile
|
18
|
-
- rvm: 2.6.2
|
19
|
-
gemfile: Gemfile
|