Send data with OpenTelemetry
Fixter ingests telemetry over standard OpenTelemetry (OTLP/HTTP). If your services already emit OpenTelemetry, through the Collector, an SDK, or an auto-instrumentation agent, connecting them to Fixter is three steps and no code changes. (Just getting started? Onboarding is the guided path; this page is the depth behind its manual tier.) On Claude Code you do not wire any of this by hand: the plugin provisions the key and configures export for you.
Step 1: Create an API key
Section titled “Step 1: Create an API key”- Open Settings > API keys in the Fixter app.
- Click Create key and give it a label you’ll recognize later, like
production-collector. - Copy the key immediately. For security it is shown only this once; if you lose it, revoke it and create a new one.
Keys look like fixter_sk_.... Store it wherever your infrastructure keeps secrets,
and export it in the shell you’ll use below:
export FIXTER_API_KEY="fixter_sk_..."No workspace yet? Email info@fixter.dev and one of our founders will set you up.
Step 2: Point your OpenTelemetry setup at Fixter
Section titled “Step 2: Point your OpenTelemetry setup at Fixter”Pick the path that matches your setup:
- On Kubernetes: run the Fixter collector (Path A).
- You already run an OpenTelemetry Collector: add a Fixter exporter to it (Path B).
- Anything else (a plain process, a VM, Docker): export straight from your application (Path C).
Path A: run the Fixter collector (Kubernetes)
Section titled “Path A: run the Fixter collector (Kubernetes)”The Fixter collector is a standard OpenTelemetry Collector that Fixter pre-configures and publishes, so there is no proprietary agent involved. On Kubernetes it is the recommended path, installed as a Helm chart.
Create the fixter namespace and, inside it, a Secret named fixter-credentials
holding the key from Step 1. Then install the chart pointing at that Secret:
helm install fixter-collector \ oci://ghcr.io/fixter-dev/charts/fixter-collector \ --namespace fixter \ --set fixter.existingSecret=fixter-credentials \ --set fixter.clusterName=<your-cluster>Pass the key by Secret reference, never --set fixter.apiKey=..., which would leave it
in your shell history and the pod’s process list.
Installed on its own, the chart brings pod logs and host and cluster metrics into
Fixter with no application changes at all. It parses JSON pod logs for severity and
trace correlation, and auto-routes common database logs (Postgres, MySQL, Kafka and
others). To add each app’s own traces and logs on top, point its workload at the
collector’s in-cluster Service instead of at ingest.fixter.dev:
OTEL_EXPORTER_OTLP_ENDPOINT=http://fixter-collector-agent.fixter.svc.cluster.local:4318OTEL_EXPORTER_OTLP_PROTOCOL=http/protobufOTEL_SERVICE_NAME=checkout-serviceThe Claude Code plugin installs and configures this chart for you, including the Secret and the case where a GitOps or Terraform system already manages your Helm releases.
Path B: add Fixter to a Collector you already run
Section titled “Path B: add Fixter to a Collector you already run”If you already run an OpenTelemetry Collector,
one exporter block sends its telemetry to Fixter as well, covering every service that
exports to it whatever the language. Add the exporter to your Collector’s configuration
file (the YAML you start it with via --config; on package installs typically
/etc/otelcol/config.yaml) and reference it from each pipeline:
# otel-collector-config.yamlexporters: otlphttp/fixter: endpoint: https://ingest.fixter.dev headers: Authorization: "Bearer ${env:FIXTER_API_KEY}" compression: gzip
service: pipelines: logs: exporters: [otlphttp/fixter] # append to your existing exporters list traces: exporters: [otlphttp/fixter] metrics: exporters: [otlphttp/fixter]Then restart the Collector (for example systemctl restart otelcol, or redeploy the
container) with FIXTER_API_KEY present in its environment.
Path C: export straight from your application
Section titled “Path C: export straight from your application”No Collector needed: every OpenTelemetry SDK and auto-instrumentation agent can send directly to Fixter. The universal contract is four environment variables, the same in every language:
OTEL_SERVICE_NAME=checkout-service # how Fixter names your serviceOTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.fixter.devOTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf # Fixter speaks OTLP over HTTP, not gRPCOTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer $FIXTER_API_KEY"Set those wherever your process gets its environment, add your language’s OpenTelemetry instrumentation, and you’re exporting. Concrete recipes:
Logs are configured separately from traces, and how much is automatic depends on your
stack. Instrumentation gives you traces and metrics; logs need a bridge from your logging
library, and it is not free everywhere. The Java agent auto-bridges logback and log4j2, so
logs come with no extra work. Node exports logs only for Winston, Pino, or Bunyan (plain
console sends none). Python needs opentelemetry-instrumentation-logging to bridge stdlib
logging. Go, PHP, and Ruby have no stable log bridge yet and ship logs as JSON through a
collector instead. Each tab below notes what its stack needs; do not assume logs arrive just
because traces do.
# install the auto-instrumentation bundlenpm install @opentelemetry/auto-instrumentations-nodeHow you load it depends on whether your app is CommonJS or ES modules, and getting it wrong
fails silently. With the CommonJS loader on an ESM app, traces still appear (CommonJS deps
pulled in through interop are patched) while ESM-loaded libraries like pino are not, so no
logs and no trace_id reach Fixter and nothing errors or warns.
CommonJS (a require-based app, no "type": "module" in package.json):
# the four OTEL_* vars set as abovenode --require @opentelemetry/auto-instrumentations-node/register app.jsES modules ("type": "module", or .mjs files): --require does not hook ESM imports.
Register the ESM loader hook from a small file and start the app with --import (Node also
deprecates --require in favour of --import):
// instrumentation.mjsimport { register } from 'node:module';register('import-in-the-middle/hook.mjs', import.meta.url);await import('@opentelemetry/auto-instrumentations-node/register');# the four OTEL_* vars set as abovenode --import ./instrumentation.mjs app.jsLogs need an instrumented log library. Auto-instrumentation exports logs only for
Winston, Pino, or Bunyan; a service that logs through plain console.log sends traces and
metrics but no logs at all. If you use console, move to one of those to get queryable logs
and the trace_id on each line that ties a log to its trace.
# install and let it detect your frameworkspip install opentelemetry-distro opentelemetry-exporter-otlpopentelemetry-bootstrap -a install
# run your app wrapped (the four OTEL_* vars set as above)opentelemetry-instrument python app.pyLogs: opentelemetry-bootstrap adds the logging instrumentation that bridges Python’s
stdlib logging; with OTEL_LOGS_EXPORTER=otlp set, log records export alongside traces.
# download the agent once, next to your service's jarcurl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
# attach it at startup (the four OTEL_* vars set as above)java -javaagent:./opentelemetry-javaagent.jar -jar your-service.jarLogs: the agent auto-bridges logback and log4j2, so your existing logs export with no extra work.
Go, Ruby, .NET, Rust, PHP, Erlang: every official OpenTelemetry SDK honors the four
environment variables above. Follow your language’s instrumentation guide at
opentelemetry.io/docs/languages, and
where it asks for an OTLP endpoint or headers, the values are already in your
environment. (Some SDKs without auto-instrumentation need the OTLP http exporter
package chosen explicitly; the http/protobuf protocol line is the setting that
matters.)
Logs: log-bridge maturity varies by language. Go, PHP, and Ruby have no stable OTLP log bridge yet, so emit JSON logs to stdout and let the Fixter collector pick them up rather than exporting logs from the SDK.
Where do the env vars go? Wherever your deploy defines its environment:
| You run on | Set them in |
|---|---|
| A plain process / VM | the shell, a .env loader, or the systemd unit (Environment=) |
| Docker | ENV/-e, or environment: in compose |
| Kubernetes (any flavor: EKS, GKE, self-managed) | the Deployment’s env: block, with the key from a Secret |
| AWS ECS | the task definition’s environment/secrets |
Store the API key as a secret in all of these; it’s a credential, not config.
Step 3: See your data
Section titled “Step 3: See your data”- Open the Logs page in the Fixter app (it’s also where you land after login).
- The default view shows the last hour. If your service logged anything since Step 2, it’s here; use the filter bar to narrow to your service name.
- Click the tail button next to the query bar to stream new logs live while you exercise your service.
Sent metrics or traces instead? Metrics appear on the Metrics page; traces attach to your logs (any log with a trace opens its full trace view). From here, connect your agent over MCP and ask it about your data instead.
What each signal is for, what you get without writing instrumentation yourself, and what happens to it all once it lands: Telemetry.
If nothing shows up
Section titled “If nothing shows up”401in your exporter or Collector logs: theAuthorizationheader isn’t reaching Fixter or the key was revoked. Re-check Step 1 and that the env var is actually set in the process’s environment.- Exporter errors mentioning gRPC: set
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf(see Step 2). - Traces arrive but no logs (Node): the app is ESM and was started with
--require, which does not instrument ESM imports, or it logs through plainconsole.log. Use the--importloader and a Winston/Pino/Bunyan logger (see the Node.js recipe in Step 2). - Data arrives but under the wrong name: set
OTEL_SERVICE_NAME. - Batches partially rejected: the exporter logs show Fixter’s
partialSuccessmessage naming the first rejected record and why.
Still stuck? Email info@fixter.dev and one of our founders will help you fix your problem asap.