Using macOS newsyslog to Rotate Service Logs

Feb 25, 2026

I noticed my OpenClaw gateway log files were growing unbounded. The service runs via launchd, and while the app has built-in log rotation, the stdout/stderr capture in the launchd plist was bypassing it entirely.

The Problem

When a macOS service uses StandardOutPath and StandardErrorPath in its launchd plist, those files just append forever. My logs had grown to 38MB with no mechanism to clean them up:

1
2
3
$ ls -lh ~/.openclaw/logs/
-rw-r--r--  1 clawd  staff  3.9M Feb 25 17:48 gateway.log
-rw-r--r--  1 clawd  staff  38M  Feb 25 17:48 gateway.err.log

OpenClaw’s internal logger writes date-based rotating logs to /tmp/openclaw/, but launchd’s stdout capture writes directly to the configured files, bypassing that rotation logic.

The Hidden Trap: When log rotation tools like newsyslog create new log files, they default to root:root ownership. If your launchd service runs as your user (not root), it suddenly can’t write to its own log files after rotation. The daemon fails to start with “Permission denied” errors, and you’re left wondering why your service won’t start.

The Solution: newsyslog

macOS includes newsyslog, a utility for managing log file rotation. It’s already running on your system, checking logs periodically via launchd. You just need to tell it about your custom log files.

Configuration

Create a config file for your service logs:

1
2
3
4
5
sudo tee /etc/newsyslog.d/openclaw.conf << 'EOF'
# OpenClaw gateway logs - rotate at 10MB, keep zero archives
/Users/clawd/.openclaw/logs/gateway.log    clawd:staff    644  0  10000  *  B
/Users/clawd/.openclaw/logs/gateway.err.log    clawd:staff    644  0  10000  *  B
EOF

Important: Notice the clawd:staff owner:group fields. Without these, newsyslog creates the new log files as root:root after rotation. When your launchd service tries to write to a root-owned file, it gets “Permission denied” and the daemon fails to start.

Field breakdown:

  • clawd:staff — Owner and group for the log files (critical!)
  • 644 — File permissions (owner read/write, others read-only)
  • 0 — Number of archived files to keep (zero = just truncate)
  • 10000 — Size threshold in KB (~10MB)
  • * — Rotate at any time (not just specific hours)
  • B — Treat as binary (no special encoding)

What Happens Without Owner Specified

If you omit the owner:group fields, you’ll see this after newsyslog runs:

1
2
3
$ ls -la ~/.openclaw/logs/
-rw-r--r--  1 root   wheel     0 Feb 25 18:30 gateway.log
-rw-r--r--  1 root   wheel     0 Feb 25 18:30 gateway.err.log

Then your service fails to start with errors like:

Could not open log file /Users/clawd/.openclaw/logs/gateway.log: Permission denied
Service exited with abnormal code: 1

The clawd:staff fields ensure the rotated files remain owned by your user, not root.

Reload and Verify

Tell newsyslog to reload its configuration:

1
sudo killall -HUP newsyslog

Check that the config loaded correctly:

1
sudo newsyslog -v -f /etc/newsyslog.d/openclaw.conf

Force an immediate rotation to test:

1
sudo newsyslog -v -f /etc/newsyslog.d/openclaw.conf -R "manual" ~/.openclaw/logs/gateway.err.log

Note: The -R flag with a requestor name is optional. Plain newsyslog -v -f /path/to/config works fine for testing.

Why Not Cron?

I considered a simple cron job:

1
0 3 * * * truncate -s 0 ~/.openclaw/logs/gateway.log

That would work, but newsyslog is the native macOS tool for this. It’s already running, already has permission handling figured out, and rotates based on file size rather than just time. If your log suddenly explodes to 500MB, newsyslog catches it on the next check cycle (every 30 minutes). Cron would wait until 3 AM.

Result

After setup, my 38MB error log was truncated to zero bytes:

1
2
3
$ ls -lh ~/.openclaw/logs/
-rw-r--r--  1 clawd  staff  4.9M Feb 25 18:02 gateway.log
-rw-r--r--  1 clawd  staff   0B  Feb 25 18:10 gateway.err.log

No manual intervention needed going forward. When either file crosses 10MB, newsyslog truncates it automatically.

References

How TosProgrammingmacOSlogginglaunchdnewsyslogopenclaw

Building the Weather-NWS Skill for OpenClaw

Tag-Teaming Claude Code with an AI Agent via Tmux