ote (otel-explorer)
See where your CI/CD time actually goes.
Install · Quick Start · Features · Trends · OpenTelemetry
An interactive terminal tool that turns OpenTelemetry traces and CI/CD runs into navigable timelines — so you can find the slow jobs, the flaky tests, and the queue-time bottlenecks. Works with GitHub Actions, Jenkins, GitLab CI, Buildkite, Dagger, and any system that emits OTel traces.
brew install stefanpenner/tap/oteOr install the latest binary with curl (macOS and Linux):
curl -fsSL https://raw.githubusercontent.com/stefanpenner/otel-explorer/main/install.sh | shOr with Go:
go install github.com/stefanpenner/otel-explorer/cmd/ote@latestPoint it at any PR or commit:
ote nodejs/node/pull/60369That's it. If you have GitHub CLI installed and authenticated, the token is picked up automatically. Otherwise:
export GITHUB_TOKEN="your_token_here"The default view is a full-screen terminal UI with a tree of workflows, jobs, and steps on the left and a Gantt-style timeline on the right. Navigate with arrow keys or vim bindings, expand/collapse nodes, multi-select ranges, search, and drill into details.
Export any analysis as a Perfetto trace for deep-dive visualization with full zoom, search, and flame-chart views:
ote <url> --perfetto=trace.pftrace --open-in-perfettoPull traces directly from Grafana Tempo or Jaeger:
ote --tempo=http://localhost:3200 --trace-id=abc123
ote --jaeger=http://localhost:16686 --trace-id=abc123Pipe a GitHub Actions webhook payload to analyze the associated commit — useful for event-driven analysis:
echo '{"workflow_run":{"head_sha":"abc123"},"repository":{"full_name":"owner/repo"}}' \
| ote --otelBeyond raw timings, the analyzer enriches spans with:
- Queue time — how long jobs waited for a runner
- Runner distribution — which runners ran which jobs
- Billable minutes — computed cost breakdown
- Retry detection — identifies re-run jobs and counts attempts
- PR annotations — review approvals, comments, merge events shown as markers on the timeline
- CI/CD pipeline recognition — auto-classifies spans using OTel CI/CD semantic conventions (
cicd.pipeline.*attributes)
Analyze workflow performance over time to spot regressions, flaky jobs, and slow-downs:
ote trends owner/repo # last 30 days
ote trends owner/repo --days=7 --branch=main # scoped
ote trends owner/repo --format=json # machine-readable================================================================================
Historical Trend Analysis: stefanpenner/otel-explorer
================================================================================
Summary Statistics
------------------
Average Duration 1m 46s
Median Duration 1m 41s
95th Percentile 3m 13s
Average Success Rate 61.7%
Trend Direction Improving (-20.7%)
Flaky Jobs Detected 1
Trend analysis covers success rates, duration percentiles, per-job breakdowns, flaky detection (>10% failure rate), and trend direction. For large repos, it uses stratified temporal sampling to keep API usage reasonable — run-level metrics are always exact, job-level analysis is sampled at 95% confidence / ±10% margin by default.
ote trends owner/repo --no-sample # exact, more API calls
ote trends owner/repo --confidence=0.99 --margin=0.05 # tune samplingExport analysis data as OpenTelemetry spans — feed them into any observability stack:
# JSON spans to stdout
ote <url> --otel
# OTLP/HTTP
ote <url> --otel=localhost:4318
# OTLP/gRPC
ote <url> --otel-grpc=localhost:4317You can also ingest OTel trace files from any CI/CD system — Jenkins, GitLab CI, Buildkite, Dagger, and anything else that emits traces following the OTel CI/CD semantic conventions:
ote --trace=spans.jsonBuilt with Bazel for hermetic, reproducible builds.
bazel run //:ote -- <url> # run
bazel build //... # build all
bazel test //... # test all
bazel run //:gazelle # regenerate BUILD filesMIT