A library to help me set up OTEL trace exports with environment variables. Similar to autoexport, but tailored to what I care about.
motel is brand new and super unstable. I'll probably change a lot of things.
Initialize in code:
tracerProvider, err := motel.NewTracerProviderFromEnv(ctx, motel.NewTracerProviderFromEnvArgs{
AppName: "myapp",
Version: "v0.0.1"
})Set environment variables:
MOTEL_SPAN_PROCESSOR=batch|sync
MOTEL_TRACES_EXPORTER=file|none|otlpgrpc|otlphttp|stderr|stdout
MOTEL_TRACES_FILE_EXPORTER_FILE_PATH=tmp.jsonl # required if MOTEL_TRACES_EXPORTER=fileSee https://opentelemetry.io/docs/specs/otel/configuration/sdk-environment-variables/ for other environment variables.
NOTE: all examples below use this internal CLI. Get it by cloning the repo.
file + local logdy
Create a file and start following it with logy using this config:
$ touch tmp.jsonl && logdy follow ./tmp.jsonl --config ~/Git-GH/dotfiles/logdy/dot-config/logdy.jsonOpen the local logs page and wait for logs.
In a new terminal, run the motel example:
$ MOTEL_TRACES_EXPORTER=file MOTEL_TRACES_FILE_EXPORTER_FILE_PATH=tmp.jsonl go run ./internal/cmd/motel run
rolling dice
rolling dice
^Ccontext done
calling ticker stop
calling cancelHead back to the browser to view traces coming in (might take a minute if using MOTEL_SPAN_PROCESSOR=batch)
Not very readable, but useful to verify everything works.
$ MOTEL_TRACES_EXPORTER=stdout go run ./internal/cmd/motel run
rolling dice
^Ccontext done
calling ticker stop
{"Name":"rolldice","SpanContext":{"TraceID":"990f2f9167e20ecc96d1e777061520fa","SpanID":"6be766f137dba10e","TraceFlags":"01","TraceState":"","Remote":false},"Parent":{"TraceID":"00000000000000000000000000000000","SpanID":"0000000000000000","TraceFlags":"00","TraceState":"","Remote":false},"SpanKind":1,"StartTime":"2025-08-03T16:23:12.24662-07:00","EndTime":"2025-08-03T16:23:12.246738958-07:00","Attributes":[{"Key":"hello","Value":{"Type":"STRING","Value":"world"}},{"Key":"key","Value":{"Type":"STRING","Value":"value"}},{"Key":"intkey","Value":{"Type":"INT64","Value":32}}],"Events":[{"Name":"exception","Attributes":[{"Key":"exception.type","Value":{"Type":"STRING","Value":"*errors.errorString"}},{"Key":"exception.message","Value":{"Type":"STRING","Value":"the oopsie error"}}],"DroppedAttributeCount":0,"Time":"2025-08-03T16:23:12.246735-07:00"}],"Links":null,"Status":{"Code":"Error","Description":"oopsie"},"DroppedAttributes":0,"DroppedEvents":0,"DroppedLinks":0,"ChildSpanCount":0,"Resource":[{"Key":"service.name","Value":{"Type":"STRING","Value":"motel"}},{"Key":"service.version","Value":{"Type":"STRING","Value":"(devel)"}}],"InstrumentationScope":{"Name":"go.bbkane.com/motel/internal/cmd/motel","Version":"","SchemaURL":"","Attributes":null},"InstrumentationLibrary":{"Name":"go.bbkane.com/motel/internal/cmd/motel","Version":"","SchemaURL":"","Attributes":null}}
calling cancelotlphttp + locally hosted OpenObserve
While I'm using locally hosted OpenObserve since it's easy to run locally, this should also work with OTEL vendors in the cloud: Grafana, Honeycomb, SigNoz and others I'm sure I'm forgetting right now
Download OpenObserve (I use the OSS version) from the downloads page.
Run it with some environment variables:
ZO_ROOT_USER_EMAIL=root@example.com \
ZO_ROOT_USER_PASSWORD=pass \
./openobserveOpen the Data sources > Traces page and turn the OTLP HTTP sources into environment variables (note: the headers seems to change each time), then run the example in a new terminal window:
$ MOTEL_TRACES_EXPORTER=otlphttp \
OTEL_EXPORTER_OTLP_ENDPOINT='http://127.0.0.1:5080/api/default' \
OTEL_EXPORTER_OTLP_HEADERS='Authorization=Basic cm9vdEBleGFtcGxlLmNvbTptODM4MDVDc2NZU1BZbTJP' \
go run ./internal/cmd/motel run
rolling dice
rolling dice
rolling dice
^Ccontext done
calling ticker stop
calling cancelView traces from the Traces page:
See Go Project Notes for notes on development tooling.
Configure OpenObserve](https://openobserve.ai/) with enventory
Last updated: 2025-08-21
I'm using enventory to configure OpenObserve. Unlike the quick instructions above (optimized for trying OpenObserve out), these instructions are optimized for quickly running OpenObserve locally once it's installed, as well as updating OpenObserve and adding it to new projects.
First, download OpenObserve from the downloads page - make sure to switch the edition to "Open Source" and the platform to your platform. I like to run commands manually, so I follow the manual instructions. I install to ~/Apps/<name>. So, for example: ~/Apps/openobserve-v0.15.0-rc3-linux-amd64-musl. That way if I install a newer version, it can go in its own folder.
On macOS, I had to unquarantine the CLI:
xattr -d com.apple.quarantine openobserveSecond, make an OpenObserve environment. We'll be re-using these variables every time we update OpenObserve
enventory env create --name openobserve
enventory var create --name ZO_ROOT_USER_EMAIL --value root@example.com --env openobserve
enventory var create --name ZO_ROOT_USER_PASSWORD --value pass --env openobserveThird, set up the environment for the OpenObserve install folder and reference the variables in the openobserve environment we just made.
cd ~/Apps/openobserve-v0.15.0-rc3-linux-amd64-musl
enventory env create
enventory var ref create --name ZO_ROOT_USER_EMAIL --ref-env openobserve --ref-var ZO_ROOT_USER_EMAIL
enventory var ref create --name ZO_ROOT_USER_PASSWORD --ref-env openobserve --ref-var ZO_ROOT_USER_PASSWORDStart OpenObserve
export-env "$PWD"
./openobserveFourth, open the Data sources > Traces page and turn the OTLP HTTP headers into environment variables, and create an environment to hold them. Example below, but the header seems to change with each install, so unfortunately you can't just copy the commands below.
enventory env create --name motel_otlphttp_openobserve
enventory var create --name OTEL_EXPORTER_OTLP_ENDPOINT --value 'http://127.0.0.1:5080/api/default' --env motel_otlphttp_openobserve
enventory var create --name OTEL_EXPORTER_OTLP_HEADERS --value 'Authorization=Basic cm9vdEBleGFtcGxlLmNvbToxZ0Yya1dwSGQ1cW1ObGRs' --env motel_otlphttp_openobserveFinally, any time you want to run the CLI, start OpenObserve in one terminal window:
cd ~/Apps/openobserve-v0.15.0-rc3-linux-amd64-musl
./openobserveThen open a new terminal window, source the env and run the command.
source-env motel_otlphttp_openobserve
go run ./internal/cmd/motel runSee traces at the tracing page.
Any time you want to update OpenObserve, download it to a new folder, reference the openobserve vars, again, and update the headers in motel_otlphttp_openobserve.

