fluentd 1.19.3 → 1.20.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/AGENTS.md +46 -0
- data/CHANGELOG.md +120 -0
- data/GithubWorkflow.md +1 -1
- data/MAINTAINERS.md +2 -2
- data/README.md +3 -2
- data/Rakefile +2 -1
- data/SECURITY.md +26 -1
- data/lib/fluent/command/cat.rb +3 -3
- data/lib/fluent/compat/exec_util.rb +20 -5
- data/lib/fluent/config/basic_parser.rb +0 -1
- data/lib/fluent/config/literal_parser.rb +22 -10
- data/lib/fluent/config/types.rb +10 -2
- data/lib/fluent/config/yaml_parser/loader.rb +12 -1
- data/lib/fluent/config/yaml_parser/parser.rb +14 -13
- data/lib/fluent/configurable.rb +1 -0
- data/lib/fluent/daemon.rb +2 -1
- data/lib/fluent/env.rb +1 -0
- data/lib/fluent/event.rb +37 -0
- data/lib/fluent/load.rb +0 -1
- data/lib/fluent/log.rb +2 -2
- data/lib/fluent/plugin/base.rb +7 -2
- data/lib/fluent/plugin/buf_file.rb +3 -3
- data/lib/fluent/plugin/buf_file_single.rb +6 -2
- data/lib/fluent/plugin/buffer/chunk.rb +14 -6
- data/lib/fluent/plugin/buffer/file_chunk.rb +28 -13
- data/lib/fluent/plugin/buffer/file_single_chunk.rb +28 -13
- data/lib/fluent/plugin/buffer.rb +125 -41
- data/lib/fluent/plugin/compressable.rb +2 -2
- data/lib/fluent/plugin/extractor.rb +17 -6
- data/lib/fluent/plugin/filter_record_transformer.rb +2 -1
- data/lib/fluent/plugin/formatter_out_file.rb +3 -4
- data/lib/fluent/plugin/in_exec.rb +6 -4
- data/lib/fluent/plugin/in_forward.rb +39 -29
- data/lib/fluent/plugin/in_http.rb +83 -2
- data/lib/fluent/plugin/in_monitor_agent.rb +2 -1
- data/lib/fluent/plugin/in_object_space.rb +2 -2
- data/lib/fluent/plugin/in_sample.rb +2 -1
- data/lib/fluent/plugin/in_syslog.rb +72 -6
- data/lib/fluent/plugin/in_tail/compatibility.rb +111 -0
- data/lib/fluent/plugin/in_tail/dir_watcher.rb +713 -0
- data/lib/fluent/plugin/in_tail/group_watch.rb +13 -13
- data/lib/fluent/plugin/in_tail/io_handler.rb +391 -0
- data/lib/fluent/plugin/in_tail/line_feeder.rb +230 -0
- data/lib/fluent/plugin/in_tail/stat_watcher.rb +52 -0
- data/lib/fluent/plugin/in_tail/tail_watcher.rb +276 -0
- data/lib/fluent/plugin/in_tail/worker_pool.rb +298 -0
- data/lib/fluent/plugin/in_tail.rb +324 -815
- data/lib/fluent/plugin/in_unix.rb +5 -3
- data/lib/fluent/plugin/out_exec_filter.rb +2 -2
- data/lib/fluent/plugin/out_file.rb +10 -4
- data/lib/fluent/plugin/out_forward/connection_manager.rb +18 -0
- data/lib/fluent/plugin/out_forward.rb +21 -2
- data/lib/fluent/plugin/out_http.rb +0 -10
- data/lib/fluent/plugin/output.rb +81 -31
- data/lib/fluent/plugin/parser_csv.rb +7 -2
- data/lib/fluent/plugin/parser_json.rb +25 -12
- data/lib/fluent/plugin/parser_ltsv.rb +2 -4
- data/lib/fluent/plugin/parser_msgpack.rb +7 -6
- data/lib/fluent/plugin/parser_syslog.rb +55 -8
- data/lib/fluent/plugin/parser_tsv.rb +6 -1
- data/lib/fluent/plugin/sd_file.rb +2 -1
- data/lib/fluent/plugin/storage_local.rb +2 -2
- data/lib/fluent/plugin_helper/http_server/server.rb +29 -13
- data/lib/fluent/plugin_helper/http_server.rb +2 -1
- data/lib/fluent/root_agent.rb +1 -1
- data/lib/fluent/supervisor.rb +32 -6
- data/lib/fluent/system_config.rb +5 -2
- data/lib/fluent/time.rb +8 -7
- data/lib/fluent/version.rb +1 -1
- data/templates/new_gem/.gitignore +8 -0
- metadata +41 -21
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa67a9199a9bcd73feb7dc286f4a1cb8347bd4d01d515561ceaf151671a9116e
|
|
4
|
+
data.tar.gz: ec7afdf8eea191d4badfb95361c3b41cfb35785c06dbacf3d0c0f65b89d734da
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1e900ecc699cb16836f2467105c09d51917446f7d7a885cbd66512e1fb8d24a2807a5b3ff7eeedec969e3e9dde7f8bc2cff40624e5c7d3d45d2bb5e4b536a75e
|
|
7
|
+
data.tar.gz: 8c258d373881b49dc90bc8e93ade34d46fb79b768203e05889a4ac3196361c97d185fa8b6c8006c9d985df65da20eabf1df62a802a3e365d27ba2f5cc345c1be
|
data/AGENTS.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Guidance for coding agents
|
|
2
|
+
|
|
3
|
+
This file is for AI coding agents (Claude Code, Cursor, Codex, Copilot, ...) working in this repository. Humans should read CONTRIBUTING.md.
|
|
4
|
+
|
|
5
|
+
## Primary sources
|
|
6
|
+
|
|
7
|
+
- Official documentation: https://docs.fluentd.org/
|
|
8
|
+
- Index for agents: https://docs.fluentd.org/llms.txt
|
|
9
|
+
- Every page is also available as Markdown by appending `.md` to its URL, e.g. https://docs.fluentd.org/configuration/config-file.md
|
|
10
|
+
- Read the documentation before answering questions about configuration syntax or plugin parameters. Do not invent parameters; check the plugin's page or its `config_param` declarations in this repository.
|
|
11
|
+
- Configuration has two formats.
|
|
12
|
+
- Classic: https://docs.fluentd.org/configuration/config-file.md
|
|
13
|
+
- YAML: https://docs.fluentd.org/configuration/config-file-yaml.md
|
|
14
|
+
|
|
15
|
+
## Repository layout
|
|
16
|
+
|
|
17
|
+
- `lib/fluent/plugin/` – bundled plugins (`in_*.rb`, `out_*.rb`, `filter_*.rb`, `parser_*.rb`, `formatter_*.rb`, `buf_*.rb`, `storage_*.rb`, `sd_*.rb`, `metrics_*.rb`)
|
|
18
|
+
- `lib/fluent/plugin_helper/` – plugin helpers
|
|
19
|
+
- `lib/fluent/config/` – configuration parsers (classic and YAML)
|
|
20
|
+
- `test/` – tests written with test-unit
|
|
21
|
+
- `templates/new_gem/` – files generated by `fluent-plugin-generate`
|
|
22
|
+
|
|
23
|
+
## Developing
|
|
24
|
+
|
|
25
|
+
- Install: `bundle install`
|
|
26
|
+
- Run all tests: `bundle exec rake test`
|
|
27
|
+
- Run one file: `bundle exec ruby -Ilib -Itest test/plugin/test_in_tail.rb`
|
|
28
|
+
- Plugin API reference: https://docs.fluentd.org/plugin-development/README.md
|
|
29
|
+
- Plugin helper reference: https://docs.fluentd.org/plugin-helper-overview/README.md
|
|
30
|
+
- Test helpers for plugins: https://docs.fluentd.org/plugin-development/plugin-test-code.md
|
|
31
|
+
|
|
32
|
+
## Conventions
|
|
33
|
+
|
|
34
|
+
- Follow CONTRIBUTING.md. Commits need a DCO sign-off (`git commit -s`).
|
|
35
|
+
- Keep changes minimal and focused; do not reformat unrelated code.
|
|
36
|
+
- Add or update tests under `test/` for behavior changes.
|
|
37
|
+
- Do not add runtime dependencies without discussion.
|
|
38
|
+
- Match the surrounding code style; there is no autoformatter to run. CI runs `rubocop`, but only the Security and Performance cops are enabled.
|
|
39
|
+
- Fluentd runs on Linux, macOS and Windows. CI tests `ubuntu-latest`, `macos-latest`, `windows-latest` and `windows-11-arm`. Assume your change must work on Windows.
|
|
40
|
+
|
|
41
|
+
## Issues and pull requests
|
|
42
|
+
|
|
43
|
+
- Pull requests follow `.github/PULL_REQUEST_TEMPLATE.md`. Keep its headings, including `Docs Changes` and `Release Note`, and write `Fixes #<n>` when an issue exists.
|
|
44
|
+
- Blank issues are disabled. Use `.github/ISSUE_TEMPLATE/bug_report.yml` or `.github/ISSUE_TEMPLATE/feature_request.yml` and answer every required field.
|
|
45
|
+
- Questions belong in [Discussions](https://github.com/fluent/fluentd/discussions), not in issues.
|
|
46
|
+
- Note that `gh pr create --body` and `gh issue create --body` skip the template. Pass `--template`, or reproduce the template's sections in the body you supply.
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,125 @@
|
|
|
1
|
+
# v1.20
|
|
2
|
+
|
|
3
|
+
## Release v1.20.0 - 2026/10/23
|
|
4
|
+
|
|
5
|
+
### Enhancement
|
|
6
|
+
|
|
7
|
+
* Replace Yajl with built-in JSON for simple cases https://github.com/fluent/fluentd/pull/5090
|
|
8
|
+
* out_forward: add `send_keepalive_packet` option to enable TCP keepalive (SO_KEEPALIVE) https://github.com/fluent/fluentd/pull/5262
|
|
9
|
+
* in_exec: add `command_timeout` option to limit child process execution time https://github.com/fluent/fluentd/pull/5320
|
|
10
|
+
* Replace Yajl with JSON for handling JSON stream https://github.com/fluent/fluentd/pull/5383
|
|
11
|
+
* When an input stream ends in the middle of a JSON document, Fluentd now logs a warning and discards the incomplete tail instead of raising `ParseError`.
|
|
12
|
+
* system_config: add `umask` option to `<system>` directive https://github.com/fluent/fluentd/pull/5390
|
|
13
|
+
* parser_syslog: accept a space after RFC3164 priority https://github.com/fluent/fluentd/pull/5449
|
|
14
|
+
* in_tail: add opt-in `enable_dir_watcher` and `dir_watcher_limit` to discover new files earlier by watching directories https://github.com/fluent/fluentd/pull/5528
|
|
15
|
+
* in_tail: add opt-in worker-thread parsing via `num_threads` to offload parsing from the event loop https://github.com/fluent/fluentd/pull/5529
|
|
16
|
+
* The default `num_threads 1` keeps the previous synchronous behavior.
|
|
17
|
+
* In worker mode, `monitor_agent` also reports `worker_pending_batch_count`, `worker_pending_bytes` and `worker_parse_error_count`.
|
|
18
|
+
* buffer: add `evacuate_limit_size` to keep evacuated chunks from filling the disk https://github.com/fluent/fluentd/pull/5473
|
|
19
|
+
* This option sets an approximate limit on the total size of the chunk files evacuated when the retry limit is reached, including the ones evacuated before. Chunks that do not fit are purged without being evacuated.
|
|
20
|
+
* The default `nil` keeps the previous behavior. Set `0` to disable evacuation.
|
|
21
|
+
* in_forward: accept metadata on encapsulated timestamps sent by Fluent Bit v5.0.5 or later https://github.com/fluent/fluentd/pull/5411
|
|
22
|
+
* Enable Ruby JIT by default https://github.com/fluent/fluentd/pull/5464
|
|
23
|
+
* The system configuration `enable_jit` now defaults to `true`.
|
|
24
|
+
* JIT increases memory usage of each worker process. Set `enable_jit false` in the `<system>` section to restore the previous behavior.
|
|
25
|
+
* This has no effect on Windows because YJIT is not supported there.
|
|
26
|
+
* fluent-plugin-generate: add .gitignore file https://github.com/fluent/fluentd/pull/5370
|
|
27
|
+
* Performance improvements
|
|
28
|
+
* https://github.com/fluent/fluentd/pull/5281
|
|
29
|
+
* https://github.com/fluent/fluentd/pull/5288
|
|
30
|
+
* https://github.com/fluent/fluentd/pull/5289
|
|
31
|
+
* https://github.com/fluent/fluentd/pull/5344
|
|
32
|
+
* https://github.com/fluent/fluentd/pull/5353
|
|
33
|
+
* https://github.com/fluent/fluentd/pull/5354
|
|
34
|
+
* https://github.com/fluent/fluentd/pull/5357
|
|
35
|
+
* https://github.com/fluent/fluentd/pull/5287
|
|
36
|
+
* https://github.com/fluent/fluentd/pull/5278
|
|
37
|
+
* https://github.com/fluent/fluentd/pull/5567
|
|
38
|
+
|
|
39
|
+
### Bug Fix
|
|
40
|
+
|
|
41
|
+
* http_server helper: Fix IPv6 bind address support in URI construction https://github.com/fluent/fluentd/pull/5239
|
|
42
|
+
* Fixed `URI::InvalidURIError` when binding to IPv6 addresses (e.g., `::`, `::1`)
|
|
43
|
+
* IPv6 addresses are now properly bracketed in URIs per RFC 3986 (e.g., `http://[::]:24231`)
|
|
44
|
+
* Handles pre-bracketed addresses correctly to avoid double-bracketing
|
|
45
|
+
* Affects all plugins using http_server helper with IPv6 bind addresses
|
|
46
|
+
* out_file: create symlinks for all chunks sharing the latest timekey https://github.com/fluent/fluentd/pull/5476
|
|
47
|
+
* time: fix TimeFormatter returning nil for the Unix epoch https://github.com/fluent/fluentd/pull/5420
|
|
48
|
+
* in_tail: fix log duplication when a rotated file is appended during `rotate_wait` with `follow_inodes` https://github.com/fluent/fluentd/pull/5499
|
|
49
|
+
* in_tail: fix `NameError` raised when flushing buffered lines with `emit_unmatched_lines true` https://github.com/fluent/fluentd/pull/5513
|
|
50
|
+
* in_tail: fix unread lines never being collected when a throttled file is removed from the watch list https://github.com/fluent/fluentd/pull/5515
|
|
51
|
+
* in_tail: fix shutdown errors and timeouts caused by an ongoing watcher refresh https://github.com/fluent/fluentd/pull/5530
|
|
52
|
+
* in_tail: fix closed stream error when file rotation overlaps with shutdown https://github.com/fluent/fluentd/pull/5551
|
|
53
|
+
* in_tail: use a monotonic clock for multiline flush timers so that they are not affected by wall-clock adjustments https://github.com/fluent/fluentd/pull/5542
|
|
54
|
+
* buffer: fix a race that could make the buffer `stage_size` gauge transiently negative while a write and a chunk enqueue overlap https://github.com/fluent/fluentd/pull/5481
|
|
55
|
+
* buffer: fix an enqueued unstaged file chunk being re-staged and flushed twice, which caused `closed stream` / `ENOENT` errors and leaked buffer size gauges https://github.com/fluent/fluentd/pull/5517
|
|
56
|
+
* parser_msgpack: fix leftover data from one parse call leaking into the next https://github.com/fluent/fluentd/pull/5553
|
|
57
|
+
* http_server helper: fix HTTP endpoints never recovering after a bind failure https://github.com/fluent/fluentd/pull/5523
|
|
58
|
+
* The plugin now fails to start, and the worker is restarted until the port is available.
|
|
59
|
+
* root_agent: fix `emit_records` and `emit_size` never counted for inputs with `@label` https://github.com/fluent/fluentd/pull/5526
|
|
60
|
+
* supervisor: fix graceful config reload failing for YAML configuration https://github.com/fluent/fluentd/pull/5522
|
|
61
|
+
* It also fixes `<<: !include` of a file that contains a mapping.
|
|
62
|
+
|
|
63
|
+
### Misc
|
|
64
|
+
|
|
65
|
+
* Drop Ruby 3.2 support https://github.com/fluent/fluentd/pull/5465
|
|
66
|
+
* out_http: remove the Net::HTTP extra_chain_cert monkey patch https://github.com/fluent/fluentd/pull/5484
|
|
67
|
+
* gem: add aarch64-mingw-ucrt gem https://github.com/fluent/fluentd/pull/5400
|
|
68
|
+
* gem: add json gem (>= 2.21) as runtime dependency and remove Refinements workaround https://github.com/fluent/fluentd/pull/5429
|
|
69
|
+
* in_tail: internal refactoring
|
|
70
|
+
* https://github.com/fluent/fluentd/pull/5518
|
|
71
|
+
* https://github.com/fluent/fluentd/pull/5520
|
|
72
|
+
* https://github.com/fluent/fluentd/pull/5521
|
|
73
|
+
* https://github.com/fluent/fluentd/pull/5527
|
|
74
|
+
* https://github.com/fluent/fluentd/pull/5554
|
|
75
|
+
|
|
1
76
|
# v1.19
|
|
2
77
|
|
|
78
|
+
## Release v1.19.4 - 2026/09/28
|
|
79
|
+
|
|
80
|
+
### Bug Fix
|
|
81
|
+
|
|
82
|
+
* buffer: enforce decompression_size_limit on the chunk IO path https://github.com/fluent/fluentd/pull/5504
|
|
83
|
+
* buffer: clamp exported buffer size metrics to non-negative values https://github.com/fluent/fluentd/pull/5488
|
|
84
|
+
* buffer: fix spurious `BufferOverflowError` caused by `queue_size` leaking when a chunk purge fails https://github.com/fluent/fluentd/pull/5487
|
|
85
|
+
* buffer: fix `stage_byte_size` leak on staged to unstaged chunk demotion that could eventually raise spurious `BufferOverflowError` in plugins implementing `#format` https://github.com/fluent/fluentd/pull/5456
|
|
86
|
+
* in_syslog: enforce message_length_limit on TCP/TLS transport https://github.com/fluent/fluentd/pull/5502
|
|
87
|
+
* The default value of `message_length_limit` is changed from 2048 to 8192 to match rsyslog's default `MaxMessageSize`.
|
|
88
|
+
* output: fix incomplete path traversal check in extract_placeholders https://github.com/fluent/fluentd/pull/5501
|
|
89
|
+
* output: treat JSON::GeneratorError as unrecoverable error https://github.com/fluent/fluentd/pull/5423
|
|
90
|
+
* parser_syslog: fix NameError when RFC5424 timestamp has repeated spaces https://github.com/fluent/fluentd/pull/5500
|
|
91
|
+
* parser_syslog: fix NameError when RFC3164 timestamp has repeated spaces https://github.com/fluent/fluentd/pull/5497
|
|
92
|
+
* parser_syslog: avoid excessive backtracking when parsing malformed RFC5424 structured data https://github.com/fluent/fluentd/pull/5444
|
|
93
|
+
* chunk: ensure to close the Tempfile for decompressed data https://github.com/fluent/fluentd/pull/5486
|
|
94
|
+
* plugin base: bound the number of worker lock files by hashing the path into a fixed set of buckets https://github.com/fluent/fluentd/pull/5471
|
|
95
|
+
* out_forward: stop the endless "ack in response and chunk id in sent data are different" warning storm by discarding (instead of reusing) a keepalive socket whose ack failed or came back with a mismatched chunk id https://github.com/fluent/fluentd/pull/5445
|
|
96
|
+
* config: accept empty lines in quoted strings https://github.com/fluent/fluentd/pull/5478
|
|
97
|
+
* config: fix a config error when a single scalar value is given to an array option in YAML config syntax (for example `retryable_response_codes: 503`) https://github.com/fluent/fluentd/pull/5433
|
|
98
|
+
* supervisor: reduce memory usage of cleanup_lock_dir with huge number of lock files https://github.com/fluent/fluentd/pull/5472
|
|
99
|
+
|
|
100
|
+
### Enhancement
|
|
101
|
+
|
|
102
|
+
* in_http: add `<auth>` for basic authentication and `<security>` for client network allowlisting https://github.com/fluent/fluentd/pull/5503
|
|
103
|
+
|
|
104
|
+
### Misc
|
|
105
|
+
|
|
106
|
+
* gem: support json gem v3.x https://github.com/fluent/fluentd/pull/5493
|
|
107
|
+
* Add `allow_comments: true` option for json parser https://github.com/fluent/fluentd/pull/5432
|
|
108
|
+
* Set `allow_duplicate_key: true` for all `JSON.parse` call https://github.com/fluent/fluentd/pull/5430
|
|
109
|
+
* CI fixes
|
|
110
|
+
* https://github.com/fluent/fluentd/pull/5495
|
|
111
|
+
* https://github.com/fluent/fluentd/pull/5477
|
|
112
|
+
* https://github.com/fluent/fluentd/pull/5466
|
|
113
|
+
* https://github.com/fluent/fluentd/pull/5460
|
|
114
|
+
* https://github.com/fluent/fluentd/pull/5455
|
|
115
|
+
* https://github.com/fluent/fluentd/pull/5454
|
|
116
|
+
* https://github.com/fluent/fluentd/pull/5453
|
|
117
|
+
* https://github.com/fluent/fluentd/pull/5452
|
|
118
|
+
* https://github.com/fluent/fluentd/pull/5434
|
|
119
|
+
* https://github.com/fluent/fluentd/pull/5426
|
|
120
|
+
* https://github.com/fluent/fluentd/pull/5425
|
|
121
|
+
* https://github.com/fluent/fluentd/pull/5424
|
|
122
|
+
|
|
3
123
|
## Release v1.19.3 - 2026/06/25
|
|
4
124
|
|
|
5
125
|
### Bug Fix
|
data/GithubWorkflow.md
CHANGED
|
@@ -9,7 +9,7 @@ Table of Contents
|
|
|
9
9
|
* [Create a Pull Request](#create-a-pull-request)
|
|
10
10
|
|
|
11
11
|
|
|
12
|
-
The [fluentd](https://github.com/fluent/fluentd.git) code is hosted on Github (https://github.com/fluent/fluentd). The repository is called `upstream`. Contributors will develop and commit their changes in a clone of upstream repository. Then contributors push their change to their forked repository (`origin`) and create a Pull Request (PR), the PR will be merged to `upstream` repository if it meets
|
|
12
|
+
The [fluentd](https://github.com/fluent/fluentd.git) code is hosted on Github (https://github.com/fluent/fluentd). The repository is called `upstream`. Contributors will develop and commit their changes in a clone of upstream repository. Then contributors push their change to their forked repository (`origin`) and create a Pull Request (PR), the PR will be merged to `upstream` repository if it meets all the necessary requirements.
|
|
13
13
|
|
|
14
14
|
## Fork a repository
|
|
15
15
|
|
data/MAINTAINERS.md
CHANGED
|
@@ -7,10 +7,10 @@
|
|
|
7
7
|
- [Satoshi Tagomori](https://github.com/tagomoris)
|
|
8
8
|
- [Toru Takahashi](https://github.com/toru-takahashi), [Treasure Data](https://www.treasuredata.com/)
|
|
9
9
|
- [Eduardo Silva](https://github.com/edsiper), [Chronosphere](https://chronosphere.io/)
|
|
10
|
-
- [Fujimoto Seiji](https://github.com/
|
|
10
|
+
- [Fujimoto Seiji](https://github.com/fujimotos)
|
|
11
11
|
- [Takuro Ashie](https://github.com/ashie), [ClearCode](https://www.clear-code.com/)
|
|
12
12
|
- [Kentaro Hayashi](https://github.com/kenhys), [ClearCode](https://www.clear-code.com/)
|
|
13
|
-
- [Daijiro Fukuda](https://github.com/daipom)
|
|
13
|
+
- [Daijiro Fukuda](https://github.com/daipom)
|
|
14
14
|
|
|
15
15
|
## Sub Projects: Fluent Bit
|
|
16
16
|
|
data/README.md
CHANGED
|
@@ -5,6 +5,7 @@ Fluentd: Open-Source Log Collector
|
|
|
5
5
|
[](https://github.com/fluent/fluentd/actions/workflows/test-ruby-head.yml)
|
|
6
6
|
[](https://bestpractices.coreinfrastructure.org/projects/1189)
|
|
7
7
|
[](https://scorecard.dev/viewer/?uri=github.com/fluent/fluentd)
|
|
8
|
+
[](https://github.com/fluent/fluentd/actions/workflows/backport.yml)
|
|
8
9
|
|
|
9
10
|
[Fluentd](https://www.fluentd.org/) collects events from various data sources and writes them to files, RDBMS, NoSQL, IaaS, SaaS, Hadoop and so on. Fluentd helps you unify your logging infrastructure (Learn more about the [Unified Logging Layer](https://www.fluentd.org/blog/unified-logging-layer)).
|
|
10
11
|
|
|
@@ -24,11 +25,11 @@ Fluentd: Open-Source Log Collector
|
|
|
24
25
|
### Branch
|
|
25
26
|
|
|
26
27
|
- master: For v1 development.
|
|
27
|
-
- v0.12: For v0.12. This is deprecated version. we already stopped supporting (See https://www.fluentd.org/blog/drop-schedule-announcement-in-2019).
|
|
28
|
+
- v0.12: For v0.12. This is a deprecated version. we already stopped supporting (See https://www.fluentd.org/blog/drop-schedule-announcement-in-2019).
|
|
28
29
|
|
|
29
30
|
### Prerequisites
|
|
30
31
|
|
|
31
|
-
- Ruby 3.
|
|
32
|
+
- Ruby 3.3 or later
|
|
32
33
|
- git
|
|
33
34
|
|
|
34
35
|
`git` should be in `PATH`. On Windows, you can use `Github for Windows` and `GitShell` for easy setup.
|
data/Rakefile
CHANGED
|
@@ -6,6 +6,7 @@ require 'rake/testtask'
|
|
|
6
6
|
require 'rake/clean'
|
|
7
7
|
|
|
8
8
|
require_relative 'tasks/benchmark'
|
|
9
|
+
require_relative 'tasks/backport'
|
|
9
10
|
|
|
10
11
|
task test: [:base_test]
|
|
11
12
|
|
|
@@ -16,7 +17,7 @@ namespace :build do
|
|
|
16
17
|
desc 'Build gems for all platforms'
|
|
17
18
|
task :all do
|
|
18
19
|
Bundler.with_original_env do
|
|
19
|
-
%w[ruby x86-mingw32 x64-mingw32 x64-mingw-ucrt].each do |name|
|
|
20
|
+
%w[ruby x86-mingw32 x64-mingw32 x64-mingw-ucrt aarch64-mingw-ucrt].each do |name|
|
|
20
21
|
ENV['GEM_BUILD_FAKE_PLATFORM'] = name
|
|
21
22
|
Rake::Task["build"].execute
|
|
22
23
|
end
|
data/SECURITY.md
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
|-----------|--------------------|
|
|
7
|
+
| 1.20.x | :white_check_mark: |
|
|
7
8
|
| 1.19.x | :white_check_mark: |
|
|
8
9
|
| 1.18.x | :x: |
|
|
9
10
|
| 1.17.x | :x: |
|
|
10
|
-
| 1.16.x | :
|
|
11
|
+
| 1.16.x | :x: |
|
|
11
12
|
| <= 1.15.x | :x: |
|
|
12
13
|
|
|
13
14
|
## Reporting a Vulnerability
|
|
@@ -15,8 +16,32 @@
|
|
|
15
16
|
Please post your vulnerability report from the following page:
|
|
16
17
|
https://github.com/fluent/fluentd/security/advisories
|
|
17
18
|
|
|
19
|
+
> [!CAUTION]
|
|
20
|
+
> In above contact form, we accept about **ONLY** Fluentd's vulnerability, in contrast, **REJECT** your vulnerability report about Fluentd derivative products such as fluent-package, Fluentd container images and Fluentd kubernetes deamonset images and so on. There are appropriate contact forms for every these derivative products. See the following notice.
|
|
21
|
+
|
|
18
22
|
> [!NOTE]
|
|
19
23
|
> If you use fluent-package, please check [fluent-package-builder](https://github.com/fluent/fluent-package-builder/blob/master/SECURITY.md) and report it there.
|
|
20
24
|
|
|
21
25
|
> [!NOTE]
|
|
22
26
|
> If you use a Docker image of Fluentd, please check [Fluentd Docker Image](https://github.com/fluent/fluentd-docker-image/blob/master/SECURITY.md) and report it there.
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
## Out of Scope / Non-Vulnerabilities
|
|
30
|
+
|
|
31
|
+
Before reporting a vulnerability, please check if it falls under the following expected behaviors, design choices, or configuration issues. Reports regarding these items will be closed immediately as **not a bug** or **out of scope**.
|
|
32
|
+
|
|
33
|
+
### 1. `in_debug_agent` and arbitrary code execution (`eval`)
|
|
34
|
+
|
|
35
|
+
* **Description:** The `in_debug_agent` plugin is a developer tool designed specifically for debugging a running Fluentd process via dRuby. It requires explicit activation in the local configuration file and is disabled by default.
|
|
36
|
+
* **Why it is not a vulnerability:** The ability to execute arbitrary Ruby code (`eval`) is **by design**. It functions similarly to `gdbserver`, allowing maintainers to inspect internal process states. It does not introduce a security risk unless an administrator explicitly enables it and exposes the port to an untrusted network, which constitutes a severe misconfiguration rather than a flaw in Fluentd itself.
|
|
37
|
+
|
|
38
|
+
### 2. `record_transformer` with `enable_ruby`
|
|
39
|
+
|
|
40
|
+
* **Description:** The `enable_ruby` option in the `record_transformer` plugin allows administrators to use Ruby expressions within the configuration file to transform log records dynamically.
|
|
41
|
+
* **Why it is not a vulnerability:** Executing the Ruby code block defined in the configuration file is **by design**. It does not allow arbitrary code execution from untrusted log inputs unless the user explicitly writes insecure expressions (e.g., passing untrusted input directly into another dynamic evaluation nested inside the block). If an attacker can modify the local Fluentd configuration file to enable this feature and inject malicious Ruby code, the system is already fully compromised at the OS/infrastructure level (Post-Exploitation). We do not accept RCE reports that rely on the ability to modify the local configuration file.
|
|
42
|
+
|
|
43
|
+
### 3. ReDoS (Regular Expression Denial of Service) reproducible only on Ruby 3.2 or older
|
|
44
|
+
|
|
45
|
+
* **Description:** Potential algorithmic complexity issues in regular expressions that could lead to High CPU usage or Denial of Service on older Ruby runtimes.
|
|
46
|
+
* **Why it is out of scope:** Fluentd officially supports modern Ruby environments. Our primary distribution channels including the official `fluent-package` and official Docker images ship with **Ruby 3.3 or later (e.g., Ruby 3.4)**, which includes built-in, robust mitigation against ReDoS at the language level (such as matching timeouts and engine-level optimizations). We do not accept ReDoS reports that only impact legacy Ruby versions (Ruby 3.2 or older) unless the issue can be demonstrated to cause a practical denial of service on Ruby 3.3+.
|
|
47
|
+
However, if you find inefficient regular expressions, we welcome them as standard bug reports or performance improvement suggestions via regular GitHub Issues rather than security advisories.
|
data/lib/fluent/command/cat.rb
CHANGED
|
@@ -107,7 +107,7 @@ rescue
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
require 'socket'
|
|
110
|
-
require '
|
|
110
|
+
require 'json'
|
|
111
111
|
require 'msgpack'
|
|
112
112
|
require 'fluent/ext_monitor_require'
|
|
113
113
|
|
|
@@ -304,7 +304,7 @@ class Writer
|
|
|
304
304
|
end
|
|
305
305
|
|
|
306
306
|
def abort_message(time, record)
|
|
307
|
-
$stdout.puts "!#{time}:#{
|
|
307
|
+
$stdout.puts "!#{time}:#{JSON.generate(record)}"
|
|
308
308
|
end
|
|
309
309
|
end
|
|
310
310
|
|
|
@@ -326,7 +326,7 @@ case format
|
|
|
326
326
|
when 'json'
|
|
327
327
|
begin
|
|
328
328
|
while line = $stdin.gets
|
|
329
|
-
record =
|
|
329
|
+
record = JSON.parse(line, **Fluent::DEFAULT_JSON_PARSE_OPTIONS)
|
|
330
330
|
w.write(record)
|
|
331
331
|
end
|
|
332
332
|
rescue
|
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
#
|
|
16
16
|
|
|
17
17
|
require 'msgpack'
|
|
18
|
-
require '
|
|
18
|
+
require 'json'
|
|
19
19
|
|
|
20
|
+
require 'fluent/env'
|
|
20
21
|
require 'fluent/engine'
|
|
21
22
|
require 'fluent/plugin'
|
|
22
23
|
require 'fluent/parser'
|
|
@@ -76,10 +77,24 @@ module Fluent
|
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
class JSONParser < Parser
|
|
80
|
+
BYTES_TO_READ = 8192
|
|
81
|
+
|
|
79
82
|
def call(io)
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
parser = JSON::ResumableParser.new(**Fluent::DEFAULT_JSON_PARSE_OPTIONS)
|
|
84
|
+
begin
|
|
85
|
+
chunk = +"".b
|
|
86
|
+
while io.readpartial(BYTES_TO_READ, chunk)
|
|
87
|
+
parser << chunk
|
|
88
|
+
while parser.parse
|
|
89
|
+
@on_message.call(parser.value)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
rescue EOFError
|
|
93
|
+
unless parser.empty?
|
|
94
|
+
$log&.warn "JSON stream ended in the middle of a document; " \
|
|
95
|
+
"discarding incomplete data"
|
|
96
|
+
end
|
|
97
|
+
end
|
|
83
98
|
end
|
|
84
99
|
end
|
|
85
100
|
|
|
@@ -115,7 +130,7 @@ module Fluent
|
|
|
115
130
|
|
|
116
131
|
class JSONFormatter < Formatter
|
|
117
132
|
def call(record, out)
|
|
118
|
-
out <<
|
|
133
|
+
out << JSON.generate(record) << "\n"
|
|
119
134
|
end
|
|
120
135
|
end
|
|
121
136
|
|
|
@@ -28,7 +28,6 @@ module Fluent
|
|
|
28
28
|
SPACING = /(?:[ \t\r\n]|\z|\#.*?(?:\z|[\r\n]))+/
|
|
29
29
|
ZERO_OR_MORE_SPACING = /(?:[ \t\r\n]|\z|\#.*?(?:\z|[\r\n]))*/
|
|
30
30
|
SPACING_WITHOUT_COMMENT = /(?:[ \t\r\n]|\z)+/
|
|
31
|
-
LINE_END_WITHOUT_SPACING_AND_COMMENT = /(?:\z|[\r\n])/
|
|
32
31
|
|
|
33
32
|
module ClassMethods
|
|
34
33
|
def symbol(string)
|
|
@@ -17,15 +17,24 @@
|
|
|
17
17
|
require 'stringio'
|
|
18
18
|
|
|
19
19
|
require 'json'
|
|
20
|
-
require 'yajl'
|
|
21
20
|
require 'socket'
|
|
22
21
|
require 'ripper'
|
|
23
22
|
|
|
23
|
+
require 'fluent/env'
|
|
24
24
|
require 'fluent/config/basic_parser'
|
|
25
25
|
|
|
26
26
|
module Fluent
|
|
27
27
|
module Config
|
|
28
28
|
class LiteralParser < BasicParser
|
|
29
|
+
# A physical line break (LF, CR, or CRLF) inside a quoted string.
|
|
30
|
+
# CRLF is normalized to LF so that the same config text does not produce a
|
|
31
|
+
# different value depending on whether the file was saved with LF or CRLF.
|
|
32
|
+
# A lone CR is kept as-is, and an escaped "\r\n" still produces CRLF.
|
|
33
|
+
LINE_BREAK = /\r\n|[\r\n]/
|
|
34
|
+
# A backslash immediately followed by a physical line break.
|
|
35
|
+
# It works as a line continuation, so both are stripped from the value.
|
|
36
|
+
LINE_CONTINUATION = /\\#{LINE_BREAK}/o
|
|
37
|
+
|
|
29
38
|
def self.unescape_char(c)
|
|
30
39
|
case c
|
|
31
40
|
when '"'
|
|
@@ -98,11 +107,10 @@ module Fluent
|
|
|
98
107
|
else
|
|
99
108
|
return string.join
|
|
100
109
|
end
|
|
101
|
-
elsif
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
skip(/[^"]#{LINE_END_WITHOUT_SPACING_AND_COMMENT}/o)
|
|
110
|
+
elsif skip(LINE_CONTINUATION)
|
|
111
|
+
next
|
|
112
|
+
elsif s = scan(LINE_BREAK)
|
|
113
|
+
string << (s == "\r\n" ? "\n" : s)
|
|
106
114
|
elsif s = scan(/\\./)
|
|
107
115
|
string << eval_escape_char(s[1,1])
|
|
108
116
|
elsif skip(/\#\{/)
|
|
@@ -125,6 +133,8 @@ module Fluent
|
|
|
125
133
|
string << "'"
|
|
126
134
|
elsif s = scan(/\\\\/)
|
|
127
135
|
string << "\\"
|
|
136
|
+
elsif s = scan(LINE_BREAK)
|
|
137
|
+
string << (s == "\r\n" ? "\n" : s)
|
|
128
138
|
elsif s = scan(/./)
|
|
129
139
|
string << s
|
|
130
140
|
else
|
|
@@ -225,8 +235,10 @@ EOM
|
|
|
225
235
|
|
|
226
236
|
def scan_json(is_array)
|
|
227
237
|
result = nil
|
|
228
|
-
#
|
|
229
|
-
#
|
|
238
|
+
# scan_json detects the end of a JSON literal by repeatedly attempting
|
|
239
|
+
# to parse the buffer and treating a successful parse as completion.
|
|
240
|
+
# This requires a parser that raises JSON::ParserError for incomplete
|
|
241
|
+
# input like '[1', '{"h"', '{"h":' or '{"h1":1'.
|
|
230
242
|
|
|
231
243
|
buffer = (is_array ? "[" : "{")
|
|
232
244
|
line_buffer = ""
|
|
@@ -241,7 +253,7 @@ EOM
|
|
|
241
253
|
# '{"foo":"bar", #' -> '{"foo":"bar"}' (to check)
|
|
242
254
|
parsed = nil
|
|
243
255
|
begin
|
|
244
|
-
parsed = JSON.parse(buffer + line_buffer.rstrip.sub(/,$/, '') + (is_array ? "]" : "}"))
|
|
256
|
+
parsed = JSON.parse(buffer + line_buffer.rstrip.sub(/,$/, '') + (is_array ? "]" : "}"), **Fluent::DEFAULT_JSON_PARSE_OPTIONS)
|
|
245
257
|
rescue JSON::ParserError
|
|
246
258
|
# This '#' is in json string literals
|
|
247
259
|
end
|
|
@@ -276,7 +288,7 @@ EOM
|
|
|
276
288
|
|
|
277
289
|
line_buffer << char
|
|
278
290
|
begin
|
|
279
|
-
result = JSON.parse(buffer + line_buffer)
|
|
291
|
+
result = JSON.parse(buffer + line_buffer, **Fluent::DEFAULT_JSON_PARSE_OPTIONS)
|
|
280
292
|
rescue JSON::ParserError
|
|
281
293
|
# Incomplete json string yet
|
|
282
294
|
end
|
data/lib/fluent/config/types.rb
CHANGED
|
@@ -201,7 +201,7 @@ module Fluent
|
|
|
201
201
|
return nil if val.nil?
|
|
202
202
|
|
|
203
203
|
param = if val.is_a?(String)
|
|
204
|
-
val.start_with?('{') ? JSON.parse(val) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
|
|
204
|
+
val.start_with?('{') ? JSON.parse(val, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) : Hash[val.strip.split(/\s*,\s*/).map{|v| v.split(':', 2)}]
|
|
205
205
|
else
|
|
206
206
|
val
|
|
207
207
|
end
|
|
@@ -228,7 +228,15 @@ module Fluent
|
|
|
228
228
|
return nil if val.nil?
|
|
229
229
|
|
|
230
230
|
param = if val.is_a?(String)
|
|
231
|
-
val.start_with?('[') ? JSON.parse(val) : val.strip.split(/\s*,\s*/)
|
|
231
|
+
val.start_with?('[') ? JSON.parse(val, **Fluent::DEFAULT_JSON_PARSE_OPTIONS) : val.strip.split(/\s*,\s*/)
|
|
232
|
+
elsif val.is_a?(Array)
|
|
233
|
+
val
|
|
234
|
+
elsif val.is_a?(Numeric) || val == true || val == false
|
|
235
|
+
# Wrap only the bare scalars that Psych/YAML actually produces
|
|
236
|
+
# here (nil is handled by the early return above). Any other
|
|
237
|
+
# type (Hash, Symbol, Time, arbitrary objects) falls through and
|
|
238
|
+
# still raises "array required" below.
|
|
239
|
+
[val]
|
|
232
240
|
else
|
|
233
241
|
val
|
|
234
242
|
end
|
|
@@ -71,9 +71,17 @@ module Fluent
|
|
|
71
71
|
else
|
|
72
72
|
pattern = path
|
|
73
73
|
end
|
|
74
|
+
# A single file keeps its own shape; only glob matches are aggregated.
|
|
75
|
+
return load(pattern) if File.file?(pattern)
|
|
76
|
+
|
|
74
77
|
result = []
|
|
75
78
|
Dir.glob(pattern).sort.each do |path|
|
|
76
|
-
|
|
79
|
+
loaded = load(Pathname.new(path))
|
|
80
|
+
if loaded.is_a?(Hash)
|
|
81
|
+
result.push(loaded)
|
|
82
|
+
else
|
|
83
|
+
result.concat(loaded)
|
|
84
|
+
end
|
|
77
85
|
end
|
|
78
86
|
result
|
|
79
87
|
rescue SystemCallError => e
|
|
@@ -93,6 +101,9 @@ module Fluent
|
|
|
93
101
|
|
|
94
102
|
def revive_hash(hash, o)
|
|
95
103
|
super(hash, o).tap do |r|
|
|
104
|
+
if r[SHOVEL].is_a?(Array) && r[SHOVEL].all?(Hash)
|
|
105
|
+
r[SHOVEL] = r[SHOVEL].reverse_each.reduce({}) { |a, e| a.merge!(e) }
|
|
106
|
+
end
|
|
96
107
|
if r[SHOVEL].is_a?(Hash)
|
|
97
108
|
h2 = {}
|
|
98
109
|
r.each do |k, v|
|
|
@@ -106,19 +106,20 @@ module Fluent
|
|
|
106
106
|
|
|
107
107
|
def included_sections_build(config, section_builder, indent: 0)
|
|
108
108
|
config.each_entry do |e|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
109
|
+
e.keys.each do |k|
|
|
110
|
+
cc = e.delete(k)
|
|
111
|
+
case k
|
|
112
|
+
when 'label'
|
|
113
|
+
section_builder.add_section(label_build(cc, indent: indent))
|
|
114
|
+
when 'worker'
|
|
115
|
+
section_builder.add_section(worker_build(cc, indent: indent))
|
|
116
|
+
when 'source'
|
|
117
|
+
section_builder.add_section(source_build(cc, indent: indent))
|
|
118
|
+
when 'filter'
|
|
119
|
+
section_builder.add_section(filter_build(cc, indent: indent))
|
|
120
|
+
when 'match'
|
|
121
|
+
section_builder.add_section(match_build(cc, indent: indent))
|
|
122
|
+
end
|
|
122
123
|
end
|
|
123
124
|
end
|
|
124
125
|
end
|
data/lib/fluent/configurable.rb
CHANGED
data/lib/fluent/daemon.rb
CHANGED
|
@@ -5,9 +5,10 @@ here = File.dirname(__FILE__)
|
|
|
5
5
|
$LOAD_PATH << File.expand_path(File.join(here, '..'))
|
|
6
6
|
|
|
7
7
|
require 'serverengine'
|
|
8
|
+
require 'fluent/env'
|
|
8
9
|
require 'fluent/supervisor'
|
|
9
10
|
|
|
10
11
|
server_module = Fluent.const_get(ARGV[0])
|
|
11
12
|
worker_module = Fluent.const_get(ARGV[1])
|
|
12
|
-
params = JSON.parse(ARGV[2])
|
|
13
|
+
params = JSON.parse(ARGV[2], **Fluent::DEFAULT_JSON_PARSE_OPTIONS)
|
|
13
14
|
ServerEngine::Daemon.run_server(server_module, worker_module) { Fluent::Supervisor.serverengine_config(params) }
|
data/lib/fluent/env.rb
CHANGED
|
@@ -26,6 +26,7 @@ module Fluent
|
|
|
26
26
|
DEFAULT_SOCKET_PATH = ENV['FLUENT_SOCKET'] || '/var/run/fluent/fluent.sock'
|
|
27
27
|
DEFAULT_BACKUP_DIR = ENV['FLUENT_BACKUP_DIR'] || '/tmp/fluent'
|
|
28
28
|
DEFAULT_OJ_OPTIONS = Fluent::OjOptions.load_env
|
|
29
|
+
DEFAULT_JSON_PARSE_OPTIONS = { allow_duplicate_key: true, allow_comments: true }.freeze
|
|
29
30
|
DEFAULT_DIR_PERMISSION = 0755
|
|
30
31
|
DEFAULT_FILE_PERMISSION = 0644
|
|
31
32
|
INSTANCE_ID = ENV['FLUENT_INSTANCE_ID'] || SecureRandom.uuid
|
data/lib/fluent/event.rb
CHANGED
|
@@ -309,6 +309,43 @@ module Fluent
|
|
|
309
309
|
end
|
|
310
310
|
end
|
|
311
311
|
|
|
312
|
+
class MetadataTimeEventStream < EventStream
|
|
313
|
+
def initialize(es)
|
|
314
|
+
@es = es
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def empty?
|
|
318
|
+
@es.empty?
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def dup
|
|
322
|
+
self.class.new(@es.dup)
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
def size
|
|
326
|
+
@es.size
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
def repeatable?
|
|
330
|
+
@es.repeatable?
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def slice(index, num)
|
|
334
|
+
self.class.new(@es.slice(index, num))
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
def each(unpacker: nil, &block)
|
|
338
|
+
@es.each(unpacker: unpacker) do |time, record|
|
|
339
|
+
next if record.nil?
|
|
340
|
+
|
|
341
|
+
time = time[0] if time.is_a?(Array)
|
|
342
|
+
time = Fluent::EventTime.now if time.nil? || time.to_i == 0
|
|
343
|
+
block.call(time, record)
|
|
344
|
+
end
|
|
345
|
+
nil
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
|
|
312
349
|
module ChunkMessagePackEventStreamer
|
|
313
350
|
# chunk.extend(ChunkMessagePackEventStreamer)
|
|
314
351
|
# => chunk.each{|time, record| ... }
|