Log rotation
CMDOP writes structured logs locally and ships nothing automatically. This guide covers what gets written, where, how rotation works, and how to ship to a centralized log store.
What CMDOP writes
| File | Path | Format | Rotation policy |
|---|---|---|---|
| Daemon log | <LogDir>/agent.log | JSON lines | Lumberjack 10 MB × 5 |
| Audit log | <LogDir>/audit.log | JSON lines | Lumberjack 10 MB × 5 |
| Daemon status | <RunDir>/daemon.status | JSON snapshot | Overwritten each tick |
| PID file | <RunDir>/cmdop.pid | text | Replaced on start |
<LogDir> resolves per platform via internal/foundation/utils/paths.go:
- macOS:
~/Library/Logs/cmdop/ - Linux:
~/.local/state/cmdop/(respectsXDG_STATE_HOME) - Windows:
%LOCALAPPDATA%\cmdop\Logs\
Built-in rotation
Both agent.log and audit.log use lumberjack :
- Max size 10 MB per file before rotation.
- Keep 5 archived files (
agent.log.1throughagent.log.5). - Maximum on-disk footprint per log: ~50 MB.
Rotation is purely size-driven. There is no time-based rotation.
Each daemon session is marked with === DAEMON SESSION START === so you can grep for boundaries even within a single file.
Tailing live
cmdop agent logs -f # daemon log
cmdop permissions audit --tail 50 # audit logThe CLI reads the rotated files in order, so --since 24h works across rotations.
Shipping to a centralized store
CMDOP does not bundle a log shipper — pick the one you already run.
Vector
[sources.cmdop]
type = "file"
include = ["~/.local/state/cmdop/agent.log*", "~/.local/state/cmdop/audit.log*"]
read_from = "beginning"
[transforms.parse_cmdop]
type = "remap"
inputs = ["cmdop"]
source = ". = parse_json!(.message)"
[sinks.datadog]
type = "datadog_logs"
inputs = ["parse_cmdop"]
default_api_key = "${DD_API_KEY}"Fluent Bit
[INPUT]
Name tail
Path /home/cmdop/.local/state/cmdop/*.log
Parser json
Tag cmdop.*Datadog Agent
logs:
- type: file
path: /home/cmdop/.local/state/cmdop/agent.log
service: cmdop
source: cmdop-agent
- type: file
path: /home/cmdop/.local/state/cmdop/audit.log
service: cmdop
source: cmdop-auditTuning rotation
The 10 MB × 5 default is hardcoded. To get tighter rotation, run an external rotator (logrotate on Linux):
/home/cmdop/.local/state/cmdop/agent.log {
daily
rotate 30
compress
delaycompress
missingok
notifempty
copytruncate
}copytruncate is important — CMDOP keeps the file handle open and does not understand SIGHUP.
Retention strategy
For compliance and post-incident review:
- Local — 50 MB by default; OK for week-of-debugging on busy hosts.
- SIEM — 90+ days for SOC 2; ship via Vector / Fluent Bit / Datadog.
- Cold archive — quarterly snapshots to S3 / GCS.
Audit log retention is also visible cabinet-side under Audit log.
The local log is local. If the disk fails or the machine is wiped, the history is gone. Ship to a centralized store for compliance.
Rotation is size-only — no SIGUSR1 for forced rotation. If you need a forced rotation (e.g. before destructive maintenance), truncate -s 0 after copying, or restart the daemon.