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

PlatformDefault 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.log

Configuring 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 files

Useful 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.
done

Export 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

LevelNumericMeaningWhen to use
DEBUG10Detailed trace — tool inputs/outputs, prompt tokens, HTTP request bodiesDebugging a reproducible issue; very verbose, never in production
INFO20Normal operation events — task started/completed, model selected, tool calledDefault for production; provides an audit trail without noise
WARNING30Non-fatal anomalies — retried request, deprecated config key, rate-limit hitShould be monitored; indicates degraded performance
ERROR40Task failed — tool execution error, API auth failure, file not foundNeeds investigation; tasks may be incomplete
CRITICAL50Service cannot continue — config corrupt, out of memory, port already in useImmediate 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 | both

Sending 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: 514

Grafana 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: message

Datadog

# /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

EnvironmentRetentionNotes
Development3–7 daysDEBUG level OK; rotate daily
Staging14 daysINFO level; mirror production setup
Production90 days minimumINFO level; archive to object storage after 30 days
Compliance (SOC2/HIPAA)1–7 yearsCheck your specific regulation requirements