Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace github.com/coreos/go-systemd/v22/sdjournal by journalctl #40061

Merged
merged 61 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
999f954
[WIP] Reading journal file with journalctl
belimawr Jun 26, 2024
f224875
Add test to ensure events are in the same format
belimawr Jun 26, 2024
a6128bd
Commit new reader
belimawr Jun 26, 2024
bb62b30
Improve tests
belimawr Jun 26, 2024
c55ce4d
Set missing fields
belimawr Jun 26, 2024
4361ee1
Add journal to test matchers
belimawr Jun 26, 2024
5d70aaf
Add test for matchers
belimawr Jun 27, 2024
1ca3aa0
Add fork/exec syscalls
belimawr Jun 28, 2024
c17b406
Add cursor and since support
belimawr Jun 28, 2024
3a51434
fix seek options
belimawr Jun 28, 2024
ebfd5fb
remove withjournald build tag
belimawr Jun 28, 2024
0fa3f8f
Add Debian 11 and 12 in the Vagrant file
belimawr Jun 28, 2024
5ca2067
fix reference
belimawr Jun 28, 2024
7cef9e7
Add units, identifiers and small refactoring
belimawr Jun 28, 2024
69073fb
Remove `journalread` and simplify seek mode
belimawr Jun 28, 2024
1e29fec
Remove references to `github.com/coreos/go-systemd/v22/sdjournal`
belimawr Jun 28, 2024
2b1da61
fix constants
belimawr Jun 28, 2024
54fa0f0
comment out failing tests
belimawr Jun 28, 2024
7d1ab6f
Fix seek/cursor tests
belimawr Jul 1, 2024
4995848
Disable include_matches AND and OR conditions
belimawr Jul 1, 2024
d6cca1b
Update matchers documentation and add tests
belimawr Jul 1, 2024
b46433a
filter and test by transport, unit and facility
belimawr Jul 1, 2024
85a01c8
remove un-used fields from config
belimawr Jul 1, 2024
876be54
remove un-used config options
belimawr Jul 1, 2024
19ab55e
update 7.x compatibility and tests
belimawr Jul 2, 2024
42f5d83
Address lint Waring's
belimawr Jul 2, 2024
763d9fe
Refactor/clean up code
belimawr Jul 2, 2024
3e51599
Add changelog
belimawr Jul 2, 2024
842e20d
Update reference files
belimawr Jul 2, 2024
7372e99
Unblocks `Next` if cancel is cancelled and add documentation
belimawr Jul 2, 2024
d3782d1
Gracefully terminate input and use map[string]any for events
belimawr Jul 3, 2024
728b0b7
Add tests for reading entries with non-string data
belimawr Jul 3, 2024
e1f8f08
Handle case where the message is not a string
belimawr Jul 3, 2024
253db5d
Improve documentation
belimawr Jul 3, 2024
409ba3e
update changelog
belimawr Jul 3, 2024
be0c064
format/update files
belimawr Jul 3, 2024
2cff54c
Better log errors
belimawr Jul 3, 2024
a1eb4b0
Implement review suggestions
belimawr Jul 8, 2024
1638e3c
Fix error handling when journalctl
belimawr Jul 8, 2024
a220b9b
Add mention about journalctl to the documentation
belimawr Jul 8, 2024
af93cbb
fix type mismatch in test
belimawr Jul 8, 2024
15536f6
Fix issue with timestamp comparison on tests.
belimawr Jul 8, 2024
dc3a251
Improve seek since times to avoid issues on different hosts
belimawr Jul 9, 2024
3b99814
Add build tags to mock file
belimawr Jul 9, 2024
6b74934
Add debug logs to tests
belimawr Jul 9, 2024
4781a27
Fix race condition on Close
belimawr Jul 10, 2024
7cc87f2
fix broken since timestamp
belimawr Jul 10, 2024
02ed4b6
Add Ubuntu 2204 to Vagrant
belimawr Jul 10, 2024
7e4325f
Fix failing tests due to journal format
belimawr Jul 10, 2024
5206107
Improve docs and fix typos
belimawr Jul 10, 2024
146d285
Add log stating it can take a while to shutdown journald
belimawr Jul 12, 2024
284f7b1
Add syscalls required to call journalctl
belimawr Aug 7, 2024
4caef50
Run seccomp tests on Aarch64
belimawr Aug 7, 2024
e1e783b
Merge branch 'main' into journalctl-for-journald-input
pierrehilbert Aug 8, 2024
e8ed98b
Merge branch 'main' into journalctl-for-journald-input
pierrehilbert Aug 8, 2024
1f58c7e
Update changelog
belimawr Aug 8, 2024
6572cb9
Merge branch 'journalctl-for-journald-input' of github.com:belimawr/b…
belimawr Aug 8, 2024
35a5d8c
Update changelog
belimawr Aug 8, 2024
acbe1d8
Re-add removed syscall from seccomp
belimawr Aug 8, 2024
ec6fc35
Removed duplicated syscall from seccomp default policy
belimawr Aug 8, 2024
1359a65
Fix log entry
belimawr Aug 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG-developer.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ The list below covers the major changes between 7.0.0-rc2 and main only.
- Beats publishing pipeline does not propagate the close signal to its clients any more. It's responsibility of the user to close the pipeline client. {issue}38197[38197] {pull}38556[38556]
- Debug log entries from the acker (`stateful ack ...` or `stateless ack ...`) removed. {pull}39672[39672]
- Rename x-pack/filebeat websocket input to streaming. {issue}40264[40264] {pull}40421[40421]
- Journald input now calls `journalctl` instead of using `github.com/coreos/go-systemd/[email protected]/sdjournal`, the CGO dependency has been removed from Filebeat {pull}40061[40061]
cmacknz marked this conversation as resolved.
Show resolved Hide resolved

==== Bugfixes

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.next.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
- Update Go version to 1.22.5. {pull}40082[40082]
- Fix FQDN being lowercased when used as `host.hostname` {issue}39993[39993]
- Beats won't log start up information when running under the Elastic Agent {40390}40390[40390]
- Filebeat now needs `dup3`, `faccessat2`, `prctl` and `setrlimit` syscalls to run the journald input. If this input is not being used, the syscalls are not needed. All Beats have those syscalls allowed now because the default seccomp policy is global to all Beats. {pull}40061[40061]

*Auditbeat*

Expand Down Expand Up @@ -53,6 +54,9 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
- Implement Elastic Agent status and health reporting for Winlog Filebeat input. {pull}40163[40163]
- Fix filestream's registry GC: registry entries will never be removed if clean_inactive is set to "-1". {pull}40258[40258]
- Added `ignore_empty_values` flag in `decode_cef` Filebeat processor. {pull}40268[40268]
- Journald: removed configuration options `include_matches.or`, `include_matches.and`, `backoff`, `max_backoff`, `cursor_seek_fallback`. {pull}40061[40061]
belimawr marked this conversation as resolved.
Show resolved Hide resolved
- Journald: `include_matches.match` now behaves in the same way as matchers in `journalctl`. Users should carefully update their input configuration. {pull}40061[40061]
- Journald: `seek` and `since` behaviour have been simplified, if there is a cursor (state) `seek` and `since` are ignored and the cursor is used. {pull}40061[40061]

*Heartbeat*

Expand Down Expand Up @@ -166,6 +170,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff]
- Fix bug in CEL input rate limit logic. {issue}40106[40106] {pull}40270[40270]
- Relax requirements in Okta entity analytics provider user and device profile data shape. {pull}40359[40359]
- Fix bug in Okta entity analytics rate limit logic. {issue}40106[40106] {pull}40267[40267]
- Fix crashes in the journald input. {pull}40061[40061]

*Heartbeat*

Expand Down
3 changes: 3 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ TEST_BOXES = [
{:name => "ubuntu1604", :box => "ubuntu/xenial64", :platform => "ubuntu"},
{:name => "ubuntu1804", :box => "ubuntu/bionic64", :platform => "ubuntu"},
{:name => "ubuntu2004", :box => "ubuntu/focal64", :platform => "ubuntu"},
{:name => "ubuntu2204", :box => "ubuntu/jammy64", :platform => "ubuntu"},

{:name => "debian8", :box => "generic/debian8", :platform => "debian"},
{:name => "debian9", :box => "debian/stretch64", :platform => "debian"},
{:name => "debian10", :box => "debian/buster64", :platform => "debian"},
{:name => "debian11", :box => "debian/bullseye64", :platform => "debian"},
{:name => "debian12", :box => "debian/bookworm64", :platform => "debian"},

{:name => "amazon1", :box => "mvbcoding/awslinux", :platform => "centos"},
{:name => "amazon2", :box => "bento/amazonlinux-2", :platform => "centos"},
Expand Down
5 changes: 2 additions & 3 deletions filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -775,9 +775,8 @@ filebeat.inputs:
# You may wish to have separate inputs for each service. You can use
# include_matches.or to specify a list of filter expressions that are
# applied as a logical OR. You may specify filter
#include_matches.or:
#- equals:
#- _SYSTEMD_UNIT=foo.service
#include_matches.match:
#- _SYSTEMD_UNIT=foo.service

# List of syslog identifiers
#syslog_identifiers: ["audit"]
Expand Down
75 changes: 34 additions & 41 deletions filebeat/docs/inputs/input-journald.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@ experimental[]

https://www.freedesktop.org/software/systemd/man/systemd-journald.service.html[`journald`]
is a system service that collects and stores logging data. The `journald` input
reads this log data and the metadata associated with it.
reads this log data and the metadata associated with it. To read this
log data {beatname_uc} calls `journalctl` to read from the journal, therefore
{beatname_uc} needs permission to execute `journalctl`.

If the `journalctl` process exits unexpectedly the {type} input will
terminate with an error and {beatname_uc} will need to be
restarted to start reading from the jouranl again.

The simplest configuration example is one that reads all logs from the default
journal.
Expand Down Expand Up @@ -71,21 +77,22 @@ The `journald` input supports the following configuration options plus the
[id="{beatname_lc}-input-{type}-id"]
==== `id`

An optional unique identifier for the input. By providing a unique `id` you can
An unique identifier for the input. By providing a unique `id` you can
operate multiple inputs on the same journal. This allows each input's cursor to
be persisted independently in the registry file.
be persisted independently in the registry file. Each {type} input must have
an unique ID.

["source","yaml",subs="attributes"]
----
{beatname_lc}.inputs:
- type: journald
id: consul.service
include_matches:
include_matches.match:
- _SYSTEMD_UNIT=consul.service

- type: journald
id: vault.service
include_matches:
include_matches.match:
- _SYSTEMD_UNIT=vault.service
----

Expand All @@ -100,20 +107,6 @@ into a single journal and reads them.

If no paths are specified, {beatname_uc} reads from the default journal.

[float]
[id="{beatname_lc}-input-{type}-backoff"]
==== `backoff`

The number of seconds to wait before trying to read again from journals. The
default is 1s.

[float]
[id="{beatname_lc}-input-{type}-max-backoff"]
==== `max_backoff`

The maximum number of seconds to wait before attempting to read again from
journals. The default is 60s.

[float]
[id="{beatname_lc}-input-{type}-seek"]
==== `seek`
Expand All @@ -124,36 +117,26 @@ The position to start reading the journal from. Valid settings are:
{beatname_uc} resends all log messages in the journal.
* `tail`: Starts reading at the end of the journal. This means that no events
will be sent until a new message is written.
* `cursor`: On first read, starts reading at the beginning of the journal. After
a reload or restart, continues reading at the last known position.
* `since`: Use the `since` option to determine where to start reading from.

If you have old log files and want to skip lines, start {beatname_uc} with
`seek: tail` specified. Then stop {beatname_uc}, set `seek: cursor`, and restart
{beatname_uc}.

[float]
[id="{beatname_lc}-input-{type}-cursor_seek_fallback"]
==== `cursor_seek_fallback`
Regardless of the value of `seek` if {beatname_uc} has a state (cursor) for this
input, the `seek` value is ignored and the current cursor is used. To reset
the cursor, just change the `id` of the input, this will start from a fresh state.
belimawr marked this conversation as resolved.
Show resolved Hide resolved

The position to start reading the journal from if no cursor information is
available. Valid options are `head`, `tail` and `since`.

[float]
[id="{beatname_lc}-input-{type}-since"]
==== `since`

A time offset from the current time to start reading from. To use
`since`, either the `seek` option must be set to `since`, or the `seek` mode
must be set to `cursor` and the `cursor_seek_fallback` set to `since`.
`since`, `seek` option must be set to `since`.

This example demonstrates how to resume from the persisted cursor when
it exists, or otherwise begin reading logs from the last 24 hours.

["source","yaml",subs="attributes"]
----
seek: cursor
cursor_seek_fallback: since
seek: since
since: -24h
----

Expand Down Expand Up @@ -199,20 +182,30 @@ If the filter expressions apply to different fields, only entries with all field
If they apply to the same fields, only entries where the field takes one of the specified values will be iterated.

`match`: List of filter expressions to match fields.
`or`: The filter expressions listed under `or` are connected with a disjunction (or).
`and`: The filter expressions listed under `and` are connected with a conjunction (and).

Please note that these expressions are limited. You can build complex filtering, but full logical
expressions are not supported.

The following include matches configuration reads all `systemd` syslog entries:
The following include matches configuration will ingest entries that
contain `journald.process.name: systemd` and `systemd.transport: syslog`.

["source","yaml",subs="attributes"]
----
include_matches:
match:
- "journald.process.name=systemd"
- "systemd.transport=syslog"
----

The following include matches configuration will ingest entries that
contain `systemd.transport: systemd` or `systemd.transport: kernel`.

["source","yaml",subs="attributes"]
----
include_matches.and:
- match:
- "journald.process.name=systemd"
- "systemd.transport=syslog"
include_matches:
match:
- "systemd.transport=kernel"
- "systemd.transport=syslog"
----

To reference fields, use one of the following:
Expand Down
5 changes: 2 additions & 3 deletions filebeat/filebeat.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1182,9 +1182,8 @@ filebeat.inputs:
# You may wish to have separate inputs for each service. You can use
# include_matches.or to specify a list of filter expressions that are
# applied as a logical OR. You may specify filter
#include_matches.or:
#- equals:
#- _SYSTEMD_UNIT=foo.service
#include_matches.match:
#- _SYSTEMD_UNIT=foo.service

# List of syslog identifiers
#syslog_identifiers: ["audit"]
Expand Down
65 changes: 9 additions & 56 deletions filebeat/input/journald/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
// specific language governing permissions and limitations
// under the License.

//go:build linux && cgo && withjournald
//go:build linux

package journald

import (
"errors"
"sync"
"time"

"github.com/elastic/go-ucfg"

"github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalctl"
"github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalfield"
"github.com/elastic/beats/v7/filebeat/input/journald/pkg/journalread"

"github.com/elastic/beats/v7/libbeat/common/cfgwarn"
"github.com/elastic/beats/v7/libbeat/reader/parser"
)
Expand All @@ -41,22 +41,12 @@ type config struct {
// Paths stores the paths to the journal files to be read.
Paths []string `config:"paths"`

// Backoff is the current interval to wait before
// attempting to read again from the journal.
Backoff time.Duration `config:"backoff" validate:"min=0,nonzero"`

// MaxBackoff is the limit of the backoff time.
MaxBackoff time.Duration `config:"max_backoff" validate:"min=0,nonzero"`

// Since is the relative time offset from now to provide journal
// entries from. If Since is nil, no offset is applied.
Since *time.Duration `config:"since"`
// entries from.
Since time.Duration `config:"since"`

// Seek is the method to read from journals.
Seek journalread.SeekMode `config:"seek"`

// CursorSeekFallback sets where to seek if registry file is not available.
CursorSeekFallback journalread.SeekMode `config:"cursor_seek_fallback"`
Seek journalctl.SeekMode `config:"seek"`

// Matches store the key value pairs to match entries.
Matches bwcIncludeMatches `config:"include_matches"`
Expand Down Expand Up @@ -89,11 +79,8 @@ func (im *bwcIncludeMatches) Unpack(c *ucfg.Config) error {
if err := c.Unpack(&matches); err != nil {
return err
}
for _, x := range matches {
im.OR = append(im.OR, journalfield.IncludeMatches{
Matches: []journalfield.Matcher{x},
})
}
im.Matches = append(im.Matches, matches...)

includeMatchesWarnOnce.Do(func() {
cfgwarn.Deprecate("", "Please migrate your journald input's "+
"include_matches config to the new more expressive format.")
Expand All @@ -104,43 +91,9 @@ func (im *bwcIncludeMatches) Unpack(c *ucfg.Config) error {
return c.Unpack((*journalfield.IncludeMatches)(im))
}

var (
errInvalidSeekFallback = errors.New("invalid setting for cursor_seek_fallback")
errInvalidSeek = errors.New("invalid setting for seek")
errInvalidSeekSince = errors.New("incompatible setting for since and seek or cursor_seek_fallback")
)

func defaultConfig() config {
return config{
Backoff: 1 * time.Second,
MaxBackoff: 20 * time.Second,
Seek: journalread.SeekCursor,
CursorSeekFallback: journalread.SeekHead,
Seek: journalctl.SeekHead,
SaveRemoteHostname: false,
}
}

func (c *config) Validate() error {
if c.Seek == journalread.SeekInvalid {
return errInvalidSeek
}
switch c.CursorSeekFallback {
case journalread.SeekHead, journalread.SeekTail, journalread.SeekSince:
default:
return errInvalidSeekFallback
}
if c.Since == nil {
switch {
case c.Seek == journalread.SeekSince,
c.Seek == journalread.SeekCursor && c.CursorSeekFallback == journalread.SeekSince:
return errInvalidSeekSince
default:
return nil
}
}
needSince := c.Seek == journalread.SeekSince || (c.Seek == journalread.SeekCursor && c.CursorSeekFallback == journalread.SeekSince)
if !needSince {
return errInvalidSeekSince
}
return nil
}
Loading
Loading