Skip to content

mashiro/otelop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

168 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

otelop

otelop

A local OpenTelemetry viewer for traces, metrics, and logs. Single binary, in-memory, browser UI.

Go React License


What it is

otelop runs a local OTLP receiver and shows whatever it gets in a browser. No Docker, no database, no Jaeger/Prometheus/Loki to wire up. Start the binary, point your app at it, open the page.

It's meant for the loop where you're writing instrumentation and just want to see what came through.

otelop trace view

Features

  • Single binary with the frontend embedded
  • OTLP gRPC and HTTP receivers (built-in OpenTelemetry Collector)
  • Optional OTLP forwarding to one upstream endpoint
  • Traces, metrics, and logs in one UI
  • Live updates over WebSocket
  • GraphQL API at /graphql
  • MCP server, so agents can query the same data
  • In-memory ring buffers — no persistence, no setup

Install

With Go:

go install github.com/mashiro/otelop/cmd/otelop@latest

With mise:

mise use -g github:mashiro/otelop

With Docker:

docker run --rm -p 4317:4317 -p 4318:4318 -p 4319:4319 ghcr.io/mashiro/otelop:latest

Quick start

otelop start

This detaches into the background so your terminal stays free. Use otelop status to see what it is listening on and otelop stop to shut it down. Pass --foreground (or -f) if you want logs in the current terminal.

Then point your app at it:

OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 your-app

And open http://localhost:4319.

With AI coding agents

Any AI coding agent that supports OpenTelemetry can export to otelop, so you can watch the agent's API calls, tool runs, and prompts live. For example:

Endpoints

Port Purpose
4319 Web UI + GraphQL
4317 OTLP gRPC receiver
4318 OTLP HTTP receiver

Commands

otelop start [flags]   # launch in the background (default), or foreground with -f
otelop stop            # stop the background server
otelop status          # show PID, listen addresses, and buffered counts
otelop version

start flags:

  --foreground, -f   run in the foreground instead of detaching
  --http             Web UI listen address           (default :4319)
  --otlp-grpc        OTLP gRPC receiver endpoint     (default 0.0.0.0:4317)
  --otlp-http        OTLP HTTP receiver endpoint     (default 0.0.0.0:4318)
  --proxy-url        upstream OTLP endpoint for forwarding
  --proxy-protocol   upstream OTLP protocol          (grpc|http)
  --proxy-auth-type  upstream OTLP auth type         (bearer|basic|headers)
  --proxy-auth-token upstream bearer token
  --proxy-auth-username upstream basic auth username
  --proxy-auth-password upstream basic auth password
  --proxy-header     upstream header                 (repeatable key=value)
  --trace-cap        max traces in memory            (default 1000)
  --metric-cap       max metric series in memory     (default 3000)
  --log-cap          max log entries in memory       (default 5000)
  --max-data-points  max data points per series      (default 1000)
  --log-level        debug|info|warn|error           (default warn)

PID, log, and metadata files live in $XDG_STATE_HOME/otelop/ (defaults to ~/.local/state/otelop/).

Configuration

Every start flag can be set three ways. Higher precedence wins:

  1. CLI flag (otelop start --http :4319)
  2. Environment variable (OTELOP_HTTP=:4319 otelop start)
  3. TOML config file at $XDG_CONFIG_HOME/otelop/config.toml (defaults to ~/.config/otelop/config.toml; override with OTELOP_CONFIG_FILE=/path/to/config.toml)

Example ~/.config/otelop/config.toml:

http = ":4319"
otlp_grpc = "0.0.0.0:4317"
otlp_http = "0.0.0.0:4318"
trace_cap = 1000
metric_cap = 3000
log_cap = 5000
max_data_points = 1000
log_level = "warn"
debug = false

[proxy]
url = "https://collector.internal:4318"
protocol = "http"

[proxy.auth]
type = "bearer"
token = "replace-me"

The matching environment variables are OTELOP_HTTP, OTELOP_OTLP_GRPC, OTELOP_OTLP_HTTP, OTELOP_PROXY_URL, OTELOP_PROXY_PROTOCOL, OTELOP_PROXY_AUTH_TYPE, OTELOP_PROXY_AUTH_TOKEN, OTELOP_PROXY_AUTH_USERNAME, OTELOP_PROXY_AUTH_PASSWORD, OTELOP_PROXY_HEADERS, OTELOP_TRACE_CAP, OTELOP_METRIC_CAP, OTELOP_LOG_CAP, OTELOP_MAX_DATA_POINTS, OTELOP_LOG_LEVEL, and OTELOP_DEBUG.

When proxying is enabled, otelop still buffers incoming telemetry locally for the UI and also forwards the same traces, metrics, and logs to the configured upstream OTLP endpoint.

proxy.auth.type supports:

  • bearer: sends Authorization: Bearer <token>
  • basic: sends Authorization: Basic <base64(username:password)>
  • headers: sends the exact headers configured under [proxy.auth.headers] or --proxy-header

Do not embed credentials in proxy.url; otelop rejects URLs with userinfo such as https://user:pass@example.com.

License

MIT

About

Local OTel viewer for dev loops — single binary, in-memory, browser UI.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors