Skip to main content

Log Management

Runix captures stdout and stderr from every managed process into separate log files with optional rotation.

Log Storage​

~/.runix/apps/<name>/
├── stdout.log # Captured stdout
└── stderr.log # Captured stderr

Log Format​

Each line is prefixed with a timestamp and source marker by the PrefixWriter:

2025-01-15 10:30:00 [out] Server listening on :8080
2025-01-15 10:30:01 [out] Connected to database
2025-01-15 10:30:05 [err] Connection timeout to redis
2025-01-15 10:30:06 [err] Retry attempt 1/3

Implementation​

Capture​

Process output is captured via exec.Cmd pipes:

  1. cmd.StdoutPipe() → connected to a PrefixWriter wrapping the log file
  2. cmd.StderrPipe() → connected to a separate PrefixWriter
  3. Each writer prepends timestamps and [out]/[err] markers
  4. Writes are mutex-protected for thread safety

Rotation​

Located at internal/logrot/rotator.go, the Rotator provides size-based log rotation:

func NewRotator(path string, maxSize int64, maxFiles int, maxAge time.Duration) (*Rotator, error)

Configuration​

processes:
api:
entrypoint: ./cmd/api
logging:
max_size: 10485760 # 10MB in bytes
max_files: 5 # Keep 5 rotated files
max_age: 168h # 7 days

Rotation Process​

  1. Before each write, check if current_size + write_size >= max_size
  2. If so, rotate:
    • Close the current file
    • Rename to <name>.log.<timestamp> (e.g., stdout.log.2025-01-15T10-30-00)
    • Open a new file at the original path
    • Prune old files
  3. Pruning removes files exceeding max_files count or max_age duration

Pruning Rules​

RuleBehavior
max_files > 0Keep only the N newest rotated files
max_age > 0Remove files older than the duration
BothBoth rules applied

Default Values​

SettingDefault
max_size10MB (10,485,760 bytes)
max_files5
max_age168h (7 days)

Log Commands​

# View last 50 lines
runix logs api

# Stream live output
runix logs api --follow

# View stderr
runix logs api --stderr

# Error lines only
runix logs api --error

# Truncate log files
runix flush api
runix flush # All apps

What's Next​