Version: 0.71.0This documentation is for Spitfire 0.71.0.
Connecting services with OTel: overview
The guides in this section connect a service to Spitfire with OpenTelemetry (OTel). Each guide is applied step by step: download, place, paste, restart, verify.
What it does
- The service's traces arrive in the run's Backend tab during a run; in tests with
traceparenton, the slowest and failed requests are found in your traces. - The service's metrics are kept continuously through the Tower (Towers & metrics → Sources, kind Service).
- No code change is needed: OTel's automatic instrumentation is used for Java, .NET, Python, Node.js and PHP.
When to use it
- When you want to see where inside the service a load test slows down.
- When server and database metrics (Collector) are not enough.
Guides and versions
First find the version of the service's runtime, then open the guide on your row.
| Language | Version band | OTel package and version | Guide |
|---|---|---|---|
| Java | 8, 11, 17, 21, 25 and later | opentelemetry-javaagent.jar 2.33.1 |
Java |
| Java | 7 and earlier | not supported | – |
| .NET | .NET 8, 9, 10 | OpenTelemetry .NET Automatic Instrumentation 1.18.0 | .NET |
| .NET | .NET 6, 7 | OpenTelemetry .NET Automatic Instrumentation 1.9.0 | .NET |
| .NET | .NET Framework 4.6.2 – 4.8.1 | OpenTelemetry .NET Automatic Instrumentation 1.18.0 | .NET |
| .NET | .NET Framework 4.6.1 and earlier (4.5 included) | not supported | – |
| Python | 3.10 and later | opentelemetry-distro 0.66b2 + opentelemetry-exporter-otlp-proto-http 1.45.2 |
Python |
| Python | 3.9 | opentelemetry-distro 0.62b1 + opentelemetry-exporter-otlp-proto-http 1.41.1 |
Python |
| Python | 3.8 | opentelemetry-distro 0.54b1 + opentelemetry-exporter-otlp-proto-http 1.33.1 |
Python |
| Node.js | 22.15 and later (22, 24, 26) | @opentelemetry/auto-instrumentations-node 0.82.0 |
Node.js |
| Node.js | 18.19+, 20.6+, 22.0 – 22.14 | @opentelemetry/auto-instrumentations-node 0.81.2, @opentelemetry/api 1.9.1 |
Node.js |
| PHP | 8.1 and later | opentelemetry PECL 1.4.2 + open-telemetry/sdk 1.15.0 |
PHP |
| PHP | 8.0 and earlier | not supported | – |
On an unsupported version: upgrade the runtime to the lowest version in the table, or take server metrics only (Collector).
Verified: 2026-11-02. The sources are under each guide's version table.
What you need
Every guide asks for the same values. Towers & metrics → Connect a service (OTel) fills them in with yours.
| Value | Where from | In the guide |
|---|---|---|
| Spitfire address | the address you open Spitfire at in the browser (e.g. https://spitfire.corp or http://spitfire.corp:8470) |
https://<spitfire> |
| OTLP receiver token | Observability → Add → OTLP receiver (how) | sfotlp_… |
| Tower address and port | the Tower machine, port 4318 (https:// if TLS is on at the Tower) |
http://<tower>:4318 |
| Collector token | shown once when the Tower is created | sfcol_… |
| Protocol | fixed: http/protobuf (gRPC is not accepted) |
OTEL_EXPORTER_OTLP_PROTOCOL |
| Service name | the service's short name (e.g. checkout-api) |
<service-name> |
| Service version | the deployed version (e.g. 1.4.2) |
<service-version> |
| Environment | e.g. prod, staging |
<environment> |
| CA certificate | the CA file (PEM) if the Tower or Spitfire uses a certificate from a private CA | /etc/spitfire-otel/ca.pem |
| Proxy | with a corporate proxy, the Tower and Spitfire must stay outside it | NO_PROXY=<tower>,<spitfire> |
| Sampling | default parentbased_traceidratio, ratio 0.1 |
OTEL_TRACES_SAMPLER, OTEL_TRACES_SAMPLER_ARG |
What goes where:
- Traces and logs: straight to Spitfire,
https://<spitfire>/otlp/v1/tracesand/otlp/v1/logs, tokensfotlp_…. The service's server must be able to reach Spitfire's address. - Metrics: to the Tower,
http://<tower>:4318/v1/metrics, tokensfcol_…. Without a Tower, send metrics to Spitfire too:https://<spitfire>/otlp/v1/metricsandsfotlp_…. - The
traceparentheader in Spitfire's tests arrives sampled;parentbased_…sampling records these requests whatever the ratio is.
Tokens are written in the header value as authorization=sfotlp_…, without the word
Bearer: a space in the environment variable breaks in some SDKs. Spitfire and the Tower accept the
token with or without Bearer.
On/off: IS_OTEL_ENABLED
The first line of every environment variable block:
IS_OTEL_ENABLED=trueWith IS_OTEL_ENABLED=false, OTel data (traces, metrics, logs) is no longer collected
or sent. With true it is collected. For the change to take effect the service must be
restarted.
OTel itself does not know this variable. The start script in the guide translates it: with false,
OTEL_SDK_DISABLED=true is set and the agent is not loaded at all (no -javaagent in Java, no
profiler variables in .NET, no --require in Node.js, Python starts without opentelemetry-instrument,
OTEL_PHP_AUTOLOAD_ENABLED=false in PHP).
Common environment variables
Every guide uses this block. On Linux it goes into the file /etc/spitfire-otel/<service-name>.env;
the same file is used with --env-file in Docker and as a Secret in Kubernetes.
IS_OTEL_ENABLED=true
OTEL_SERVICE_NAME=<service-name>
OTEL_RESOURCE_ATTRIBUTES=service.version=<service-version>,deployment.environment=<environment>
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=https://<spitfire>/otlp/v1/traces
OTEL_EXPORTER_OTLP_TRACES_HEADERS=authorization=sfotlp_…
OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=https://<spitfire>/otlp/v1/logs
OTEL_EXPORTER_OTLP_LOGS_HEADERS=authorization=sfotlp_…
OTEL_EXPORTER_OTLP_METRICS_ENDPOINT=http://<tower>:4318/v1/metrics
OTEL_EXPORTER_OTLP_METRICS_HEADERS=authorization=sfcol_…
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1
NO_PROXY=<tower>,<spitfire>
#OTEL_EXPORTER_OTLP_CERTIFICATE=/etc/spitfire-otel/ca.pem- With a private CA, remove the
#at the start of the last line and put the CA file at that path. - Do not use quotes or end-of-line comments in the file (systemd and Docker both add them to the value).
- The file's permission:
sudo chmod 600 /etc/spitfire-otel/<service-name>.env(it holds tokens).
Verifying
- From the service machine, try the Spitfire token;
200means the address and token are right,401means the token is wrong:
curl -s -o /dev/null -w '%{http_code}\n' -X POST https://<spitfire>/otlp/v1/traces \
-H 'Authorization: Bearer sfotlp_…' -H 'Content-Type: application/json' --data '{}'- From the service machine, try the Tower; the answer must show
"connected":true:
curl -s http://<tower>:4318/health- Restart the service and wait a minute: the service name shows in the Towers & metrics → Sources list with kind Service.
- Start a test run: the service's traces show in the run's Backend tab. On the Observability page, "last data" next to the OTLP receiver is updated.
Common problems
| Symptom | Cause | Fix |
|---|---|---|
curl returned 401 |
The token is wrong, revoked or another Tower's | Renew the token with New token on Observability; compare the Tower token with the sfcol_… given when the Tower was created |
| The service is not in the list | Keeping metrics is off, or metrics do not reach the Tower | Is Collect and keep metrics on; does OTEL_EXPORTER_OTLP_METRICS_ENDPOINT end in /v1/metrics |
| A PHP service is not in the list | PHP records no metrics by itself | Expected; see the PHP guide |
| No traces in the run | Traces are only kept in a run's window; or sampling is low | Produce the traces during the run; turn on traceparent in the test |
404 from the Tower |
Traces or logs were sent to the Tower | Traces and logs go to Spitfire's /otlp/v1/... address |
| TLS error | The private CA is not trusted | Uncomment the OTEL_EXPORTER_OTLP_CERTIFICATE line and put the CA file in place |
| Connection timeout | A corporate proxy gets in the way or the firewall is closed | Check the NO_PROXY line; have the service → Tower 4318/TCP and service → Spitfire rules opened |