Log Files
Where to find OpenClaw log files, how to configure log levels, rotate old logs, and useful patterns for log analysis.
Quick Fix — Find Your Logs Now
- Linux/Mac:
tail -f ~/.openclaw/logs/openclaw.log - Windows:
Get-Content "$env:APPDATA\openclaw\logs\openclaw.log" -Tail 50 -Wait - Enable debug mode:
openclaw run "task" --log-level debug - Last error only:
grep -i "error" ~/.openclaw/logs/openclaw.log | tail -5
Log File Locations
| Platform | Default Log Path |
|---|---|
| Linux | ~/.local/share/openclaw/logs/openclaw.log |
| macOS | ~/Library/Logs/openclaw/openclaw.log |
| Windows | %APPDATA%\openclaw\logs\openclaw.log |
| Custom (config) | Value of log_file in config.yaml |
# Quick: get log path
openclaw config show | grep log_file
# Tail the live log
tail -f ~/.local/share/openclaw/logs/openclaw.logConfiguring Log Output
# config.yaml
log_level: info # error | warning | info | debug | trace
log_file: /var/log/openclaw/openclaw.log
log_format: json # json or text
log_max_size_mb: 50 # rotate when file exceeds 50 MB
log_max_backups: 5 # keep last 5 rotated filesUseful grep Patterns
LOG=~/.local/share/openclaw/logs/openclaw.log
# All errors
grep "ERROR" $LOG
# Tool call failures
grep "TOOL_FAIL\|ToolExecutionError" $LOG
# Rate limit hits
grep "429\|RateLimitError" $LOG
# Last 100 lines filtered to errors/warnings
tail -100 $LOG | grep -E "ERROR|WARN"
# Count errors by type in last 500 lines
tail -500 $LOG | grep "ERROR" | awk '{print $5}' | sort | uniq -c | sort -rn
# Events in a time range (JSON logs)
cat $LOG | jq 'select(.timestamp >= "2024-01-15T09:00:00" and .level == "error")'Log Rotation
# OpenClaw rotates logs automatically when log_max_size_mb is set.
# You can also use logrotate on Linux:
# /etc/logrotate.d/openclaw
/home/user/.local/share/openclaw/logs/openclaw.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}JSON Log Analysis
When log_format: json is set, each log entry is a structured JSON object. This makes it easy to filter, aggregate, and monitor:
# Show last 20 errors with timestamp and message
cat ~/.local/share/openclaw/logs/openclaw.log \
| jq -r 'select(.level=="error") | "\(.timestamp) \(.message)"' \
| tail -20
# Count API calls per provider
cat openclaw.log | jq -r 'select(.event=="api_call") | .provider' \
| sort | uniq -c | sort -rn
# Total tokens used today
TODAY=$(date +%Y-%m-%d)
cat openclaw.log \
| jq "select(.timestamp | startswith(\"$TODAY\")) | .tokens_used // 0" \
| awk '{sum += $1} END {print "Total tokens today:", sum}'Live Log Monitoring
# Tail and filter — show errors in real-time
tail -f ~/.local/share/openclaw/logs/openclaw.log | grep --line-buffered "ERROR"
# With JSON format — pretty-print errors as they arrive
tail -f openclaw.log | jq -r 'select(.level == "error") | [.timestamp, .message] | @tsv'
# Alert on repeated errors
tail -f openclaw.log | grep "RateLimitError" | while read -r line; do
echo "ALERT: $(date) — rate limit hit"
# Add: send notification, email, etc.
doneExport Logs for Support
# Export last 1000 lines, sanitize API keys, zip for sharing
LOG=~/.local/share/openclaw/logs/openclaw.log
tail -1000 "$LOG" \
| sed 's/sk-[a-zA-Z0-9-]*/sk-***REDACTED***/g' \
| gzip > /tmp/openclaw-debug-$(date +%Y%m%d).log.gz
echo "Log exported to /tmp/openclaw-debug-$(date +%Y%m%d).log.gz"Log Levels Explained
| Level | Numeric | Meaning | When to use |
|---|---|---|---|
DEBUG | 10 | Detailed trace — tool inputs/outputs, prompt tokens, HTTP request bodies | Debugging a reproducible issue; very verbose, never in production |
INFO | 20 | Normal operation events — task started/completed, model selected, tool called | Default for production; provides an audit trail without noise |
WARNING | 30 | Non-fatal anomalies — retried request, deprecated config key, rate-limit hit | Should be monitored; indicates degraded performance |
ERROR | 40 | Task failed — tool execution error, API auth failure, file not found | Needs investigation; tasks may be incomplete |
CRITICAL | 50 | Service cannot continue — config corrupt, out of memory, port already in use | Immediate action required; OpenClaw will usually exit |
# ~/.openclaw/config.yaml
logging:
level: INFO # change to DEBUG only temporarily
format: json # json | text (text is human-readable)
output: file # file | stdout | bothSending Logs to External Services
For centralised observability across multiple OpenClaw instances, forward logs to a logging aggregator.
syslog (Linux/macOS)
# Pipe output to logger (add to your start command)
openclaw start 2>&1 | logger -t openclaw -p local0.info# Or configure in config.yaml
logging:
output: syslog
syslog_host: 127.0.0.1
syslog_port: 514Grafana Loki
# Promtail scrape config snippet
scrape_configs:
- job_name: openclaw
static_configs:
- targets: [localhost]
labels:
job: openclaw
__path__: /var/log/openclaw/*.log
pipeline_stages:
- json:
expressions:
level: level
msg: messageDatadog
# /etc/datadog-agent/conf.d/openclaw.d/conf.yaml
logs:
- type: file
path: /var/log/openclaw/openclaw.log
service: openclaw
source: python
tags:
- "env:production"Log Retention Policy Recommendations
| Environment | Retention | Notes |
|---|---|---|
| Development | 3–7 days | DEBUG level OK; rotate daily |
| Staging | 14 days | INFO level; mirror production setup |
| Production | 90 days minimum | INFO level; archive to object storage after 30 days |
| Compliance (SOC2/HIPAA) | 1–7 years | Check your specific regulation requirements |