fix(diskqueue): use per-beat paths instead of global paths#48834
fix(diskqueue): use per-beat paths instead of global paths#48834orestisfl merged 23 commits intoelastic:mainfrom
Conversation
Add a Paths field to diskqueue Settings so beat receivers get their own data directory for the disk queue. The pipeline threads its per-beat paths through to the diskqueue factory. When Paths is nil (e.g. from output-level queue overrides), the global paths.Resolve fallback is preserved for backward compatibility. Closes elastic#46989
Output factories can configure the queue (including diskqueue). Thread the per-beat *paths.Path through outputs.Load and outputs.Success/SuccessNet so queue settings no longer rely on the global paths instance. This also makes diskqueue settings require Paths when resolving the default queue directory.
🤖 GitHub commentsJust comment with:
|
612419e to
dfd18fb
Compare
## What does this PR do? Remove per-test context timeouts and rely on the go test -timeout flag (20m in CI). Bump sleep durations to 1200s to outlast the test run. ## Why is it important? The container system tests used a shared 5-minute context.WithTimeout for the entire permission matrix. On slower CI workers the 8-case matrix in TestProcessAllSettings recently started exceeded this, causing "context deadline exceeded" failures: https://buildkite.com/elastic/elastic-agent-system-metrics/builds/929 ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added tests that prove my fix is effective or that my feature works - [ ] ~~I have added an entry in `CHANGELOG.md`~~ ## Related issues CI failed in main and elastic/beats#48834
This reverts commit dfd18fb.
|
Pinging @elastic/elastic-agent-data-plane (Team:Elastic-Agent-Data-Plane) |
Instead of passing *paths.Path through every method call, store it on diskQueue, readerLoop, writerLoop, and deleterLoop structs. This avoids cascading signature changes while keeping paths out of Settings. Also fixes the missed callsite in outputs/util.go.
|
This pull request is now in conflicts. Could you fix it? 🙏 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review infoConfiguration used: Organization UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (39)
📝 WalkthroughWalkthroughThis pull request threads beat instance-specific path information throughout the outputs and queueing subsystems, replacing implicit global path resolution with explicit parameterization. The 🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs). Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…eat-paths # Conflicts: # libbeat/publisher/queue/diskqueue/segments_test.go
fix(diskqueue): use per-beat paths instead of global paths Add a `Paths` field to diskqueue `Settings` so each beat receiver gets its own data directory for the disk queue. Thread the per-beat `*paths.Path` through the pipeline and output factory APIs: - `outputs.Factory`, `outputs.Load`, `outputs.Success`, `outputs.SuccessNet` now accept `*paths.Path` - `pipeline.Settings` carries `Paths` and forwards it to `queueFactoryForUserConfig` - All 8 output factory implementations (console, discard, elasticsearch, file, kafka, logstash, redis, otelconsumer) updated to accept and forward paths - `dockerlogbeat` updated to pass `paths.New()` explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used in `dockerlogbeat`. - `pipeline/stress` test harness updated to use `LoadWithSettings` with paths When `Settings.Path` is explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beat `Paths.Resolve()` instead of the global `paths.Resolve()`. ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - ~~I have made corresponding changes to the documentation~~ - ~~I have made corresponding change to the default configuration files~~ - [x] I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the [`stresstest.sh`](https://github.com/elastic/beats/blob/main/script/stresstest.sh) script to run them under stress conditions and race detector to verify their stability. - ~~I have added an entry in `./changelog/fragments` using the [changelog tool](https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md).~~ ## Disruptive User Impact None. In the standalone beat flow, `b.Paths` and `paths.Paths` point to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance. ## How to test this PR locally ### Standalone filebeat ```yaml # filebeat-diskqueue-test.yml path.home: /tmp/diskqueue-test/standalone path.data: /tmp/diskqueue-test/standalone/data filebeat.inputs: - type: filestream id: test-input enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ queue.disk: max_size: 100MB output.console: pretty: true ``` ```bash cd filebeat && mage build echo '{"message": "hello"}' > /tmp/diskqueue-test/input.log ./filebeat -e -c /path/to/filebeat-diskqueue-test.yml # Verify: diskqueue created under path.data ls -la /tmp/diskqueue-test/standalone/data/diskqueue/ # Should contain: state.dat (and .seg files once events flow) ``` ### `elastic-agent otel` Create `/tmp/diskqueue-test/otel-receivers.yml`: ```yaml receivers: filebeatreceiver/a: filebeat: inputs: - type: filestream id: stream-a enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-a queue.disk: max_size: 100MB filebeatreceiver/b: filebeat: inputs: - type: filestream id: stream-b enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-b queue.disk: max_size: 100MB exporters: debug: verbosity: detailed service: pipelines: logs: receivers: [filebeatreceiver/a, filebeatreceiver/b] exporters: [debug] telemetry: metrics: level: none ``` Run: ```bash elastic-agent otel --config /tmp/diskqueue-test/otel-receivers.yml ``` Verify: ```bash find /tmp/diskqueue-test/receiver-a -name state.dat # Expected: /tmp/diskqueue-test/receiver-a/data/diskqueue/state.dat find /tmp/diskqueue-test/receiver-b -name state.dat # Expected: /tmp/diskqueue-test/receiver-b/data/diskqueue/state.dat ``` ## Related issues - Closes #46989 (cherry picked from commit 979f9b4) # Conflicts: # libbeat/outputs/logstash/logstash.go # x-pack/otel/exporter/logstashexporter/exporter.go
fix(diskqueue): use per-beat paths instead of global paths Add a `Paths` field to diskqueue `Settings` so each beat receiver gets its own data directory for the disk queue. Thread the per-beat `*paths.Path` through the pipeline and output factory APIs: - `outputs.Factory`, `outputs.Load`, `outputs.Success`, `outputs.SuccessNet` now accept `*paths.Path` - `pipeline.Settings` carries `Paths` and forwards it to `queueFactoryForUserConfig` - All 8 output factory implementations (console, discard, elasticsearch, file, kafka, logstash, redis, otelconsumer) updated to accept and forward paths - `dockerlogbeat` updated to pass `paths.New()` explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used in `dockerlogbeat`. - `pipeline/stress` test harness updated to use `LoadWithSettings` with paths When `Settings.Path` is explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beat `Paths.Resolve()` instead of the global `paths.Resolve()`. ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - ~~I have made corresponding changes to the documentation~~ - ~~I have made corresponding change to the default configuration files~~ - [x] I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the [`stresstest.sh`](https://github.com/elastic/beats/blob/main/script/stresstest.sh) script to run them under stress conditions and race detector to verify their stability. - ~~I have added an entry in `./changelog/fragments` using the [changelog tool](https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md).~~ ## Disruptive User Impact None. In the standalone beat flow, `b.Paths` and `paths.Paths` point to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance. ## How to test this PR locally ### Standalone filebeat ```yaml # filebeat-diskqueue-test.yml path.home: /tmp/diskqueue-test/standalone path.data: /tmp/diskqueue-test/standalone/data filebeat.inputs: - type: filestream id: test-input enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ queue.disk: max_size: 100MB output.console: pretty: true ``` ```bash cd filebeat && mage build echo '{"message": "hello"}' > /tmp/diskqueue-test/input.log ./filebeat -e -c /path/to/filebeat-diskqueue-test.yml # Verify: diskqueue created under path.data ls -la /tmp/diskqueue-test/standalone/data/diskqueue/ # Should contain: state.dat (and .seg files once events flow) ``` ### `elastic-agent otel` Create `/tmp/diskqueue-test/otel-receivers.yml`: ```yaml receivers: filebeatreceiver/a: filebeat: inputs: - type: filestream id: stream-a enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-a queue.disk: max_size: 100MB filebeatreceiver/b: filebeat: inputs: - type: filestream id: stream-b enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-b queue.disk: max_size: 100MB exporters: debug: verbosity: detailed service: pipelines: logs: receivers: [filebeatreceiver/a, filebeatreceiver/b] exporters: [debug] telemetry: metrics: level: none ``` Run: ```bash elastic-agent otel --config /tmp/diskqueue-test/otel-receivers.yml ``` Verify: ```bash find /tmp/diskqueue-test/receiver-a -name state.dat # Expected: /tmp/diskqueue-test/receiver-a/data/diskqueue/state.dat find /tmp/diskqueue-test/receiver-b -name state.dat # Expected: /tmp/diskqueue-test/receiver-b/data/diskqueue/state.dat ``` ## Related issues - Closes #46989 (cherry picked from commit 979f9b4)
fix(diskqueue): use per-beat paths instead of global paths Add a `Paths` field to diskqueue `Settings` so each beat receiver gets its own data directory for the disk queue. Thread the per-beat `*paths.Path` through the pipeline and output factory APIs: - `outputs.Factory`, `outputs.Load`, `outputs.Success`, `outputs.SuccessNet` now accept `*paths.Path` - `pipeline.Settings` carries `Paths` and forwards it to `queueFactoryForUserConfig` - All 8 output factory implementations (console, discard, elasticsearch, file, kafka, logstash, redis, otelconsumer) updated to accept and forward paths - `dockerlogbeat` updated to pass `paths.New()` explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used in `dockerlogbeat`. - `pipeline/stress` test harness updated to use `LoadWithSettings` with paths When `Settings.Path` is explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beat `Paths.Resolve()` instead of the global `paths.Resolve()`. ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - ~~I have made corresponding changes to the documentation~~ - ~~I have made corresponding change to the default configuration files~~ - [x] I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the [`stresstest.sh`](https://github.com/elastic/beats/blob/main/script/stresstest.sh) script to run them under stress conditions and race detector to verify their stability. - ~~I have added an entry in `./changelog/fragments` using the [changelog tool](https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md).~~ ## Disruptive User Impact None. In the standalone beat flow, `b.Paths` and `paths.Paths` point to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance. ## How to test this PR locally ### Standalone filebeat ```yaml # filebeat-diskqueue-test.yml path.home: /tmp/diskqueue-test/standalone path.data: /tmp/diskqueue-test/standalone/data filebeat.inputs: - type: filestream id: test-input enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ queue.disk: max_size: 100MB output.console: pretty: true ``` ```bash cd filebeat && mage build echo '{"message": "hello"}' > /tmp/diskqueue-test/input.log ./filebeat -e -c /path/to/filebeat-diskqueue-test.yml # Verify: diskqueue created under path.data ls -la /tmp/diskqueue-test/standalone/data/diskqueue/ # Should contain: state.dat (and .seg files once events flow) ``` ### `elastic-agent otel` Create `/tmp/diskqueue-test/otel-receivers.yml`: ```yaml receivers: filebeatreceiver/a: filebeat: inputs: - type: filestream id: stream-a enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-a queue.disk: max_size: 100MB filebeatreceiver/b: filebeat: inputs: - type: filestream id: stream-b enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-b queue.disk: max_size: 100MB exporters: debug: verbosity: detailed service: pipelines: logs: receivers: [filebeatreceiver/a, filebeatreceiver/b] exporters: [debug] telemetry: metrics: level: none ``` Run: ```bash elastic-agent otel --config /tmp/diskqueue-test/otel-receivers.yml ``` Verify: ```bash find /tmp/diskqueue-test/receiver-a -name state.dat # Expected: /tmp/diskqueue-test/receiver-a/data/diskqueue/state.dat find /tmp/diskqueue-test/receiver-b -name state.dat # Expected: /tmp/diskqueue-test/receiver-b/data/diskqueue/state.dat ``` ## Related issues - Closes #46989 (cherry picked from commit 979f9b4)
…49276) fix(diskqueue): use per-beat paths instead of global paths Add a `Paths` field to diskqueue `Settings` so each beat receiver gets its own data directory for the disk queue. Thread the per-beat `*paths.Path` through the pipeline and output factory APIs: - `outputs.Factory`, `outputs.Load`, `outputs.Success`, `outputs.SuccessNet` now accept `*paths.Path` - `pipeline.Settings` carries `Paths` and forwards it to `queueFactoryForUserConfig` - All 8 output factory implementations (console, discard, elasticsearch, file, kafka, logstash, redis, otelconsumer) updated to accept and forward paths - `dockerlogbeat` updated to pass `paths.New()` explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used in `dockerlogbeat`. - `pipeline/stress` test harness updated to use `LoadWithSettings` with paths When `Settings.Path` is explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beat `Paths.Resolve()` instead of the global `paths.Resolve()`. ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - ~~I have made corresponding changes to the documentation~~ - ~~I have made corresponding change to the default configuration files~~ - [x] I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the [`stresstest.sh`](https://github.com/elastic/beats/blob/main/script/stresstest.sh) script to run them under stress conditions and race detector to verify their stability. - ~~I have added an entry in `./changelog/fragments` using the [changelog tool](https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md).~~ ## Disruptive User Impact None. In the standalone beat flow, `b.Paths` and `paths.Paths` point to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance. ## How to test this PR locally ### Standalone filebeat ```yaml # filebeat-diskqueue-test.yml path.home: /tmp/diskqueue-test/standalone path.data: /tmp/diskqueue-test/standalone/data filebeat.inputs: - type: filestream id: test-input enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ queue.disk: max_size: 100MB output.console: pretty: true ``` ```bash cd filebeat && mage build echo '{"message": "hello"}' > /tmp/diskqueue-test/input.log ./filebeat -e -c /path/to/filebeat-diskqueue-test.yml # Verify: diskqueue created under path.data ls -la /tmp/diskqueue-test/standalone/data/diskqueue/ # Should contain: state.dat (and .seg files once events flow) ``` ### `elastic-agent otel` Create `/tmp/diskqueue-test/otel-receivers.yml`: ```yaml receivers: filebeatreceiver/a: filebeat: inputs: - type: filestream id: stream-a enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-a queue.disk: max_size: 100MB filebeatreceiver/b: filebeat: inputs: - type: filestream id: stream-b enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-b queue.disk: max_size: 100MB exporters: debug: verbosity: detailed service: pipelines: logs: receivers: [filebeatreceiver/a, filebeatreceiver/b] exporters: [debug] telemetry: metrics: level: none ``` Run: ```bash elastic-agent otel --config /tmp/diskqueue-test/otel-receivers.yml ``` Verify: ```bash find /tmp/diskqueue-test/receiver-a -name state.dat # Expected: /tmp/diskqueue-test/receiver-a/data/diskqueue/state.dat find /tmp/diskqueue-test/receiver-b -name state.dat # Expected: /tmp/diskqueue-test/receiver-b/data/diskqueue/state.dat ``` ## Related issues - Closes #46989 (cherry picked from commit 979f9b4) Co-authored-by: Orestis Floros <orestis.floros@elastic.co>
…49275) fix(diskqueue): use per-beat paths instead of global paths Add a `Paths` field to diskqueue `Settings` so each beat receiver gets its own data directory for the disk queue. Thread the per-beat `*paths.Path` through the pipeline and output factory APIs: - `outputs.Factory`, `outputs.Load`, `outputs.Success`, `outputs.SuccessNet` now accept `*paths.Path` - `pipeline.Settings` carries `Paths` and forwards it to `queueFactoryForUserConfig` - All 8 output factory implementations (console, discard, elasticsearch, file, kafka, logstash, redis, otelconsumer) updated to accept and forward paths - `dockerlogbeat` updated to pass `paths.New()` explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used in `dockerlogbeat`. - `pipeline/stress` test harness updated to use `LoadWithSettings` with paths When `Settings.Path` is explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beat `Paths.Resolve()` instead of the global `paths.Resolve()`. ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - ~~I have made corresponding changes to the documentation~~ - ~~I have made corresponding change to the default configuration files~~ - [x] I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the [`stresstest.sh`](https://github.com/elastic/beats/blob/main/script/stresstest.sh) script to run them under stress conditions and race detector to verify their stability. - ~~I have added an entry in `./changelog/fragments` using the [changelog tool](https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md).~~ ## Disruptive User Impact None. In the standalone beat flow, `b.Paths` and `paths.Paths` point to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance. ## How to test this PR locally ### Standalone filebeat ```yaml # filebeat-diskqueue-test.yml path.home: /tmp/diskqueue-test/standalone path.data: /tmp/diskqueue-test/standalone/data filebeat.inputs: - type: filestream id: test-input enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ queue.disk: max_size: 100MB output.console: pretty: true ``` ```bash cd filebeat && mage build echo '{"message": "hello"}' > /tmp/diskqueue-test/input.log ./filebeat -e -c /path/to/filebeat-diskqueue-test.yml # Verify: diskqueue created under path.data ls -la /tmp/diskqueue-test/standalone/data/diskqueue/ # Should contain: state.dat (and .seg files once events flow) ``` ### `elastic-agent otel` Create `/tmp/diskqueue-test/otel-receivers.yml`: ```yaml receivers: filebeatreceiver/a: filebeat: inputs: - type: filestream id: stream-a enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-a queue.disk: max_size: 100MB filebeatreceiver/b: filebeat: inputs: - type: filestream id: stream-b enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-b queue.disk: max_size: 100MB exporters: debug: verbosity: detailed service: pipelines: logs: receivers: [filebeatreceiver/a, filebeatreceiver/b] exporters: [debug] telemetry: metrics: level: none ``` Run: ```bash elastic-agent otel --config /tmp/diskqueue-test/otel-receivers.yml ``` Verify: ```bash find /tmp/diskqueue-test/receiver-a -name state.dat # Expected: /tmp/diskqueue-test/receiver-a/data/diskqueue/state.dat find /tmp/diskqueue-test/receiver-b -name state.dat # Expected: /tmp/diskqueue-test/receiver-b/data/diskqueue/state.dat ``` ## Related issues - Closes #46989 (cherry picked from commit 979f9b4) Co-authored-by: Orestis Floros <orestis.floros@elastic.co>
Resolve cherry-pick conflicts from #48834 backport to 8.19: - logstash.go: keep 8.19 code structure (no MakeLogstashClients refactoring), add paths import and pass beatPaths to SuccessNet - exporter.go: remove file that doesn't exist on 8.19 (the logstashexporter package is a main-branch feature)
… global paths (#49274) * fix(diskqueue): use per-beat paths instead of global paths (#48834) fix(diskqueue): use per-beat paths instead of global paths Add a `Paths` field to diskqueue `Settings` so each beat receiver gets its own data directory for the disk queue. Thread the per-beat `*paths.Path` through the pipeline and output factory APIs: - `outputs.Factory`, `outputs.Load`, `outputs.Success`, `outputs.SuccessNet` now accept `*paths.Path` - `pipeline.Settings` carries `Paths` and forwards it to `queueFactoryForUserConfig` - All 8 output factory implementations (console, discard, elasticsearch, file, kafka, logstash, redis, otelconsumer) updated to accept and forward paths - `dockerlogbeat` updated to pass `paths.New()` explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used in `dockerlogbeat`. - `pipeline/stress` test harness updated to use `LoadWithSettings` with paths When `Settings.Path` is explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beat `Paths.Resolve()` instead of the global `paths.Resolve()`. ## Checklist - [x] My code follows the style guidelines of this project - [x] I have commented my code, particularly in hard-to-understand areas - ~~I have made corresponding changes to the documentation~~ - ~~I have made corresponding change to the default configuration files~~ - [x] I have added tests that prove my fix is effective or that my feature works. Where relevant, I have used the [`stresstest.sh`](https://github.com/elastic/beats/blob/main/script/stresstest.sh) script to run them under stress conditions and race detector to verify their stability. - ~~I have added an entry in `./changelog/fragments` using the [changelog tool](https://github.com/elastic/elastic-agent-changelog-tool/blob/main/docs/usage.md).~~ ## Disruptive User Impact None. In the standalone beat flow, `b.Paths` and `paths.Paths` point to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance. ## How to test this PR locally ### Standalone filebeat ```yaml # filebeat-diskqueue-test.yml path.home: /tmp/diskqueue-test/standalone path.data: /tmp/diskqueue-test/standalone/data filebeat.inputs: - type: filestream id: test-input enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ queue.disk: max_size: 100MB output.console: pretty: true ``` ```bash cd filebeat && mage build echo '{"message": "hello"}' > /tmp/diskqueue-test/input.log ./filebeat -e -c /path/to/filebeat-diskqueue-test.yml # Verify: diskqueue created under path.data ls -la /tmp/diskqueue-test/standalone/data/diskqueue/ # Should contain: state.dat (and .seg files once events flow) ``` ### `elastic-agent otel` Create `/tmp/diskqueue-test/otel-receivers.yml`: ```yaml receivers: filebeatreceiver/a: filebeat: inputs: - type: filestream id: stream-a enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-a queue.disk: max_size: 100MB filebeatreceiver/b: filebeat: inputs: - type: filestream id: stream-b enabled: true paths: - /tmp/diskqueue-test/input.log prospector.scanner.fingerprint.enabled: false file_identity.native: ~ path.home: /tmp/diskqueue-test/receiver-b queue.disk: max_size: 100MB exporters: debug: verbosity: detailed service: pipelines: logs: receivers: [filebeatreceiver/a, filebeatreceiver/b] exporters: [debug] telemetry: metrics: level: none ``` Run: ```bash elastic-agent otel --config /tmp/diskqueue-test/otel-receivers.yml ``` Verify: ```bash find /tmp/diskqueue-test/receiver-a -name state.dat # Expected: /tmp/diskqueue-test/receiver-a/data/diskqueue/state.dat find /tmp/diskqueue-test/receiver-b -name state.dat # Expected: /tmp/diskqueue-test/receiver-b/data/diskqueue/state.dat ``` ## Related issues - Closes #46989 (cherry picked from commit 979f9b4) # Conflicts: # libbeat/outputs/logstash/logstash.go # x-pack/otel/exporter/logstashexporter/exporter.go * fix: resolve backport merge conflicts for diskqueue paths PR Resolve cherry-pick conflicts from #48834 backport to 8.19: - logstash.go: keep 8.19 code structure (no MakeLogstashClients refactoring), add paths import and pass beatPaths to SuccessNet - exporter.go: remove file that doesn't exist on 8.19 (the logstashexporter package is a main-branch feature) --------- Co-authored-by: Orestis Floros <orestis.floros@elastic.co>
Proposed commit message
fix(diskqueue): use per-beat paths instead of global paths
Add a
Pathsfield to diskqueueSettingsso each beat receiver gets its own data directory for the disk queue. Thread the per-beat*paths.Paththrough the pipeline and output factory APIs:outputs.Factory,outputs.Load,outputs.Success,outputs.SuccessNetnow accept*paths.Pathpipeline.SettingscarriesPathsand forwards it toqueueFactoryForUserConfigdockerlogbeatupdated to passpaths.New()explicitly. This is making explicit the previously implied behavior: the global paths were never initialized or used indockerlogbeat.pipeline/stresstest harness updated to useLoadWithSettingswith pathsWhen
Settings.Pathis explicitly configured, it still takes precedence (backward compatible). When empty, the diskqueue directory is resolved via the per-beatPaths.Resolve()instead of the globalpaths.Resolve().Checklist
I have made corresponding changes to the documentationI have made corresponding change to the default configuration filesstresstest.shscript to run them under stress conditions and race detector to verify their stability.I have added an entry in./changelog/fragmentsusing the changelog tool.Disruptive User Impact
None. In the standalone beat flow,
b.Pathsandpaths.Pathspoint to the same object, so behavior is identical. The change only corrects behavior for beat receivers, where each receiver gets its own paths instance.How to test this PR locally
Standalone filebeat
elastic-agent otelCreate
/tmp/diskqueue-test/otel-receivers.yml:Run:
Verify:
Related issues