OpenClaw Build and Operations (3/5) — Production Ops: launchd, systemd, Log Rotation
How --install-daemon works, the /tmp log path trap, openclaw.json hot reload, multi-agent routing in practice
ํต์ฌ ์์ฝ
- Audience: Past desktop testing — you want to run OpenClaw 24/7 on a home server or a small VPS.
- What you'll get: What
--install-daemonactually creates (launchd / systemd user service), the default log path (/tmp/openclaw/), how~/.openclaw/openclaw.jsonhot-reloads, multi-channel coexistence as JSON5, group-chat mention gating, and the 3-tier log-level precedence. - Prerequisite: #9 install + Discord in 30 minutes done. Basic familiarity with Linux/macOS process managers.
1. What the daemon actually is
Per the official README:
"OpenClaw Onboard installs the Gateway daemon (launchd/systemd user service)"
- macOS: launchd user agent (not system)
- Linux: systemd user service
Both are user scope — no root required. Works fine on shared machines inside your home directory.
openclaw onboard --install-daemon
The README doesn't pin the exact plist/service file paths. Conventional locations:
- macOS:
~/Library/LaunchAgents/com.openclaw.gateway.plist - Linux:
~/.config/systemd/user/openclaw.service
Verify on your system:
launchctl list | grep openclaw
ls ~/Library/LaunchAgents/ | grep openclaw
systemctl --user list-units | grep openclaw
systemctl --user status openclaw
2. Manual daemon management — restart, disable, remove
2.1 macOS (launchd)
launchctl unload ~/Library/LaunchAgents/com.openclaw.gateway.plist
launchctl unload ~/Library/LaunchAgents/com.openclaw.gateway.plist
launchctl load ~/Library/LaunchAgents/com.openclaw.gateway.plist
launchctl unload ~/Library/LaunchAgents/com.openclaw.gateway.plist
rm ~/Library/LaunchAgents/com.openclaw.gateway.plist
2.2 Linux (systemd user)
systemctl --user stop openclaw
systemctl --user restart openclaw
systemctl --user status openclaw
systemctl --user disable openclaw
systemctl --user stop openclaw
systemctl --user disable openclaw
rm ~/.config/systemd/user/openclaw.service
systemctl --user daemon-reload
2.3 In-session chat commands (not the daemon)
The README lists agent-session commands: /status, /restart, /reset, /compact, /think <level>, /verbose on|off, /trace on|off, /usage off|tokens|full, /activation mention|always.
These are session-level commands, not daemon management. To actually bounce the daemon, use 2.1 / 2.2 above.
3. Logs — location, level, subcommands
3.1 Default path
Per the official docs:
"The Gateway writes logs to
/tmp/openclaw/openclaw-YYYY-MM-DD.logby default, using the gateway host's local timezone."
/tmp is wiped at reboot. Move the path if you want retention.
3.2 Override the path
~/.openclaw/openclaw.json:
{
logging: {
file: "/var/log/openclaw/gateway.log"
}
}
The target directory must be writable. Prep system paths:
sudo mkdir -p /var/log/openclaw
sudo chown $USER /var/log/openclaw
3.3 Log level — 3-tier precedence
Official: env var > CLI flag > config.
export OPENCLAW_LOG_LEVEL=debug
openclaw gateway
openclaw gateway --log-level trace
Config example:
{
logging: {
level: "info", // file log level
consoleLevel: "warn" // console output level
}
}
Levels: trace > debug > info > warn > error.
3.4 Log subcommands
openclaw logs --follow
openclaw channels logs --channel discord
openclaw logs --follow --local-time --json
openclaw logs --follow --plain --no-color
For a remote gateway, combine --url + --token.
4. Log rotation — not built in
The docs only mention daily file naming (YYYY-MM-DD). No explicit rotation policy (size-based, retention, compression) is provided. Use OS-level logrotate.
4.1 Linux — /etc/logrotate.d/openclaw
/var/log/openclaw/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0644 myuser myuser
postrotate
systemctl --user reload openclaw 2>/dev/null || true
endscript
}
14-day retention, compression, postrotate reload so the gateway reopens file handles.
4.2 macOS — newsyslog.d
macOS uses newsyslog, not logrotate. /etc/newsyslog.d/openclaw.conf:
/var/log/openclaw/gateway.log myuser:wheel 644 14 * $D0 J
14 rotations, daily, gzip compression.
5. Hot reload — edit config, no restart
Per the official docs:
"The gateway automatically monitors
openclaw.jsonfor changes and applies safe updates without restart. Configuration must pass strict schema validation before loading — unknown keys or malformed types cause startup failure."
Practical implications:
- Safe changes apply live (adding channels, adjusting log level, reconfiguring bindings).
- Schema failure is a startup failure — existing gateway keeps running with the old config.
- Validate with:
openclaw doctor
Edit-apply pattern:
vim ~/.openclaw/openclaw.json
openclaw doctor
openclaw logs --follow
Changes that can't hot-reload (e.g., the gateway port itself) need a daemon restart.
6. Multi-channel coexistence — one gateway, many messengers
Per the docs, 22+ channels can run concurrently. Each under channels.<provider>.
6.1 JSON5 example (Discord + Telegram + Slack)
{
channels: {
discord: {
enabled: true,
token: { ref: { provider: "default", source: "env", id: "DISCORD_BOT_TOKEN" } },
dmPolicy: "pairing",
allowFrom: ["discord:123456789"]
},
telegram: {
enabled: true,
botToken: { ref: { provider: "default", source: "env", id: "TELEGRAM_BOT_TOKEN" } },
dmPolicy: "allowlist",
allowFrom: ["tg:123"]
},
slack: {
enabled: true,
token: { ref: { provider: "default", source: "env", id: "SLACK_BOT_TOKEN" } },
dmPolicy: "pairing"
}
}
}
6.2 DM Policy — four options
Official:
| Value | Behavior |
|---|---|
"pairing" (default) |
Unknown senders receive one-time approval codes |
"allowlist" |
Only entries in allowFrom allowed |
"open" |
All DMs accepted (risky — requires allowFrom: ["*"]) |
"disabled" |
All DMs ignored |
For public-server bots, "allowlist" is safest. Avoid "open" outside automated testing.
7. Multi-agent routing — one gateway, multiple bots
7.1 Per-agent workspaces
{
agents: {
list: [
{ id: "home", default: true, workspace: "~/.openclaw/workspace-home" },
{ id: "work", workspace: "~/.openclaw/workspace-work" }
]
},
bindings: [
{ agentId: "home", match: { channel: "whatsapp", accountId: "personal" } },
{ agentId: "work", match: { channel: "whatsapp", accountId: "biz" } }
]
}
Each inbound message resolves to an agent via bindings. Each agent gets its own workspace / skills / memory.
7.2 Default agent
{
agents: {
defaults: {
workspace: "~/.openclaw/workspace",
sandbox: { mode: "non-main" } // mandatory if you share channels
}
}
}
The README's security rule: default main session runs tools on the host with full access. When channels are shared, sandbox.mode: "non-main" is the safety line.
8. Group chat — mention gating
A bot that replies to every message floods the group. Gate with mentions.
{
agents: {
list: [{
id: "main",
groupChat: {
mentionPatterns: ["@openclaw", "openclaw", "hey claw"]
}
}]
},
channels: {
whatsapp: {
groups: { "*": { requireMention: true } }
},
discord: {
groups: { "*": { requireMention: true } }
}
}
}
mentionPatterns: supports native @-mentions plus regex text patterns.requireMention: true: only replies when mentioned in groups. DMs unaffected.
9. Config file structure — six top-level sections
~/.openclaw/openclaw.json (JSON5 format) key sections:
{
gateway: { port: 18789 /* server, auth, health */ },
agents: { /* model, skills, sandbox */ },
channels: { /* per-provider settings */ },
session: { /* conversation scope, reset policy */ },
cron: { /* scheduled jobs */ },
hooks: { /* webhooks */ }
}
Knowing these six makes reference-doc navigation fast.
9.1 Why JSON5
- Allows comments (
//,/* */) - Trailing commas OK
- Single quotes OK
More maintainable than plain JSON. For editor highlighting, using .json5 extension helps on GitHub.
10. Monitoring — minimum observability set
For a personal production deployment, don't skip:
10.1 openclaw doctor
openclaw doctor
Checks Node version, gateway state, channel connectivity, token validity, config schema. Automate with cron and alert on failure:
*/10 * * * * /usr/local/bin/openclaw doctor > /tmp/openclaw-doctor.log 2>&1 || osascript -e 'display notification "OpenClaw doctor FAIL" with title "OpenClaw"'
10.2 openclaw channels status --probe
Actively probes each channel's connection.
10.3 Keyword-filtered log watch
openclaw logs --follow | grep -Ei 'error|fatal|panic|disconnected'
11. Resource consumption — observable bounds
Official docs don't publish hard numbers. From observation:
- Memory: scales with gateway + connected channels + active sessions. Common range: 100–400 MB.
- Disk:
/tmp/openclaw/*.loggrows fast over time. Move path + logrotate are mandatory. - Network: each messenger's persistent connection + API calls. Running 24/7 often consumes several GB/month.
- Restart cadence: no official guidance, but weekly restarts are prudent against memory leaks.
0 4 * * 0 systemctl --user restart openclaw
12. Counter-scenarios — don't go to production if…
- Desktop-only use → Skip the daemon; run
openclaw gatewaymanually. Easier to cycle. - You already use PM2 or similar → Wrapping OpenClaw with PM2 works, but don't collide with
--install-daemon. - You want Docker isolation → No official Docker image in the README. Custom Dockerfile needed, with PTY and channel credential mounts — high complexity.
- You need strict audit retention → OpenClaw's built-in logging is weak. Stream into journald + an external SIEM.
13. Production checklist
- [ ]
--install-daemoninstalled launchd / systemd user service - [ ] Log path moved out of
/tmp/vialogging.file - [ ] logrotate / newsyslog configured (14 days, compress)
- [ ] Default
OPENCLAW_LOG_LEVEL=info; raise todebug/traceonly while debugging - [ ] Shared channels have
agents.defaults.sandbox.mode = "non-main" - [ ] Group chats set
requireMention: true+mentionPatterns - [ ] DM Policy defaults to
"allowlist"(new senders need explicit approval) - [ ]
openclaw doctorcron every 10 min with failure alerting - [ ] Weekly restart cron (memory leak hedge)
- [ ] Env vars (tokens) split into systemd
Environment=or.env.local
14. What's next
With production stable:
- OpenClaw ↔ Claude Code bridge — channel trigger → code execution (coming soon)
- OpenClaw install + Discord in 30 min — foundation.
- Claude Code hooks complete guide — for code-automation hook patterns.
References
This is post 10/15 in the "AI Coding CLI Entry Guide" series.
last verified: 2026-04-25 (per openclaw/openclaw README + docs.openclaw.ai).
Series overview: Series index
๋๊ธ
๋๊ธ ์ฐ๊ธฐ