diff --git a/.gitignore b/.gitignore index c596a60a..169de188 100644 --- a/.gitignore +++ b/.gitignore @@ -146,3 +146,6 @@ thoughtbox-web-two/ .specs/channel-daemon/chatgpt01.md rlm-code/ + +# OTEL collector file-exporter output (host backing for /var/log/otel) +otel-collector/data/ diff --git a/docker-compose.yml b/docker-compose.yml index 6c9ede70..69e6ce86 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,8 +66,20 @@ services: otel-collector: image: otel/opentelemetry-collector-contrib:0.113.0 command: ["--config=/etc/otelcol/config.yaml"] + # Run as root so the container can write to the mounted host path + # regardless of who owns it. Avoids uid 10001 / macOS perm friction. + user: "0:0" + environment: + # In-container directory the file exporter writes to. Fixed — it's + # the mount point. The HOST backing is the volume below, which + # honors CLAUDE_CODE_TMPDIR when set in the shell that runs compose. + OTEL_FILE_EXPORT_DIR: /var/log/otel volumes: - ./otel-collector/config-with-prometheus.yaml:/etc/otelcol/config.yaml:ro + # Sub-namespace under CLAUDE_CODE_TMPDIR so collector output doesn't + # share a directory with Claude Code's per-uid runtime tmpdir + # (claude-/). Files land at $CLAUDE_CODE_TMPDIR/otel/ on host. + - ${CLAUDE_CODE_TMPDIR:-./otel-collector/data}/otel:/var/log/otel ports: - "4318:4318" - "8889:8889" diff --git a/otel-collector/config-with-prometheus.yaml b/otel-collector/config-with-prometheus.yaml index 61462d23..d3cd58d3 100644 --- a/otel-collector/config-with-prometheus.yaml +++ b/otel-collector/config-with-prometheus.yaml @@ -31,13 +31,15 @@ exporters: namespace: mcp debug: verbosity: basic + # OTEL_FILE_EXPORT_DIR resolves inside the container; the host backing + # is set in docker-compose.yml and honors CLAUDE_CODE_TMPDIR when present. file/logs: - path: /tmp/claude-code-events.jsonl + path: ${env:OTEL_FILE_EXPORT_DIR}/claude-code-events.jsonl rotation: max_megabytes: 100 max_days: 7 file/metrics: - path: /tmp/claude-code-metrics.jsonl + path: ${env:OTEL_FILE_EXPORT_DIR}/claude-code-metrics.jsonl rotation: max_megabytes: 50 max_days: 7 diff --git a/otel-collector/config.yaml b/otel-collector/config.yaml index 493b2ddf..31a86158 100644 --- a/otel-collector/config.yaml +++ b/otel-collector/config.yaml @@ -15,16 +15,19 @@ exporters: debug: verbosity: detailed - # File exporter for persistent logs + # File exporter for persistent logs. + # Path is configurable via OTEL_FILE_EXPORT_DIR (in-container); the host + # backing of that directory is set in docker-compose.yml and honors + # CLAUDE_CODE_TMPDIR when present. file/logs: - path: /tmp/claude-code-events.jsonl + path: ${env:OTEL_FILE_EXPORT_DIR}/claude-code-events.jsonl rotation: max_megabytes: 100 max_days: 7 max_backups: 5 file/metrics: - path: /tmp/claude-code-metrics.jsonl + path: ${env:OTEL_FILE_EXPORT_DIR}/claude-code-metrics.jsonl rotation: max_megabytes: 50 max_days: 7 diff --git a/otel-collector/enable-telemetry.sh b/otel-collector/enable-telemetry.sh index c345d103..88e404f6 100755 --- a/otel-collector/enable-telemetry.sh +++ b/otel-collector/enable-telemetry.sh @@ -6,6 +6,13 @@ # # Or add these to your shell profile (~/.zshrc, ~/.bashrc) +# Where the OTEL collector should drop file-exported logs/metrics on the +# HOST. docker-compose interpolates this; if unset, falls back to the +# project-local ./otel-collector/data directory. Honors any project- or +# user-level override of CLAUDE_CODE_TMPDIR already in the shell env. +: "${CLAUDE_CODE_TMPDIR:=$(cd "$(dirname "${BASH_SOURCE[0]}")/data" && pwd)}" +export CLAUDE_CODE_TMPDIR + # Required: Enable telemetry export CLAUDE_CODE_ENABLE_TELEMETRY=1