logger2
A modern, feature-rich replacement for the classic Unix logger(1) CLI —
same core job (send a message to syslog), but with truecolor hex output,
emoji, JSON output, remote delivery over UDP/TCP, RFC 5424 support, and a
fully configurable TOML config file.
Written in Rust. Single static-ish binary, cross-platform, no runtime dependencies.
$ logger2 -l warning "disk usage on /var is at 92%"
2026-07-01 09:41:06.243 ⚠️ WARN [hadi] disk usage on /var is at 92%
Features
- Drop-in familiar CLI — mirrors util-linux
logger's flags (-p,-t,-i,-s,-f,-n,-P,-T/-d,-u,-r,-S) so existing scripts and muscle memory transfer directly. - Truecolor hex output — per-level colors configured as
#RRGGBB(or overridden per-invocation with-c), rendered with 24-bit ANSI escapes. - Emoji decoration — a configurable emoji per severity level, or an
ad-hoc override with
-e. - Local and remote syslog — writes to the local syslog Unix socket
(
/dev/logon Linux,/var/run/syslogon macOS) by default, or to a remote syslog daemon over UDP or TCP with-n/--server. - RFC 3164 and RFC 5424 framing — pick the legacy BSD format or the modern IETF format with structured data, plus RFC 6587 octet-counting for TCP.
- JSON output mode —
--jsonemits one structured JSON object per line for easy piping intojq, log shippers, or other tooling. - Structured fields — attach arbitrary
key=valuepairs with-k, included in both console and JSON output and forwarded as RFC 5424 structured data. - Fully configurable via TOML — colors, emoji, default priority, output template, network settings, and more, all overridable per-invocation by CLI flags.
- Safe on every platform — local Unix-socket syslog delivery is
Linux/macOS/BSD only; on other platforms (e.g. Windows) logger2 degrades
gracefully and tells you to use
--serverfor remote delivery instead of panicking or silently failing. --dry-run— see exactly what would be printed and sent, without sending anything.
Installation
From crates.io
cargo install logger2
From a release binary
Download the archive for your platform from the
Releases page, extract it,
and put the logger2 binary on your PATH.
From source
git clone https://github.com/licface/logger2
cd logger2
cargo build --release
# binary at target/release/logger2
Usage
logger2 [OPTIONS] [MESSAGE]...
If MESSAGE is omitted, logger2 reads from --file, then falls back to
stdin.
Basic examples
# Simple message at the default priority (user.notice)
logger2 "backup completed successfully"
# Explicit facility.level priority (like the original logger)
logger2 -p local0.error "disk write failed"
# Friendly level name instead of spelling out facility.level
logger2 -l error "disk write failed"
# Custom tag and include the PID
logger2 -t backup-script -i "starting nightly backup"
# Read the message from a file
logger2 -f /var/log/app/last-error.txt -l error
# Pipe a message in
echo "queue depth exceeded threshold" | logger2 -l warning
# One-off color/emoji override, ignoring the config file
logger2 -c "#FF00AA" -e "🚀" -l info "deploy started"
# Ship straight to a remote syslog collector over TCP with RFC 5424 framing
logger2 -n logs.example.com -P 6514 -T -r -l critical "node unreachable"
# Attach structured fields (shown in console output, JSON, and RFC 5424 SD)
logger2 --json -k request_id=abc123 -k user=alice -l info "request handled"
# See what would happen without actually sending or writing anything
logger2 --dry-run -l debug "just checking output"
Levels
trace, debug, info, notice, warning, error, critical, alert,
emergency — mapped to standard syslog severities 7 down to 0 (trace is a
non-standard convenience level that maps to severity 7, same as debug).
Facilities
All standard syslog facilities are supported: kern, user, mail,
daemon, auth, syslog, lpr, news, uucp, cron, authpriv,
ftp, ntp, security, console, solaris-cron, and local0–local7.
Configuration file
logger2 looks for a config file in this order (first match wins):
--config <path>/LOGGER2_CONFIGenvironment variable$XDG_CONFIG_HOME/logger2/config.toml(or the platform equivalent, e.g.~/.config/logger2/config.tomlon Linux)~/.logger2.toml/etc/logger2/config.toml(Unix only)- Built-in defaults, if none of the above exist
Generate a starter config with:
logger2 --init-config
Inspect the fully-resolved effective config (defaults + file + no CLI overrides) with:
logger2 --print-config
Example config
[]
= "user.notice"
= "" # empty = use the current username
= "%Y-%m-%d %H:%M:%S%.3f"
= false
= 8192
[]
= true
= true
= false
= "{timestamp} {emoji} {level} [{tag}] {message}"
[]
= "" # empty = deliver to the local syslog socket
= 514
= "udp" # "udp" or "tcp"
= "/dev/log" # local Unix socket path
= false
= false
= 2000
[]
= true
= "#87AFFF"
= "#808080"
= "#FFFFFF"
[]
= "#808080"
= "#00AFFF"
= "#00FF00"
= "#00FFFF"
= "#FFFF00"
= "#FF5555"
= "#FF00FF"
= "#FF0000"
= "#FFFFFF"
[]
= true
[]
= "🔍"
= "🐛"
= "ℹ️"
= "📝"
= "⚠️"
= "❌"
= "🔥"
= "🚨"
= "💀"
Command-line flags always take precedence over the config file, which in turn takes precedence over built-in defaults.
Output template placeholders
{timestamp}, {emoji}, {level}, {tag}, {message} are substituted
into output.template.
Color and emoji behavior
- Colors are disabled automatically when output is not a TTY, when
NO_COLORis set, or with--no-color. Force them on with--force-colororCLICOLOR_FORCE. - Emoji can be turned off globally in the config (
emoji.enabled = false) or per-invocation with--no-emoji. -c/--colorand-e/--emojioverride the level-based defaults for a single invocation without touching the config file.
Platform notes
- Linux / macOS / BSD: full support, including local syslog delivery over the Unix domain socket.
- Windows: local Unix-socket syslog delivery is not available (there is
no
/dev/logequivalent); use-n/--serverto ship to a remote syslog collector over UDP or TCP, which works everywhere. Console/JSON output works identically on every platform.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Delivery failed, or a usage/validation error occurred |
Development
make build # debug build
make test # run unit + integration tests
make lint # clippy, warnings as errors
make fmt # rustfmt
make release # optimized release build
make cross-all # cross-compile for all supported targets (needs rustup)
make dist # cross-compile + package tarballs into dist/
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.
