# journalcheck

[![CI](https://github.com/gms1/journalcheck/actions/workflows/ci.yml/badge.svg)](https://github.com/gms1/journalcheck/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/gms1/journalcheck/branch/main/graph/badge.svg)](https://codecov.io/gh/gms1/journalcheck)
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/gms1/journalcheck/pulls)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Systemd journal monitoring and notification tool with priority filtering, pattern matching and security violation detection.

Inspired by [logcheck](https://packages.debian.org/stable/logcheck), but designed for systemd's journal with output that can be piped to other programs for notifications, monitoring, or alerting.

## Key Differences from logcheck

- **Priority-based filtering**: Filter messages by systemd priority levels (emerg, alert, crit, err, warning, notice, info, debug) - logcheck only supports pattern matching
- **Per-service priority control**: Set different priority thresholds for different services without writing individual ignore patterns
- **Flexible output**: Pipe to any command, send via email, or output to stdout - not limited to email only
- **JSON output**: Machine-readable format for integration with monitoring systems
- **Cursor-based tracking**: Only process new entries since last run using systemd journal cursors

## Features

- Priority-based filtering (emerg, alert, crit, err, warning, notice, info, debug)
- Per-identifier priority configuration
- Regex pattern matching for identifiers (case-sensitive; (?i) is supported)
- Regex pattern matching for ignore and violations patterns (always case-insensitive)
  - **Ignore patterns**: Must match the entire message (implicit anchors)
  - **Violation patterns**: Can match anywhere in the message (substring match)
- Two-level pattern hierarchy:
  - **Violations**: Always shown (e.g., failed logins, security events)
  - **Ignore**: Suppress matching messages (exact match)
- Pre-configured violation patterns for common services (sshd, sudo, su, smartd)
- Cursor-based tracking (only process new entries)
- Multiple output formats (short, json)
- Modular configuration via `/etc/journalcheck.yaml` and `/etc/journalcheck.d/*.yaml`

## Installation

### From PyPI

```bash
pip install journalcheck
```

### From Debian package

Download the `.deb` file from the [releases page](https://github.com/gms1/journalcheck/releases) and install:

```bash
sudo dpkg -i journalcheck_*.deb
```

### via APT Repository

- download the public key:

```bash
curl -fsSL https://gms1.github.io/journalcheck/apt/public.gpg | sudo gpg --dearmor -o /usr/share/keyrings/journalcheck-archive-keyring.gpg
```

- register the apt repository

```bash
echo "deb [signed-by=/usr/share/keyrings/journalcheck-archive-keyring.gpg] https://gms1.github.io/journalcheck/apt ./" | sudo tee /etc/apt/sources.list.d/journalcheck.list
```

- install this package

```bash
sudo apt update && sudo apt install journalcheck
```

### From source

```bash
pip install -e .
```

## Configuration

Main config: `/etc/journalcheck.yaml`

Additional configs: `/etc/journalcheck.d/*.yaml` (merged automatically)

Example:
```yaml
priority: warning
format: short

# Optional: pipe output to a command
output_command: "notify-send 'Journal Alert'"

# Optional: send output via email
email_to: "admin@example.com"
email_subject: "Journal Alerts"

identifiers:
  ssh: # Exact match
    priority: info
    ignore:
      - ".*session opened.*"   # Full match: must match entire message
      - ".*session closed.*"
    violations:
      - "Failed password"       # Substring: matches anywhere in message
  /^(?i)cron$/: # Match both "cron" and "CRON" using case-insensitive regex
    priority: notice
    ignore:
      - ".*session opened.*"
      - ".*session closed.*"
  /^.*$/: # Any other identifier
    violations:
    - (error|failed)
```

**Output Options:**
- If `output_command` is set, output will be piped to that command
- If `email_to` is set, output will be sent via email using the `mail` command
- If neither is set, output goes to stdout by (default), except if running as systemd service

## Default Violations

The following identifiers have pre-configured violation patterns that are automatically included:

- **sshd**: Failed password, Invalid user, Connection closed by authenticating user, etc.
- **sudo**: authentication failure, user NOT in sudoers, incorrect password attempt
- **su**: FAILED su, authentication failure
- **smartd**: SMART Failure, Attribute.*failed, Error.*occurred
- **kernel**: I/O error, Buffer I/O error, end_request: I/O error

You can add additional violations to these identifiers - they will be appended to the defaults.
## Usage

### Basic usage
```bash
journalcheck
```

### Filter output
```bash
journalcheck | grep ssh
```

### Save to file
```bash
journalcheck > /var/log/journal-alerts.log
```

### Send via email
```bash
journalcheck | mail -s "Journal Alerts" admin@example.com
```

### Run via systemd timer
The package includes systemd service and timer units for automated checking.

**Enable the timer:**
```bash
sudo systemctl enable --now journalcheck.timer
```

**Check timer status:**
```bash
sudo systemctl status journalcheck.timer
sudo systemctl list-timers journalcheck.timer
```

**Customize the schedule:**
The default schedule is hourly. To change it:
```bash
sudo systemctl edit journalcheck.timer
```

Add your custom schedule:
```ini
[Timer]
OnCalendar=daily
```

See `systemd.time(7)` for schedule syntax.

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Repository

https://github.com/gms1/journalcheck

