Valerter is configured via a YAML file, typically at /etc/valerter/config.yaml.
See config/config.example.yaml for a complete annotated example.
| Location | Description |
|---|---|
/etc/valerter/config.yaml |
Default location (systemd) |
Custom path via -c flag |
valerter -c /path/to/config.yaml |
Security: The file should be owned by valerter:valerter with mode 600 (owner read/write only).
For large deployments, you can split rules, templates, and notifiers into separate files in .d/ directories alongside config.yaml:
/etc/valerter/
├── config.yaml # Main config
├── rules.d/
│ ├── security.yaml # Security team rules
│ └── infra.yaml # Infrastructure rules
├── templates.d/
│ └── custom.yaml # Custom templates
└── notifiers.d/
└── team-channels.yaml
.d/ FilesFiles in .d/ directories use a HashMap format where the name is the YAML key:
# rules.d/security.yaml
auth_failure:
query: "_msg:authentication AND status:failed"
parser:
json:
fields: [user, ip]
notify:
template: "security_alert"
destinations:
- security-team
brute_force:
query: "_msg:blocked"
parser:
regex: "IP (?P<ip>\\d+\\.\\d+\\.\\d+\\.\\d+)"
notify:
template: "security_alert"
destinations:
- security-team
# templates.d/custom.yaml
security_alert:
title: "Security: "
body: ""
accent_color: "#ff0000"
# notifiers.d/team-channels.yaml
security-team:
type: mattermost
webhook_url: "https://mattermost.example.com/hooks/security"
infra-team:
type: mattermost
webhook_url: "https://mattermost.example.com/hooks/infra"
*.yaml and *.yml only. are ignoredconfig.yaml and all .d/ files.d/ can reference templates in config.yaml and vice versaIf the same name is defined in multiple files, Valerter fails at startup with an explicit error:
Error: duplicate rule name 'my_rule': defined in 'config.yaml' and 'rules.d/extra.yaml'
victorialogs: # VictoriaLogs connection (REQUIRED)
metrics: # Prometheus metrics (optional)
notifiers: # Named notification channels (recommended)
defaults: # Default throttle and notify settings (REQUIRED)
templates: # Message templates (REQUIRED)
rules: # Alert rules (REQUIRED, at least one)
victorialogs:
url: "http://victorialogs:9428" # REQUIRED
# Optional: Basic Authentication
basic_auth:
username: "${VL_USER}"
password: "${VL_PASS}"
# Optional: Custom headers (for tokens, API keys)
headers:
Authorization: "Bearer ${VL_TOKEN}"
# Optional: TLS configuration
tls:
verify: true # Set to false for self-signed certs
If VictoriaLogs is behind a reverse proxy (nginx, Traefik, etc.), you must disable buffering and caching for the /select/logsql/tail endpoint. Valerter uses HTTP streaming to receive logs in real-time, and proxy buffering will cause delays or connection issues.
Nginx example:
# Add this BEFORE your general /select location block
location = /select/logsql/tail {
proxy_pass http://victorialogs_backend;
# CRITICAL: Disable buffering and caching for streaming
proxy_buffering off;
proxy_cache off;
# Long timeouts for persistent connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
Key settings:
proxy_buffering off — Send data immediately to clientproxy_cache off — Don’t cache streaming responsesproxy_read_timeout 3600s — Keep connection alive for 1 hourDefault values applied to all rules unless overridden.
defaults:
throttle:
count: 5 # Max alerts per window
window: 60s # Time window (e.g., 60s, 5m, 1h)
# timestamp_timezone: "Europe/Paris" # Optional: timezone for formatted timestamps (default: UTC)
The timestamp_timezone setting controls the timezone used for `` in templates and Mattermost footers.
| Value | Example Output |
|---|---|
UTC (default) |
15/01/2026 10:00:00 UTC |
Europe/Paris |
15/01/2026 11:00:00 CET (winter) / CEST (summer) |
America/New_York |
15/01/2026 05:00:00 EST |
Uses IANA timezone names. Invalid timezone will fail at startup.
Message templates use Jinja2 syntax (via minijinja).
templates:
default_alert:
title: "" # REQUIRED
body: "" # REQUIRED
body_html: "<p></p>" # REQUIRED for email destinations
accent_color: "#ff0000" # Optional: hex color
Variables come from the parser output plus built-in fields:
| Variable | Description |
|---|---|
rule_name |
Name of the rule that triggered |
_msg |
Original log message (from VictoriaLogs) |
_time |
Log timestamp (raw from VictoriaLogs) |
_stream |
Stream labels |
log_timestamp |
Original log timestamp in ISO 8601 format (for VictoriaLogs search) |
log_timestamp_formatted |
Human-readable timestamp (respects timestamp_timezone setting) |
| Custom fields | Extracted by regex/JSON parser |
Note: log_timestamp and log_timestamp_formatted are available in:
body_templatelog_timestamp_formatted)Important: Templates used with email destinations MUST include body_html. Valerter validates this at startup and will fail if missing.
Alert rules define what logs to monitor and how to process them.
rules:
- name: "high_cpu_alert" # REQUIRED: unique name
enabled: true # Default: true
query: '_stream:{host="server1"} | json | cpu > 90' # REQUIRED: LogsQL
parser: # At least one recommended
json:
fields: ["host", "cpu", "timestamp"]
# OR
regex: '(?P<level>\S+) (?P<message>.*)'
throttle: # Optional: overrides defaults
key: "" # Group throttling by field
count: 3
window: 5m
notify: # REQUIRED
template: "custom_template" # REQUIRED: template name
destinations: # REQUIRED: at least one notifier
- mattermost-ops
- email-ops
mattermost_channel: "alerts" # Optional: override Mattermost channel
JSON Parser: Extract specific fields from JSON logs.
parser:
json:
fields: ["host", "level", "message", "timestamp"]
Regex Parser: Extract fields using named capture groups.
parser:
regex: '(?P<timestamp>\S+) (?P<level>\S+) (?P<message>.*)'
Prevents alert spam by limiting notifications per time window.
| Field | Description |
|---|---|
key |
Template to group alerts (e.g., ``) |
count |
Max alerts per window |
window |
Time window (e.g., 30s, 5m, 1h) |
Example: Max 3 alerts per host per 5 minutes:
throttle:
key: ""
count: 3
window: 5m
Put secrets directly in the config file and secure with permissions:
notifiers:
mattermost-ops:
type: mattermost
webhook_url: "https://mattermost.example.com/hooks/abc123def456"
sudo chmod 600 /etc/valerter/config.yaml
sudo chown valerter:valerter /etc/valerter/config.yaml
For Kubernetes or orchestrators, use ${VAR_NAME} syntax:
notifiers:
mattermost-ops:
type: mattermost
webhook_url: "${MATTERMOST_WEBHOOK}"
Variables are resolved at startup from the process environment. You can use any environment variable - there is no predefined list. Common examples:
${VL_USER}, ${VL_PASS} - VictoriaLogs credentials${SMTP_USER}, ${SMTP_PASSWORD} - Email credentials${SLACK_WEBHOOK_URL}, ${PAGERDUTY_TOKEN} - Notification servicesThese variables are read directly by the process (not substituted in config):
| Variable | Description |
|---|---|
RUST_LOG |
Log level: error, warn, info (default), debug, trace |
LOG_FORMAT |
Output format: text (default), json |
valerter [OPTIONS]
Options:
-c, --config <PATH> Path to configuration file [default: /etc/valerter/config.yaml]
--validate Validate configuration and exit
-h, --help Print help
-V, --version Print version
Always validate before deploying:
valerter --validate
This checks:
body_html