Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ analysis_results/
prometheus_data/
grafana_data/
loki_data/
.docker-local/

# Temporary files
tmp/
temp/
temp/
23 changes: 12 additions & 11 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Claude Code Observability Stack
.PHONY: help up down logs restart clean validate-config
DOCKER_COMPOSE := ./scripts/docker-compose.sh

help: ## Show this help message
@echo "Claude Code Observability Stack"
Expand All @@ -10,7 +11,7 @@ help: ## Show this help message

up: ## Start the observability stack
@echo "🚀 Starting Claude Code observability stack..."
docker compose up -d
$(DOCKER_COMPOSE) up -d
@echo "✅ Stack started!"
@echo "📊 Grafana: http://localhost:3000 (admin/admin)"
@echo "🔍 Prometheus: http://localhost:9090"
Expand All @@ -19,29 +20,29 @@ up: ## Start the observability stack

down: ## Stop the observability stack
@echo "🛑 Stopping Claude Code observability stack..."
docker compose down
$(DOCKER_COMPOSE) down
@echo "✅ Stack stopped!"

restart: ## Restart the observability stack
@echo "🔄 Restarting Claude Code observability stack..."
docker compose restart
$(DOCKER_COMPOSE) restart
@echo "✅ Stack restarted!"

logs: ## Show logs from all services
docker compose logs -f
$(DOCKER_COMPOSE) logs -f

logs-collector: ## Show OpenTelemetry collector logs
docker compose logs -f otel-collector
$(DOCKER_COMPOSE) logs -f otel-collector

logs-prometheus: ## Show Prometheus logs
docker compose logs -f prometheus
$(DOCKER_COMPOSE) logs -f prometheus

logs-grafana: ## Show Grafana logs
docker compose logs -f grafana
$(DOCKER_COMPOSE) logs -f grafana

clean: ## Clean up containers and volumes
@echo "🧹 Cleaning up..."
docker compose down -v
$(DOCKER_COMPOSE) down -v
docker system prune -f
@echo "✅ Cleanup complete!"

Expand All @@ -52,7 +53,7 @@ clean: ## Clean up containers and volumes
validate-config: ## Validate all configuration files
@echo "✅ Validating configurations..."
@echo "📋 Checking docker compose.yml..."
docker compose config > /dev/null && echo "✅ docker compose.yml is valid"
@$(DOCKER_COMPOSE) config > /dev/null && echo "✅ docker compose.yml is valid"
@echo "📋 Checking collector-config.yaml..."
@if command -v otelcol-contrib >/dev/null 2>&1; then \
otelcol-contrib --config-validate --config=collector-config.yaml; \
Expand All @@ -64,7 +65,7 @@ validate-config: ## Validate all configuration files
status: ## Show stack status
@echo "📊 Claude Code Observability Stack Status"
@echo "==========================================="
@docker compose ps
@$(DOCKER_COMPOSE) ps
@echo ""
@echo "🌐 Service URLs:"
@echo " Grafana: http://localhost:3000"
Expand Down Expand Up @@ -94,4 +95,4 @@ setup-claude: ## Display Claude Code telemetry setup instructions
demo-metrics: ## Generate demo metrics for testing
@echo "🎯 This would generate demo metrics if Claude Code was running"
@echo "💡 To see real metrics, ensure Claude Code is configured with telemetry enabled"
@echo "📖 Run 'make setup-claude' for setup instructions"
@echo "📖 Run 'make setup-claude' for setup instructions"
21 changes: 21 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Changelog

## 2026-02-24

### Added
- `start.sh` script to:
- check Docker CLI availability
- show an English message if Docker Desktop is not running
- run `make up`
- export Claude Code telemetry variables
- launch `claude`
- `scripts/docker-compose.sh` wrapper that detects missing `docker-credential-desktop` and uses a local fallback `DOCKER_CONFIG`.

### Changed
- `Makefile` now routes Docker Compose commands through `./scripts/docker-compose.sh` via `DOCKER_COMPOSE := ./scripts/docker-compose.sh`.
- `.gitignore` now ignores `.docker-local/` to avoid committing local Docker fallback config.

### Notes
- Root issue fixed: `docker compose` failed with:
`error getting credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH`.
- Current remaining startup risk is transient network/image pull errors (e.g. Docker Hub `504 Gateway Time-out`), unrelated to credential helper configuration.
37 changes: 37 additions & 0 deletions scripts/docker-compose.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/usr/bin/env sh
set -eu

SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
REPO_ROOT="$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)"

if command -v docker-credential-desktop >/dev/null 2>&1; then
exec docker compose "$@"
fi

DOCKER_CONFIG_DIR="${DOCKER_CONFIG:-$HOME/.docker}"
DOCKER_CONFIG_FILE="$DOCKER_CONFIG_DIR/config.json"

if [ -f "$DOCKER_CONFIG_FILE" ] && grep -Eq '"credsStore"[[:space:]]*:[[:space:]]*"desktop"' "$DOCKER_CONFIG_FILE"; then
FALLBACK_DOCKER_CONFIG="${CLAUDE_OTEL_DOCKER_CONFIG:-$REPO_ROOT/.docker-local}"
mkdir -p "$FALLBACK_DOCKER_CONFIG"

# Keep user's Docker context/plugin setup, but remove the desktop creds helper.
sed '/"credsStore"[[:space:]]*:/d' "$DOCKER_CONFIG_FILE" > "$FALLBACK_DOCKER_CONFIG/config.json"

for shared_dir in cli-plugins contexts; do
source_path="$DOCKER_CONFIG_DIR/$shared_dir"
target_path="$FALLBACK_DOCKER_CONFIG/$shared_dir"
if [ -e "$source_path" ] && [ ! -e "$target_path" ]; then
ln -s "$source_path" "$target_path"
fi
done

if [ ! -f "$FALLBACK_DOCKER_CONFIG/config.json" ]; then
printf '{\n "auths": {}\n}\n' > "$FALLBACK_DOCKER_CONFIG/config.json"
fi

printf '%s\n' "docker-credential-desktop not found. Using fallback DOCKER_CONFIG=$FALLBACK_DOCKER_CONFIG" >&2
exec env DOCKER_CONFIG="$FALLBACK_DOCKER_CONFIG" docker compose "$@"
fi

exec docker compose "$@"
30 changes: 30 additions & 0 deletions start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail

REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$REPO_ROOT"

if ! command -v docker >/dev/null 2>&1; then
echo "Docker is not installed. Please install Docker Desktop first."
exit 1
fi

if ! docker info >/dev/null 2>&1; then
echo "Docker Desktop is not running. Please start Docker Desktop, wait until it is fully started, then run ./start.sh again."
exit 1
fi

echo "Starting Claude Code observability stack..."
make up

echo "Configuring telemetry environment variables..."
export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
export OTEL_METRIC_EXPORT_INTERVAL=10000
export OTEL_LOGS_EXPORT_INTERVAL=5000

echo "Starting Claude Code..."
claude