Skip to Content

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

FilePathFormatRotation policy
Daemon log<LogDir>/agent.logJSON linesLumberjack 10 MB × 5
Audit log<LogDir>/audit.logJSON linesLumberjack 10 MB × 5
Daemon status<RunDir>/daemon.statusJSON snapshotOverwritten each tick
PID file<RunDir>/cmdop.pidtextReplaced on start

<LogDir> resolves per platform via internal/foundation/utils/paths.go:

  • macOS: ~/Library/Logs/cmdop/
  • Linux: ~/.local/state/cmdop/ (respects XDG_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.1 through agent.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 log

The 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-audit

Tuning 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.

Last updated on