When working with journalctl
's pattern matching for SYSLOG_IDENTIFIER
, many developers encounter unexpected behavior. As shown in the example:
journalctl -t sshd | wc -l
987
journalctl -t 'ssh*'
-- No Entries --
The pattern matching doesn't work as intuitively expected with wildcards. Let's dive deeper into how systemd actually implements pattern matching.
Systemd's pattern matching for SYSLOG_IDENTIFIER
follows these rules:
- Patterns must match the entire identifier string
- Wildcards (*) are only supported at the beginning or end of patterns
- The matching is case-sensitive by default
- Regular expression syntax is not supported in basic pattern matching
Here are several approaches to achieve what you need:
1. Basic Wildcard Matching:
journalctl -t 'sshd*'
journalctl -t '*sshd'
2. Using Multiple Identifiers:
journalctl -t sshd -t ssh
3. Advanced Filtering with Journal Query Language:
journalctl _SYSTEMD_UNIT=sshd.service
journalctl SYSLOG_IDENTIFIER=sshd
For comprehensive SSH log analysis:
# Show all SSH-related logs from today
journalctl -u sshd --since today
# Show failed login attempts
journalctl -t sshd | grep 'Failed password'
# Show logs with PID information
journalctl -t sshd -o verbose
When pattern matching isn't sufficient, consider these alternatives:
# Using grep for more complex pattern matching
journalctl | grep -E 'sshd|ssh'
# Combining multiple filters
journalctl --unit=sshd* --since="1 hour ago"
# Exporting logs for external processing
journalctl -t sshd --output=json > ssh_logs.json
Pattern matching behavior may vary across systemd versions. Always check your version:
journalctl --version
systemd 225
Newer versions (systemd 230+) may support more advanced pattern matching features.
When working with systemd's journal logs, many admins expect -t
(or --identifier
) to support standard glob patterns for syslog identifier matching. The man page suggests this capability exists, but practical implementation reveals quirks.
Testing with common pattern formats shows limited pattern support:
# Exact match works:
journalctl -t sshd
# Wildcards fail:
journalctl -t 'ssh*'
journalctl -t 'ssh.*'
For broader pattern matching, combine journalctl
with grep filtering:
# Basic prefix matching:
journalctl | grep -E '^[A-Za-z]{3} [0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} .* ssh'
# More precise unit matching:
journalctl _SYSTEMD_UNIT=sshd.service
For true pattern matching across journal fields, use --field
:
journalctl --field=_SYSTEMD_UNIT | grep -E '^ssh'
# Combine with JSON output for processing:
journalctl -o json | jq 'select(._SYSTEMD_UNIT | test("^ssh"))'
Pattern matching behavior may vary across systemd versions:
# Check your systemd version:
systemd --version
# Newer versions (v240+) support more advanced filtering:
journalctl -t 'sshd*' --output=json | jq length
When direct pattern matching fails, consider these alternatives:
# List all available identifiers first:
journalctl --field=_SYSTEMD_UNIT | sort -u
# Then filter programmatically:
journalctl -o json | jq -r '._SYSTEMD_UNIT' | grep '^ssh' | uniq