Skip to content

Commit fc7b8fc

Browse files
authored
Add more filtering options to journald input (#29294)
## What does this PR do? This PR adds support for `unit`, `transports` and `syslog_identifiers` options for filtering. This PR also introduces a breaking change to `include_matches` option. From now on it does not accept a list of expressions. Now both conjunction (AND) and disjunctions (OR) are supported when applying matches to journals. Collecting entries of two different units: ```yaml - type: journald include_matches.or: - equals: - _SYSTEMD_UNIT=my_unit - _SYSTEMD_UNIT=my_other_unit ``` Collecting entries using syslog transport for a unit ```yaml - type: journald include_matches.and: - equals: - _SYSTEMD_UNIT=my_unit - _TRANSPORT=syslog ``` Although the configuration lets you write complex expressions, systemd does not provide full logical expression support. ## Why is it important? When this change merged, journald input can be marked either beta or GA. Furthermore, now it provides similar filtering capabilities as the good old community Journalbeat did.
1 parent eaa3b32 commit fc7b8fc

File tree

12 files changed

+530
-22
lines changed

12 files changed

+530
-22
lines changed

CHANGELOG.next.asciidoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
2626
- Index template's default_fields setting is only populated with ECS fields. {pull}28596[28596] {issue}28215[28215]
2727
- Remove deprecated `--template` and `--ilm-policy` flags. Use `--index-management` instead. {pull}28870[28870]
2828
- Remove options `logging.files.suffix` and default to datetime endings. {pull}28927[28927]
29+
- Remove Journalbeat. Use `journald` input of Filebeat instead. {pull}29131[29131]
30+
- `include_matches` option of `journald` input no longer accepts a list of string. {pull}29294[29294]
2931
- Add job.name in pods controlled by Jobs {pull}28954[28954]
3032

3133
*Auditbeat*
@@ -148,6 +150,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d
148150
- Add documentation for add_kubernetes_metadata processors `log_path` matcher. {pull}28868[28868]
149151
- Add support for parsers on journald input {pull}29070[29070]
150152
- Add support in httpjson input for oAuth2ProviderDefault of password grant_type. {pull}29087[29087]
153+
- Add support for filtering in journald input with `unit`, `kernel`, `identifiers` and `include_matches`. {pull}29294[29294]
151154
- Add new `userAgent` and `beatInfo` template functions for httpjson input {pull}29528[29528]
152155

153156
*Heartbeat*

filebeat/_meta/config/filebeat.inputs.reference.yml.tmpl

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -566,10 +566,21 @@ filebeat.inputs:
566566
#id: service-foo
567567

568568
# You may wish to have separate inputs for each service. You can use
569-
# include_matches to specify a list of filter expressions that are
569+
# include_matches.or to specify a list of filter expressions that are
570570
# applied as a logical OR. You may specify filter
571-
#include_matches:
572-
#- _SYSTEMD_UNIT=foo.service
571+
#include_matches.or:
572+
#- equals:
573+
#- _SYSTEMD_UNIT=foo.service
574+
575+
# List of syslog identifiers
576+
#syslog_identifiers: ["audit"]
577+
578+
# Collect events from the service and messages about the service,
579+
# including coredumps.
580+
#units: ["docker.service"]
581+
582+
# The list of transports (_TRANSPORT field of journald entries)
583+
#transports: ["audit"]
573584

574585
# Parsers are also supported, here is an example of the multiline
575586
# parser.

filebeat/docs/inputs/input-journald.asciidoc

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ journal.
2424
----
2525

2626
You may wish to have separate inputs for each service. You can use
27-
`include_matches` to specify a list of filter expressions that are applied as a
28-
logical OR. A good way to list the journald fields that are available for
27+
`include_matches` to specify filtering expressions.
28+
A good way to list the https://www.freedesktop.org/software/systemd/man/systemd.journal-fields.html[journald fields] that are available for
2929
filtering messages is to run `journalctl -o json` to output logs and metadata as
3030
JSON. This example collects logs from the `vault.service` systemd unit.
3131

@@ -34,7 +34,7 @@ JSON. This example collects logs from the `vault.service` systemd unit.
3434
{beatname_lc}.inputs:
3535
- type: journald
3636
id: service-vault
37-
include_matches:
37+
include_matches.match:
3838
- _SYSTEMD_UNIT=vault.service
3939
----
4040

@@ -48,7 +48,7 @@ possible.
4848
{beatname_lc}.inputs:
4949
- type: journald
5050
id: iptables
51-
include_matches:
51+
include_matches.match:
5252
- _TRANSPORT=kernel
5353
processors:
5454
- drop_event:
@@ -133,14 +133,64 @@ If you have old log files and want to skip lines, start {beatname_uc} with
133133
`seek: tail` specified. Then stop {beatname_uc}, set `seek: cursor`, and restart
134134
{beatname_uc}.
135135

136+
[float]
137+
[id="{beatname_lc}-input-{type}-units"]
138+
==== `units`
139+
140+
Iterate only the entries of the units specified in this option. The iterated entries include
141+
messages from the units, messages about the units by authorized daemons and coredumps. However,
142+
it does not match systemd user units.
143+
144+
[float]
145+
[id="{beatname_lc}-input-{type}-syslog-identifiers"]
146+
==== `syslog_identifiers`
147+
148+
Read only the entries with the selected syslog identifiers.
149+
150+
[float]
151+
[id="{beatname_lc}-input-{type}-transports"]
152+
==== `transports`
153+
154+
Collect the messages using the specified transports. Example: syslog.
155+
156+
Valid transports:
157+
158+
* audit: messages from the kernel audit subsystem
159+
* driver: internally generated messages
160+
* syslog: messages received via the local syslog socket with the syslog protocol
161+
* journal: messages received via the native journal protocol
162+
* stdout: messages from a service's standard output or error output
163+
* kernel: messages from the kernel
164+
136165
[float]
137166
[id="{beatname_lc}-input-{type}-include-matches"]
138167
==== `include_matches`
139168

140-
A list of filter expressions used to match fields. The format of the expression
169+
A collection of filter expressions used to match fields. The format of the expression
141170
is `field=value`. {beatname_uc} fetches all events that exactly match the
142171
expressions. Pattern matching is not supported.
143172

173+
If you configured a filter expression, only entries with this field set will be iterated by the journald reader of Filebeat.
174+
If the filter expressions apply to different fields, only entries with all fields set will be iterated.
175+
If they apply to the same fields, only entries where the field takes one of the specified values will be iterated.
176+
177+
`match`: List of filter expressions to match fields.
178+
`or`: The filter expressions listed under `or` are connected with a disjunction (or).
179+
`and`: The filter expressions listed under `and` are connected with a conjunction (and).
180+
181+
Please note that these expressions are limited. You can build complex filtering, but full logical
182+
expressions are not supported.
183+
184+
The following include matches configuration reads all `systemd` syslog entries:
185+
186+
["source","yaml",subs="attributes"]
187+
----
188+
include_matches.and:
189+
- match:
190+
- "journald.process.name=systemd"
191+
- "systemd.transport=syslog"
192+
----
193+
144194
To reference fields, use one of the following:
145195

146196
* The field name used by the systemd journal. For example,

filebeat/filebeat.reference.yml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -973,10 +973,21 @@ filebeat.inputs:
973973
#id: service-foo
974974

975975
# You may wish to have separate inputs for each service. You can use
976-
# include_matches to specify a list of filter expressions that are
976+
# include_matches.or to specify a list of filter expressions that are
977977
# applied as a logical OR. You may specify filter
978-
#include_matches:
979-
#- _SYSTEMD_UNIT=foo.service
978+
#include_matches.or:
979+
#- equals:
980+
#- _SYSTEMD_UNIT=foo.service
981+
982+
# List of syslog identifiers
983+
#syslog_identifiers: ["audit"]
984+
985+
# Collect events from the service and messages about the service,
986+
# including coredumps.
987+
#units: ["docker.service"]
988+
989+
# The list of transports (_TRANSPORT field of journald entries)
990+
#transports: ["audit"]
980991

981992
# Parsers are also supported, here is an example of the multiline
982993
# parser.

filebeat/input/journald/config.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,16 @@ type config struct {
4848
CursorSeekFallback journalread.SeekMode `config:"cursor_seek_fallback"`
4949

5050
// Matches store the key value pairs to match entries.
51-
Matches []journalfield.Matcher `config:"include_matches"`
51+
Matches journalfield.IncludeMatches `config:"include_matches"`
52+
53+
// Units stores the units to monitor.
54+
Units []string `config:"units"`
55+
56+
// Transports stores the list of transports to include in the messages.
57+
Transports []string `config:"transports"`
58+
59+
// Identifiers stores the syslog identifiers to watch.
60+
Identifiers []string `config:"syslog_identifiers"`
5261

5362
// SaveRemoteHostname defines if the original source of the entry needs to be saved.
5463
SaveRemoteHostname bool `config:"save_remote_hostname"`

filebeat/input/journald/input.go

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ type journald struct {
4343
MaxBackoff time.Duration
4444
Seek journalread.SeekMode
4545
CursorSeekFallback journalread.SeekMode
46-
Matches []journalfield.Matcher
46+
Matches journalfield.IncludeMatches
47+
Units []string
48+
Transports []string
49+
Identifiers []string
4750
SaveRemoteHostname bool
4851
Parsers parser.Config
4952
}
@@ -105,6 +108,9 @@ func configure(cfg *common.Config) ([]cursor.Source, cursor.Input, error) {
105108
Seek: config.Seek,
106109
CursorSeekFallback: config.CursorSeekFallback,
107110
Matches: config.Matches,
111+
Units: config.Units,
112+
Transports: config.Transports,
113+
Identifiers: config.Identifiers,
108114
SaveRemoteHostname: config.SaveRemoteHostname,
109115
Parsers: config.Parsers,
110116
}, nil
@@ -156,7 +162,8 @@ func (inp *journald) Run(
156162

157163
func (inp *journald) open(log *logp.Logger, canceler input.Canceler, src cursor.Source) (*journalread.Reader, error) {
158164
backoff := backoff.NewExpBackoff(canceler.Done(), inp.Backoff, inp.MaxBackoff)
159-
reader, err := journalread.Open(log, src.Name(), backoff, withFilters(inp.Matches))
165+
reader, err := journalread.Open(log, src.Name(), backoff,
166+
withFilters(inp.Matches), withUnits(inp.Units), withTransports(inp.Transports), withSyslogIdentifiers(inp.Identifiers))
160167
if err != nil {
161168
return nil, sderr.Wrap(err, "failed to create reader for %{path} journal", src.Name())
162169
}
@@ -184,9 +191,27 @@ func initCheckpoint(log *logp.Logger, c cursor.Cursor) checkpoint {
184191
return cp
185192
}
186193

187-
func withFilters(filters []journalfield.Matcher) func(*sdjournal.Journal) error {
194+
func withFilters(filters journalfield.IncludeMatches) func(*sdjournal.Journal) error {
188195
return func(j *sdjournal.Journal) error {
189-
return journalfield.ApplyMatchersOr(j, filters)
196+
return journalfield.ApplyIncludeMatches(j, filters)
197+
}
198+
}
199+
200+
func withUnits(units []string) func(*sdjournal.Journal) error {
201+
return func(j *sdjournal.Journal) error {
202+
return journalfield.ApplyUnitMatchers(j, units)
203+
}
204+
}
205+
206+
func withTransports(transports []string) func(*sdjournal.Journal) error {
207+
return func(j *sdjournal.Journal) error {
208+
return journalfield.ApplyTransportMatcher(j, transports)
209+
}
210+
}
211+
212+
func withSyslogIdentifiers(identifiers []string) func(*sdjournal.Journal) error {
213+
return func(j *sdjournal.Journal) error {
214+
return journalfield.ApplySyslogIdentifierMatcher(j, identifiers)
190215
}
191216
}
192217

0 commit comments

Comments
 (0)