By default, OpenTelemetry writes the trace ID only to request headers. Use a Java agent extension or a Node.js responseHook to include it in response headers.
Java applications
By default, the trace ID appears only in HTTP request headers. To include it in response headers, add an OpenTelemetry Java agent extension.
Choose one of the following methods:
-
Method 1: Use the pre-built extension from Managed Service for OpenTelemetry to add trace IDs to response headers.
-
Method 2: Build a custom extension. If the pre-built extension from Managed Service for OpenTelemetry does not meet your requirements, create your own Java agent extension and package it as a JAR file.
Method 1: Use the pre-built extension
Download the extension: ot-java-agent-extension-1.28.0.jar.
Managed Service for OpenTelemetry provides this extension. To return a trace ID and span ID in response headers, add the JAR file path to your startup parameters.
Modify startup parameters
Add the otel.javaagent.extensions parameter to your startup command: -Dotel.javaagent.extensions=/path/to/opentelemetry-java-agent-extension.jar
Complete startup command example:
java -javaagent:path/to/opentelemetry-javaagent.jar \
-Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \
-Dotel.exporter.otlp.headers=Authentication=<token> \
-Dotel.exporter.otlp.endpoint=<endpoint> \
-Dotel.metrics.exporter=none \
-jar your-app.jar
Method 2: Build a custom Java agent extension
Prerequisites
-
The OpenTelemetry Java agent is configured.
-
OpenTelemetry Java agent version 1.24.0 or later.
-
Write the Java agent extension.
-
Create a new project.
-
Add the following dependencies to
pom.xml.The
opentelemetry-javaagentdependency version must match the Java agent version you use.<dependencies> <dependency> <groupId>com.google.auto.service</groupId> <artifactId>auto-service</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>io.opentelemetry.javaagent</groupId> <artifactId>opentelemetry-javaagent</artifactId> <version>1.28.0</version> <scope>compile</scope> </dependency> </dependencies> -
Create an
AgentHttpResponseCustomizerclass that implementsHttpServerResponseCustomizer.package org.example; import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.trace.Span; import io.opentelemetry.javaagent.shaded.io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.javaagent.shaded.io.opentelemetry.context.Context; import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer; import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator; @AutoService(HttpServerResponseCustomizer.class) public class AgentHttpResponseCustomizer implements HttpServerResponseCustomizer { @Override public <RESPONSE> void customize(Context context, RESPONSE response, HttpServerResponseMutator<RESPONSE> responseMutator) { SpanContext spanContext = Span.fromContext(context).getSpanContext(); String traceId = spanContext.getTraceId(); String spanId = spanContext.getSpanId(); // Add the trace ID and the span ID to the HTTP response header. You can change the field name of the header based on your requirements. responseMutator.appendHeader(response, "TraceId", traceId); responseMutator.appendHeader(response, "SpanId", spanId); } }
-
-
Build the extension.
Package the project into a JAR file. The output is stored in the
targetdirectory.mvn clean package -
Load the extension at application startup.
Add the
otel.javaagent.extensionsparameter to your startup command:-Dotel.javaagent.extensions=/path/to/opentelemetry-java-agent-extension.jarComplete startup command example:
java -javaagent:path/to/opentelemetry-javaagent.jar \ -Dotel.javaagent.extensions=path/to/opentelemetry-java-agent-extension.jar \ -Dotel.exporter.otlp.headers=Authentication=<token> \ -Dotel.exporter.otlp.endpoint=<endpoint> \ -Dotel.metrics.exporter=none \ -jar yourapp.jar
Node.js applications
-
(Optional) Run the node.js-demo project to integrate your Node.js application with OpenTelemetry.
Skip this step if your application is already integrated with OpenTelemetry.
-
Add a responseHook to the HTTP instrumentation.
Use the
responseHookparameter inHttpInstrumentationConfigto inject custom headers into responses before they are sent. The following example adds a trace ID and span ID to the response header.... // The content to be replaced. // registerInstrumentations({ // tracerProvider: provider, // instrumentations: [new HttpInstrumentation(), ExpressInstrumentation], // }); const httpInstrumentation = new HttpInstrumentation({ // Add a custom response hook. responseHook: (span, response) => { // Obtain the trace ID and the span ID from the context. const traceId = span.spanContext().traceId; const spanId = span.spanContext().spanId; // Add the trace ID and the span ID to the HTTP response header. response.setHeader('TraceId', traceId); response.setHeader('SpanId', spanId); // Return the response object. return response; }, }); registerInstrumentations({ tracerProvider: provider, instrumentations: [httpInstrumentation, ExpressInstrumentation], }); ...