GoClaw's logging pipeline writes every log line to the Web UI's live log stream and, when each is enabled, to the console, a rotated file, syslog and an OpenTelemetry OTLP/HTTP exporter.
internal/logging/pipeline.go
flowchart TD
SETUP["<b>logging.Setup(ctx, cfg, logBroadcaster)</b>"] --> MULTI["<b>log.SetOutput(io.MultiWriter(writers...))</b>"]
MULTI --> W1["<b>LogBroadcaster</b><br/>SSE → Web UI (always)"]
MULTI --> W2["<b>os.Stdout</b><br/>(if console.enabled)"]
MULTI --> W3["<b>File</b><br/>(if file.enabled → gateway.log, rotated)"]
MULTI --> W4["<b>Syslog</b><br/>(if syslog.enabled; not on Windows)"]
MULTI --> W5["<b>otlpWriter</b><br/>(if otel.enabled + DSN)"]
W5 --> OTLP["<b>otlploghttp.Exporter → OTLP/HTTP</b><br/>• BatchProcessor → efficiency<br/>• Severity: ERROR/error → SeverityError"]
SETUP --> CLOSE["<b>CloseFunc</b><br/>Graceful shutdown (5s timeout)"]
| # | Feature | OpenClaw | GoClaw | Status |
|---|---|---|---|---|
| 4.1 | Console logging | ✅ | ✅ logging.console.enabled → os.Stdout |
Done |
| 4.2 | SSE log broadcast | ✅ WebSocket | ✅ gateway.LogBroadcaster → Web UI |
Done |
| 4.3 | File logging | ✅ | ✅ logging.file.enabled → ~/.goclaw/logs/gateway.log, rotated by size (lumberjack) |
Done |
| 4.3a | Syslog | — | ✅ logging.syslog.enabled → the OS log on Linux (journalctl -t goclaw). On macOS the messages do not reach the unified log (log show finds nothing); use the file log. Not on Windows |
Partial |
| 4.4 | Multi-writer pipeline | Separate outputs | ✅ io.MultiWriter(console, SSE, file, syslog, OTEL) |
Done |
| 4.5 | OpenTelemetry OTLP/HTTP export | — | ✅ otlploghttp.Exporter with batch processor |
GoClaw only |
| 4.6 | OTEL severity auto-detection | — | ✅ a line containing ERROR or error → SeverityError, else SeverityInfo |
GoClaw only |
| 4.7 | Custom OTEL headers | — | ✅ logging.otel.headers map |
GoClaw only |
| 4.8 | Insecure mode | — | ✅ logging.otel.insecure flag |
GoClaw only |
| 4.9 | Configurable service name | — | ✅ logging.otel.service_name (default: goclaw-gateway) |
GoClaw only |
| 4.10 | Resource attributes | — | ✅ semconv.ServiceName |
Done |
| 4.11 | Graceful shutdown | — | ✅ LoggerProvider.Shutdown (5s timeout), concurrent file closers |
GoClaw only |
| 4.12 | Structured JSON logging | ✅ | — | TODO |
logging:
console:
enabled: true
file:
enabled: true
path: "/var/log/goclaw/gateway.log"
max_size_mb: 100 # rotate at this size (default 100)
max_backups: 7 # rotated files to keep (default 7)
max_age_days: 30 # days to keep rotated files (default 30)
compress: false # gzip rotated files (default false)
syslog:
enabled: false
tag: "goclaw" # default "goclaw"
facility: "daemon" # "daemon" (default) or "local0"–"local7"
otel:
enabled: true
dsn: "https://otel-collector.example.com/v1/logs"
service_name: "goclaw-prod"
headers:
Authorization: "Bearer <token>"
insecure: false
| Package | Purpose |
|---|---|
otlploghttp |
OTLP/HTTP log exporter |
sdk/log |
LoggerProvider + BatchProcessor |
semconv/v1.26.0 |
Resource attribute conventions |
gopkg.in/lumberjack.v2 |
Log file rotation |
Structured JSON logging is not implemented.