This guide walks you through instrumenting your Quarkus application with OpenTelemetry and sending traces to SigNoz. Quarkus uses built-in OpenTelemetry extensions rather than the Java agent, making it well-suited for both JVM and native builds.
Prerequisites
- Java 17 or higher
- A Quarkus REST application
- A SigNoz Cloud account or self-hosted SigNoz instance
Send traces to SigNoz
Step 1. Set environment variables
export OTEL_RESOURCE_ATTRIBUTES="service.name=my-quarkus-app"
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
Add these environment variables to your deployment manifest:
env:
- name: OTEL_RESOURCE_ATTRIBUTES
value: 'service.name=my-quarkus-app'
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: 'https://ingest.<region>.signoz.cloud:443'
- name: OTEL_EXPORTER_OTLP_HEADERS
value: 'signoz-ingestion-key=<your-ingestion-key>'
$env:OTEL_RESOURCE_ATTRIBUTES = "service.name=my-quarkus-app"
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "https://ingest.<region>.signoz.cloud:443"
$env:OTEL_EXPORTER_OTLP_HEADERS = "signoz-ingestion-key=<your-ingestion-key>"
Add to your Dockerfile:
ENV OTEL_RESOURCE_ATTRIBUTES="service.name=my-quarkus-app"
ENV OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
ENV OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
Or pass at runtime:
docker run -p 8080:8080 \
-e OTEL_RESOURCE_ATTRIBUTES="service.name=my-quarkus-app" \
-e OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443" \
-e OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>" \
my-quarkus-app
Replace the following:
<region>: Your SigNoz Cloud region (us,eu, orin). See endpoints.<your-ingestion-key>: Your SigNoz ingestion key.
Step 2. Add the OpenTelemetry extension
quarkus extension add opentelemetry
./mvnw quarkus:add-extension -Dextensions="opentelemetry"
Or add directly to your pom.xml:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-opentelemetry</artifactId>
</dependency>
Add to your build.gradle:
implementation 'io.quarkus:quarkus-opentelemetry'
Step 3. Configure application.properties
Add the following configuration to src/main/resources/application.properties:
quarkus.application.name=my-quarkus-app
quarkus.otel.exporter.otlp.endpoint=${OTEL_EXPORTER_OTLP_ENDPOINT}
quarkus.otel.exporter.otlp.headers=${OTEL_EXPORTER_OTLP_HEADERS:}
quarkus.otel.resource.attributes=${OTEL_RESOURCE_ATTRIBUTES:}
This configuration reads values from environment variables, making it easy to configure different environments without code changes.
Step 4. Build and run your application
./mvnw package
java -jar target/quarkus-app/quarkus-run.jar
Validate
With your application running, verify traces are being sent to SigNoz:
- Make a few requests to your application endpoints.
- In SigNoz, open the Services tab and click Refresh. Your application should appear.
- Go to the Traces tab to see your application's traces.
Troubleshooting
Traces not showing up in SigNoz?
Check environment variables:
echo $OTEL_EXPORTER_OTLP_ENDPOINT
echo $OTEL_RESOURCE_ATTRIBUTES
Enable debug logging in application.properties:
quarkus.log.category."io.opentelemetry".level=DEBUG
Test connectivity:
curl -v https://ingest.<region>.signoz.cloud:443/v1/traces
Extension not found?
Make sure the quarkus-opentelemetry extension is in your dependencies:
# Check installed extensions
./mvnw quarkus:list-extensions -Dinstalled
If missing, add it:
./mvnw quarkus:add-extension -Dextensions="opentelemetry"
Quarkus dev mode not sending traces?
In dev mode, make sure environment variables are set in your terminal before running:
export OTEL_EXPORTER_OTLP_ENDPOINT="https://ingest.<region>.signoz.cloud:443"
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=<your-ingestion-key>"
./mvnw quarkus:dev
Native build failing with OpenTelemetry?
Ensure you're using a GraalVM-compatible version of the OpenTelemetry extension. Check the Quarkus platform BOM version in your pom.xml and update if needed:
<quarkus.platform.version>3.8.0</quarkus.platform.version>
Why not use the Java agent with Quarkus?
The Java agent relies on bytecode manipulation at runtime, which conflicts with:
- Native builds: GraalVM native-image compiles bytecode ahead of time, so runtime agents cannot work
- Quarkus build-time optimization: Quarkus performs dependency injection and configuration at build time
The quarkus-opentelemetry extension is designed to work with Quarkus's build-time approach and supports both JVM and native modes.
Next steps
- Add manual instrumentation for custom spans and business context
- Collect Java application logs with OpenTelemetry
- Set up alerts for your Quarkus application
Sample application: