#!/usr/bin/env bash # Regenerates every file under docs/output/ from a real run against a real grafana/otel-lgtm # container. Needs Docker, JDK 25 and several minutes -- Tempo's search index lags live traffic # by roughly a minute in this bundled all-in-one image, so this script waits for it rather than # racing it. Leaves the LGTM container running afterwards; `docker compose down` to stop it. set -euo pipefail cd "$(dirname "$0")/.." OUT="docs/output" mkdir -p "$OUT" mvn -q -DskipTests package echo "--- phase 1: default sampling (0.10), Docker Compose auto-wiring + real metrics ---" mvn -q spring-boot:run > /tmp/obs-run-default.log 2>&1 & APP_PID=$! until curl -sf http://localhost:8080/actuator/health > /dev/null 2>&1; do sleep 2; done { echo '$ mvn spring-boot:run' grep -E "DockerComposeLifecycleManager|DockerCli|Publishing metrics|Started Observability" /tmp/obs-run-default.log echo echo '$ docker ps' docker ps --filter name=lgtm } > "$OUT/00-docker-compose-auto-wiring.txt" for i in $(seq 1 8); do curl -s -X POST "http://localhost:8080/orders/$i" > /dev/null; done sleep 65 { echo "8 requests sent to /orders/{1..8}. Queried from LGTM's own Prometheus-compatible API:" echo '$ curl -s "http://localhost:9090/api/v1/query?query=orders_placed_total"' curl -s "http://localhost:9090/api/v1/query?query=orders_placed_total" | python3 -m json.tool } > "$OUT/01-metrics-and-traces-in-lgtm.txt" BASELINE_TRACES=$(curl -s "http://localhost:3200/api/search?limit=50" | python3 -c "import json,sys;print(len(json.load(sys.stdin)['traces']))") for i in $(seq 101 115); do curl -s -X POST "http://localhost:8080/orders/$i" > /dev/null; done sleep 90 AFTER_TRACES=$(curl -s "http://localhost:3200/api/search?limit=50" | python3 -c "import json,sys;print(len(json.load(sys.stdin)['traces']))") { echo "Default sampling probability (0.10): 15 requests sent, metric increases by 15," echo "trace count increases by only $((AFTER_TRACES - BASELINE_TRACES)) (baseline=$BASELINE_TRACES, after=$AFTER_TRACES)." } > "$OUT/02-low-sampling-demo.txt" kill "$APP_PID" 2>/dev/null || true wait "$APP_PID" 2>/dev/null || true echo "--- phase 2: fulltrace profile (1.0 sampling), @Observed span proof ---" mvn -q -Dspring-boot.run.profiles=fulltrace spring-boot:run > /tmp/obs-run-fulltrace.log 2>&1 & APP_PID=$! until curl -sf http://localhost:8080/actuator/health > /dev/null 2>&1; do sleep 2; done curl -s -X POST "http://localhost:8080/orders/777" > /dev/null sleep 90 TRACE_ID=$(curl -s "http://localhost:3200/api/search?limit=5" | python3 -c " import json,sys d=json.load(sys.stdin) t=sorted(d['traces'], key=lambda x:int(x['startTimeUnixNano']), reverse=True)[0] print(t['traceID']) ") { echo "Trace for the /orders/777 request just sent, fetched from Tempo:" curl -s "http://localhost:3200/api/traces/$TRACE_ID" | python3 -c " import json,sys d=json.load(sys.stdin) for b in d['batches']: for ss in b['scopeSpans']: for sp in ss['spans']: print('span:', sp['name'], '| kind:', sp['kind'], '| parent:', sp.get('parentSpanId','(root)')) " } > "$OUT/03-observed-needs-explicit-bean.txt" kill "$APP_PID" 2>/dev/null || true wait "$APP_PID" 2>/dev/null || true docker compose down echo "--- phase 3: standard OTEL_* env var support, Boot 4.0 vs 4.1 ---" ./scripts/run-env-var-proof.sh > "$OUT/04-otel-env-vars-4.0-vs-4.1.txt" 2>&1 echo "Done. See $OUT/*.txt"