Fix journald input for journalctl versions < 242 by omitting --boot all#49445
Fix journald input for journalctl versions < 242 by omitting --boot all#49445belimawr merged 35 commits intoelastic:mainfrom
--boot all#49445Conversation
- Set timezone to match host - Add systemd 242 - use absolute path for journald.conf
🤖 GitHub commentsJust comment with:
|
philippkahr
left a comment
There was a problem hiding this comment.
LGTM! can't. comment on the code really. Functionality looks like exactly what we need :)
|
@belimawr I think you missed to link the follow-up PR |
|
You could make the vagrant machines to install go and mage during their creation. They're meant to test filebeat anyway |
I linked the branch with the changes. Because both branches are in my fork, I cannot open a PR on this repo and a merge commit was making the diff to list more changes than only my commit. So to keep things simple I just linked the branch. I'll use it to create a PR as soon as this one is merged. |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
filebeat/input/journald/input.go (1)
381-382:⚠️ Potential issue | 🔴 CriticalThe
nolintis masking a real timestamp overflow.Line 382 still narrows
data.RealtimeTimestampfromuint64toint64beforetime.UnixMicro. If that value exceedsmath.MaxInt64, the timestamp wraps to a bogus value; suppressinggosecdoes not make the conversion safe.#!/bin/bash rg -n -C2 'RealtimeTimestamp|UnixMicro|nolint:gosec' filebeat/input/journald/input.go🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@filebeat/input/journald/input.go` around lines 381 - 382, The code narrows data.RealtimeTimestamp (uint64) to int64 for time.UnixMicro which can overflow; remove the nolint and instead check and handle the range before converting: compute secs := data.RealtimeTimestamp / 1_000_000 and use nsec := (data.RealtimeTimestamp % 1_000_000) * 1_000, ensure secs fits in int64 (compare against uint64(math.MaxInt64)); if it overflows clamp or handle as appropriate, then call time.Unix(int64(secs), int64(nsec)) to build the timestamp without unsafe uint64->int64 narrowing (update the code around the time.UnixMicro usage that references data.RealtimeTimestamp).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@filebeat/tests/integration/journald_test.go`:
- Around line 218-223: The test currently derives expectedMessages from
oldestBoot and secondOldestBoot but only asserts that the first N events contain
two distinct boot IDs, which can pass without including those specific boots;
change the assertions to explicitly check that bootIDs (the set/list extracted
from the consumed events) contains oldestBoot.BootID and secondOldestBoot.BootID
(in addition to existing distinctness checks). Locate where oldestBoot and
secondOldestBoot are used to build expectedMessages and where bootIDs is
asserted (around the countBootEntries call and the subsequent event assertions)
and add two explicit contains assertions for oldestBoot.BootID and
secondOldestBoot.BootID; apply the same explicit-contains fixes to the analogous
assertions in the block spanning lines 237-263.
---
Duplicate comments:
In `@filebeat/input/journald/input.go`:
- Around line 381-382: The code narrows data.RealtimeTimestamp (uint64) to int64
for time.UnixMicro which can overflow; remove the nolint and instead check and
handle the range before converting: compute secs := data.RealtimeTimestamp /
1_000_000 and use nsec := (data.RealtimeTimestamp % 1_000_000) * 1_000, ensure
secs fits in int64 (compare against uint64(math.MaxInt64)); if it overflows
clamp or handle as appropriate, then call time.Unix(int64(secs), int64(nsec)) to
build the timestamp without unsafe uint64->int64 narrowing (update the code
around the time.UnixMicro usage that references data.RealtimeTimestamp).
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c2a87096-c5b6-4726-9f22-7660ab2733d7
📒 Files selected for processing (6)
changelog/fragments/1772726727-fix-journald-args.yamlfilebeat/input/journald/README.mdfilebeat/input/journald/Vagrantfilefilebeat/input/journald/input.gofilebeat/input/journald/pkg/journalctl/reader_test.gofilebeat/tests/integration/journald_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
- filebeat/input/journald/Vagrantfile
- changelog/fragments/1772726727-fix-journald-args.yaml
- filebeat/input/journald/pkg/journalctl/reader_test.go
|
@Mergifyio backport 8.19 9.2 9.3 |
✅ Backports have been createdDetails
Cherry-pick of f6662a9 has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally
Cherry-pick of f6662a9 has failed: To fix up this pull request, you can check it out locally. See documentation: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/reviewing-changes-in-pull-requests/checking-out-pull-requests-locally
|
…all` (#49445) journalctl versions < 242 do not support the `--boot all` flag that newer versions require to read all boot messages, this commit fixes this problem by omitting the flag because versins < 242 returns messages from all boots without the need to set `--boot all` The journal files used for tests are updated making them compatible with journalctl >= 239. The integration test TestJournaldInputReadsMessagesFromAllBoots is added to ensure the journald input can always read messages form all boots. This test is intended to be run manually on VMs where the journal has less than 50 000 messages. Some fixes to the life-cycle of `journalctl` are implemented because they were required for the tests to be stable. GenAI-Assisted: Yes Human-Reviewed: Yes Tool: Cursor-CLI, Model: GPT-5.3 Codex Extra High Fast Tool: Cursor-CLI, Model: Claude 4.6 Opus (Thinking) --------- Co-authored-by: Philipp Kahr <philipp.kahr@elastic.co> (cherry picked from commit f6662a9) # Conflicts: # filebeat/input/journald/pkg/journalctl/journalctl.go # filebeat/input/journald/pkg/journalctl/reader_test.go
…all` (#49445) journalctl versions < 242 do not support the `--boot all` flag that newer versions require to read all boot messages, this commit fixes this problem by omitting the flag because versins < 242 returns messages from all boots without the need to set `--boot all` The journal files used for tests are updated making them compatible with journalctl >= 239. The integration test TestJournaldInputReadsMessagesFromAllBoots is added to ensure the journald input can always read messages form all boots. This test is intended to be run manually on VMs where the journal has less than 50 000 messages. Some fixes to the life-cycle of `journalctl` are implemented because they were required for the tests to be stable. GenAI-Assisted: Yes Human-Reviewed: Yes Tool: Cursor-CLI, Model: GPT-5.3 Codex Extra High Fast Tool: Cursor-CLI, Model: Claude 4.6 Opus (Thinking) --------- Co-authored-by: Philipp Kahr <philipp.kahr@elastic.co> (cherry picked from commit f6662a9) # Conflicts: # filebeat/input/journald/pkg/journalctl/journalctl.go # filebeat/input/journald/pkg/journalctl/reader_test.go
…all` (#49445) journalctl versions < 242 do not support the `--boot all` flag that newer versions require to read all boot messages, this commit fixes this problem by omitting the flag because versins < 242 returns messages from all boots without the need to set `--boot all` The journal files used for tests are updated making them compatible with journalctl >= 239. The integration test TestJournaldInputReadsMessagesFromAllBoots is added to ensure the journald input can always read messages form all boots. This test is intended to be run manually on VMs where the journal has less than 50 000 messages. Some fixes to the life-cycle of `journalctl` are implemented because they were required for the tests to be stable. GenAI-Assisted: Yes Human-Reviewed: Yes Tool: Cursor-CLI, Model: GPT-5.3 Codex Extra High Fast Tool: Cursor-CLI, Model: Claude 4.6 Opus (Thinking) --------- Co-authored-by: Philipp Kahr <philipp.kahr@elastic.co> (cherry picked from commit f6662a9)
Resolve failed backport conflicts for the journald `--boot all` compatibility fix while keeping the `9.2` API and behavior intact. Preserve support for journalctl < 242 and apply process lifecycle/test fixes without introducing `main`-only features. GenAI-Assisted: Yes Human-Reviewed: Yes Tool: Cursor-CLI, Model: GPT-5.3 Codex High
…all` (#49445) (#49527) journalctl versions < 242 do not support the `--boot all` flag that newer versions require to read all boot messages, this commit fixes this problem by omitting the flag because versins < 242 returns messages from all boots without the need to set `--boot all` The journal files used for tests are updated making them compatible with journalctl >= 239. The integration test TestJournaldInputReadsMessagesFromAllBoots is added to ensure the journald input can always read messages form all boots. This test is intended to be run manually on VMs where the journal has less than 50 000 messages. Some fixes to the life-cycle of `journalctl` are implemented because they were required for the tests to be stable. GenAI-Assisted: Yes Human-Reviewed: Yes Tool: Cursor-CLI, Model: GPT-5.3 Codex Extra High Fast Tool: Cursor-CLI, Model: Claude 4.6 Opus (Thinking) --------- (cherry picked from commit f6662a9) Co-authored-by: Tiago Queiroz <tiago.queiroz@elastic.co> Co-authored-by: Philipp Kahr <philipp.kahr@elastic.co>
Proposed commit message
Note for reviewers
There are still some small issues with the process management in
filebeat/input/journald/pkg/journalctl/journalctl.go, I'll fix them in a follow up PR (based on this PR and linked here). This PR has grown too large already to include other fixes.The only fixes unrelated to the original issue I included here are the ones that caused failures on CI or during my tests.
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../changelog/fragmentsusing the changelog tool.## Disruptive User ImpactAuthor's Checklist
How to test this PR locally
1) Run existing tests (unit + integration)
These cover the new
journalctlargument behavior by version.2) Use the provided VMs to test different versions of
journalctlVAGRANT_VAGRANTFILEmakes Vagrant always usefilebeat/input/journald/Vagrantfile.VAGRANT_CWDdefines where Vagrant will save its state and which folder to use for relative pathsBring up VM matrix and verify versions
vagrant up 239 250 # or any other version/VM you want to test vagrant statusManually validate the new all-boots integration test
TestJournaldInputReadsMessagesFromAllBootsis intentionally skipped bydefault, you'll need to export
JOURNALD_MANUAL_TEST=1for the testto run.
Inside one of the VMs (recommended:
239and250):Expected:
journald.host.boot_idvalues.If there is only one boot, create another boot (
sudo reboot), reconnect, andrun again.
3) Manual test
Run Filebeat with the following configuration:
Details
Look for the log entries with message:
Journalctl command. Paths relative to chroot (if set). They will contain a fieldprocess.command_linewith the wholejournalctlcommand.You can use the following command to filter the logs and format them with
jq:You should see logs like:
{ "log.level": "info", "@timestamp": "2026-03-12T13:14:25.465-0400", "log.logger": "input.journald.reader", "log.origin": { "function": "github.com/elastic/beats/v7/filebeat/input/journald.(*journald).Run.NewFactory.func1", "file.name": "journalctl/journalctl.go", "file.line": 86 }, "message": "Journalctl command. Paths relative to chroot (if set)", "service.name": "filebeat", "id": "test--boot-all", "input_source": "LOCAL_SYSTEM_JOURNAL", "path": "LOCAL_SYSTEM_JOURNAL", "input_id": "test--boot-all", "process.command_line": "journalctl --version", "process.chroot": "", "ecs.version": "1.6.0" } { "log.level": "info", "@timestamp": "2026-03-12T13:14:25.467-0400", "log.logger": "input.journald.reader.journalctl-runner", "log.origin": { "function": "github.com/elastic/beats/v7/filebeat/input/journald.(*journald).Run.NewFactory.func1", "file.name": "journalctl/journalctl.go", "file.line": 86 }, "message": "Journalctl command. Paths relative to chroot (if set)", "service.name": "filebeat", "id": "test--boot-all", "input_source": "LOCAL_SYSTEM_JOURNAL", "path": "LOCAL_SYSTEM_JOURNAL", "input_id": "test--boot-all", "process.command_line": "journalctl --utc --output=json --no-pager --all --follow --after-cursor s=e82795fad4ce42b79fb3da0866d91f7e;i=15502a0;b=e224754c921445279ded5949d3a0dfc9;m=1820a8d806;t=64a18fd40f98c;x=a138e845a98ffe14 --boot all", "process.chroot": "", "ecs.version": "1.6.0" }Related issues
v242#48152--boot all. #49413## Use cases## Screenshots## Logs