I built a lightweight OpenTelemetry viewer for local development
Source: Dev.to
The problem
Every time I wanted to test OpenTelemetry instrumentation locally, I had to spin up Jaeger or a full collector stack. docker‑compose up, wait, configure exporters, hope nothing clashes on port 4317… It felt like too much ceremony for a “does my trace look right?” check.
So I built otel‑front: a single binary that receives OTLP data and shows it in a web UI. No Docker, no external database, no config files.
brew tap mesaglio/otel-front
brew install mesaglio/otel-front/otel-front
otel-front # → opens http://localhost:8000Point your app at localhost:4318 (HTTP) or localhost:4317 (gRPC) and that’s it.
What it does

- Traces – waterfall view, flame graph, side‑by‑side trace comparison, search by operation or trace ID
- Logs – full‑text search, severity/service filters, correlation with traces via
trace_id - Metrics – query builder, time‑series charts, aggregations (avg, sum, min, max, count)
Traces

Side‑by‑side comparison to spot regressions between two runs:

Logs correlated by trace_id directly from a trace view:

Logs

Metrics

How it’s built
Constraint: single binary, zero external dependencies.
Go + embedded frontend
The backend is Go (Gin). The React frontend is built with Vite and then embedded directly into the binary using Go’s embed.FS:
//go:embed static/*
var staticFiles embed.FSOne go build, one binary that serves everything.
DuckDB as in‑memory store
I needed SQL (for flexible filtering and aggregations) without shipping a database. DuckDB runs entirely in‑process, zero setup, and handles analytical queries well.
All spans, logs, and metrics land in DuckDB tables with JSON columns for attributes, e.g.:
CREATE TABLE spans (
trace_id TEXT,
span_id TEXT,
name TEXT,
start_time_unix_nano BIGINT,
end_time_unix_nano BIGINT,
attributes JSON,
...
);Instead of writing protobuf parsers from scratch, I reused the OpenTelemetry Collector’s pdata library. It handles deserialization; I just transform the result into my internal models.
Quick start
Homebrew
brew tap mesaglio/otel-front
brew install otel-front
otel-frontDocker
docker run -p 8000:8000 -p 4317:4317 -p 4318:4318 \
ghcr.io/mesaglio/otel-front:latestBinary (macOS / Linux, x86_64 & ARM64)
Download from the latest release.
Configure your app:
export OTEL_EXPORTER_OTLP_ENDPOINT="http://localhost:4318"
export OTEL_EXPORTER_OTLP_PROTOCOL="http/protobuf"
export OTEL_LOGS_EXPORTER="otlp"
export OTEL_TRACES_EXPORTER="otlp"
export OTEL_METRICS_EXPORTER="otlp"The UI includes a… (continue with the rest of your content).
# Copy‑paste helper for these env varsSource
GitHub: mesaglio/otel-front
PRs and feedback welcome. If you’re working with OpenTelemetry locally and find it useful (or broken), let me know in the comments.
