Skip to content

Log Levels ​

TCP Warden uses a single log_level setting to control the verbosity of both its logging subsystems simultaneously.

global:  # Accepted values (case-insensitive):  #   debug | info | warn | error | off  log_level: "warn"   # default

Two Independent Log Streams ​

TCP Warden produces two distinct categories of log output, both gated by log_level:

StreamFormatDestinationPurpose
Operational logsHuman-readable textstderrStartup banners, plugin status, API listener confirmations, daemon warnings
Security eventsStructured JSONLstdout + log_filePer-connection audit records consumed by CrowdSec, dashboards, and SIEMs

Both streams respect log_level independently: operational messages below the threshold are dropped from stderr, and security events with actions below the threshold are never written to stdout or log_file.


Level Reference ​

LevelOperational logsSecurity events writtenTypical use case
debugAll messages including internal traceAll events (allowed, auth_failure, blocked)Local development, troubleshooting
infoOperational status, plugin status, API listenersAll events (allowed, auth_failure, blocked)Detailed traffic auditing
warnDefault. Warnings and errors only (plugin failures, sync errors)auth_failure and blocked events onlyStandard production deployments & CrowdSec
errorErrors onlyblocked and banned events onlyHigh-traffic servers; minimal log volume
offNothingNothingTest harnesses; external log management

Security Event Action Mapping ​

The action field in each JSONL SecurityEvent determines the minimum level required for that event to be written:

action valueWritten when log_level isSuppressed when
alloweddebug or infowarn, error, or off
auth_failuredebug, info, or warnerror or off
blocked / banneddebug, info, warn, or erroroff only

Why this design?

allowed events are the highest volume by far — every successful legitimate connection generates one. Suppressing them at warn and above keeps log files compact and ensures CrowdSec and SIEMs only process meaningful security signals, not routine traffic.


Examples by Level ​

global:  log_level: "debug"  log_file: "/var/log/routewarden/tcp-warden.jsonl"

Security Event Format ​

Each JSONL line is a single SecurityEvent object. Here are real examples for each action type:

{"type":"security_event","timestamp":"2026-09-30T09:42:11.320Z","plugin":"tcp-warden","service":"ssh_bastion","protocol":"ssh","client_ip":"10.0.0.5","country_code":"LAN","flag_emoji":"🏠","action":"allowed","reason":"session_complete","bytes_in":2048,"bytes_out":1024,"duration_ms":3201}

Event Fields ​

FieldTypeDescription
typestringAlways "security_event"
timestampstringRFC 3339 UTC timestamp
pluginstringAlways "tcp-warden"
servicestringService name from configuration
protocolstringProtocol handler (ssh, tcp, smtp, etc.)
client_ipstringSource IP address
country_codestringISO 3166-1 alpha-2 code ("US", "LAN" for private ranges)
country_namestringCountry name (omitted for private ranges)
flag_emojistringCountry flag emoji (🏠 for LAN)
actionstringallowed, auth_failure, blocked, or banned
reasonstringSpecific reason string (e.g. "ip_denied", "crowdsec_ban: ...")
bytes_inint64Bytes received from client (omitted when 0)
bytes_outint64Bytes sent to client (omitted when 0)
duration_msint64Connection duration in milliseconds

Environment Variable Override ​

log_level can also be set via the ROUTEWARDEN_LOG_LEVEL environment variable, which takes precedence over the YAML value. This is convenient for container deployments:

services:  tcp-warden:    image: ghcr.io/routewarden/tcp-warden:latest    environment:      - ROUTEWARDEN_LOG_LEVEL=warn   # overrides log_level in tcp-warden.yaml

Startup Banner ​

TCP Warden prints the active log level at startup so you can confirm the setting at a glance:

🛡️  Starting TCP Warden...   Config:     /etc/routewarden/tcp-warden.yaml   Services (3):     • ssh_bastion  [ssh]   :2222 -> 127.0.0.1:22 (enabled)     • db_proxy     [postgres]  :5432 -> 10.0.0.15:5432 (enabled)     • cache        [redis]  :6380 -> 127.0.0.1:6379 (enabled)   Log file:   /var/log/routewarden/tcp-warden.jsonl   Log level:  warn

CrowdSec & Log Levels

When running TCP Warden alongside CrowdSec, set log_level: "warn". This keeps the JSONL audit file focused on auth_failure and blocked events — the exact signals CrowdSec scenarios are built to detect — without flooding the file with allowed records from legitimate traffic. See the CrowdSec Integration Guide for full setup details.

Released under the MIT License.