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:
| |
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 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:
| |
Field breakdown:
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)
Reload and Verify
Tell newsyslog to reload its configuration:
| |
Check that the config loaded correctly:
| |
Force an immediate rotation to test:
| |
Note: The
-Rflag with a requestor name is optional. Plainnewsyslog -v -f /path/to/configworks fine for testing.
Why Not Cron?
I considered a simple cron job:
| |
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:
| |
No manual intervention needed going forward. When either file crosses 10MB, newsyslog truncates it automatically.
