Logging and Audit¶
The Gateway writes operational logs and a separate management audit trail. This page describes their configuration and status APIs at the selected source revision. Independently verify retained records and external delivery.
Audience
Infrastructure operators, DevOps engineers, and platform SREs who need durable logs for troubleshooting and an audit record of management actions.
Structured logging configuration¶
LoxiLB emits structured log events to files under a configurable log directory. Three startup options control this behaviour. Each can be set as a command-line flag or, where noted, an environment variable.
| Flag | Env var | Default | Description |
|---|---|---|---|
--loglevel |
— | debug |
Minimum severity emitted. One of trace, debug, info, error, warning, notice, critical, emergency, alert. |
--log-dir |
LOXILB_LOG_DIR |
/var/log/loxilb/ |
Directory the log files are written to. |
--log-format |
LOXILB_LOG_FORMAT |
both |
Output format: json, text, or both. |
These are startup options
All three are read once, when the process starts. Changing a value requires a restart of LoxiLB to take effect.
Production example¶
Emit machine-readable JSON only, at info and above — the right balance of signal and volume for a log aggregator (Loki, Elasticsearch, Splunk):
The equivalent using environment variables (convenient for containers and systemd units):
Development example¶
Emit both formats at full debug verbosity so you get human-readable plaintext for terminal triage alongside the JSON stream:
Log files & rotation¶
All log files are written to the directory named by --log-dir (default /var/log/loxilb/). Which files appear depends on --log-format:
| File | Plane | Format | Written when --log-format is |
|---|---|---|---|
loxilb-audit.json.log |
Control plane | Structured JSON, one object per line | json or both |
loxilb<HOSTNAME>.log |
Control plane | Human-readable plaintext | text or both |
loxilb-dp-audit.json.log |
Data plane | Structured JSON, one object per line | json or both |
loxilb-dp<HOSTNAME>.log |
Data plane | Human-readable plaintext | text or both |
<HOSTNAME> is the value of the $HOSTNAME environment variable at process start. If it is empty, the plaintext files are simply loxilb.log and loxilb-dp.log.
# Confirm the files are being written
ls -lh /var/log/loxilb/
# Follow the structured JSON stream (pretty-printed)
tail -f /var/log/loxilb/loxilb-audit.json.log | jq .
# Follow the human-readable stream
tail -f /var/log/loxilb/loxilb.log
Built-in rotation¶
Rotation is handled inside the gateway — there is no need to configure an external logrotate unit. When a structured log file would exceed its size limit it is rotated in place: the current file is renamed with a UTC timestamp (<base>-<timestamp>.log), gzip-compressed, and old backups are pruned by count and age.
The structured log files rotate with these production defaults:
| Setting | Flag | Env var | Default |
|---|---|---|---|
| Rotate above size (MB) | --log-max-size |
LOXILB_LOG_MAX_SIZE |
50 |
| Backups kept per file | --log-max-backups |
LOXILB_LOG_MAX_BACKUPS |
4 |
| Retention (days) | --log-max-age |
LOXILB_LOG_MAX_AGE |
28 |
| Skip gzip of backups | --log-no-compress |
LOXILB_LOG_NO_COMPRESS |
off (backups are compressed) |
Setting --log-max-size=0 disables rotation and lets a file grow unbounded — not recommended in production. Rotated backups keep the .log / .log.gz naming so they remain easy to locate and archive.
Persist logs in Docker
A container's filesystem is discarded when the container is removed, taking /var/log/loxilb/ with it. Mount a host volume at the log directory so logs (and their rotated backups) survive restarts and redeploys:
Gateway management audit trail¶
The Gateway process keeps a management audit trail of the changes made through its management API. The management API serves its state and policy, never its records: no record content is served over the API, and identifiers name segments and events, never their content.
| Operation | Purpose |
|---|---|
GET /audit/status |
Whether a writer is configured and running, records accepted and dropped per stream, write, sync and timeout failures, the last write, the active segment, sealed bytes, the retention policy and the retention it projects, and the previous boot's management intents that never received a result |
GET /audit/policy |
The runtime-changeable policy: the limits that seal the active segment and the local retention target |
POST /audit/policy |
Replace that policy. The change is itself audited before it is applied. |
GET /audit/sink |
The remote syslog sink's configuration and session state |
POST /audit/sink |
Configure the remote syslog sink |
POST /audit/rotate |
Seal the active segment now and open the next; the audit record names both |
GET /audit/sinks/{name} |
One secondary sink: where it sends, what it selects from the trail, and how far it has got |
PUT /audit/sinks/{name} |
Create or replace a secondary sink. The name compliance is reserved. |
DELETE /audit/sinks/{name} |
Stop a secondary sink; its place in the trail and its export sequence are kept |
Prepare the endpoint and protected credential file:
export CONTROL_API="https://gateway.example.com/netlox/v1"
install -m 600 /dev/null ./control-plane.headers
printf 'Authorization: Bearer %s\n' "$CONTROL_PLANE_TOKEN" > ./control-plane.headers
curl --fail-with-body --silent --show-error --header @control-plane.headers \
"$CONTROL_API/audit/status" | jq '{available, running, last_write, write_failures, orphaned_intents}'
Check writer availability/running state, write and drop counters, active segment, retained bytes, and orphaned intent fields. Investigate missing records, persistence failures, and unknown mutation outcomes independently. Retain exact image identity with the observations.
Remote sink submission is not a delivery receipt. Verify receiver certificate
trust and independently locate a synthetic test record at the receiver before
using that path for operations. Review each sink's selection and progress;
status alone does not prove complete, unique, or durable external delivery.
See the metric reference for the frozen
loxilb_audit_* family contracts.
Gateway audit trail files live in their own directory (default /var/log/loxilb/audit/), which
the loxilb*.log filter of the log API never matches, so the log API cannot read
them.
Read logs through the API¶
Operators can page current and rotated logs without receiving shell access to the Gateway. The API returns newest entries first and follows an opaque cursor backward:
| Method | Path | Purpose |
|---|---|---|
GET |
/logs |
Read current or archived log lines |
GET |
/log-archives |
List archive names, compressed size, and modification time |
GET |
/log-archives/{filename} |
Download one archive |
Important response semantics:
-
REST log handlers resolve files under
/var/logand do not honor--log-dirorLOXILB_LOG_DIR; those settings affect writers only, so use the filesystem/aggregator when logs are written elsewhere; -
log_countis the number of lines in this page, not total file matches; total_sizeis the whole uncompressed file size;scanned_bytesis how much content the server examined for this page;- filtered searches stop after reaching the 32 MiB threshold and completing the current read
batch, so
scanned_bytesmay be slightly higher; .log.gzarchives are decompressed transparently for paging, with a 64 MiB decompressed-size ceiling;- a filtered page may contain no lines while
has_moreremains true, so clients must continue untilhas_more: false.
Use TLS and a least-privileged management identity. Treat every returned line as potentially sensitive, even when known secret-shaped fields are masked. The complete paging, archive, rotation, and cleanup procedure is in Log API Operations.
Audit review checklist¶
- Confirm system clocks are synchronized so events can be correlated.
- Record the immutable Gateway version and product flavor without including credentials or private topology.
- Query the smallest time, file, level, and keyword scope needed.
- Walk every cursor to
has_more: falsebefore concluding that no older match exists. - Correlate management changes with policy read-back and relevant metrics.
- Redact credentials, API keys, prompts, personal information, tenant names, client addresses, and internal hostnames before sharing evidence.
- Store exported evidence under the organization's access and retention policy, then securely remove temporary copies.
Verification boundary¶
API availability and local status are separate from retained records, receiver delivery, compliance acceptance, and recovery qualification. Validate the selected deployment's retention and failure/recovery behavior with independent evidence before relying on it.
For the metrics side of observability, see Grafana Dashboards and Observability.
Recovery and high-risk diagnostics need additional evidence beyond logs:
- Configuration Backup and Restore — checksums, dry-run, commit, rollback, and restore metrics;
- Application and L4 Tracing — trace data handling and OTLP verification;