This document contains instructions on how to set up OpenTelemetry instrumentation in your Quarkus applications and view your application traces in SigNoz.
Prerequisite
- A Quarkus REST application with basic endpoints
- Java 17 or higher environment
- Docker (if using Docker and Kubernetes)
Configuration Steps
- Add OpenTelemetry extension to your project:
# Using Quarkus CLI
quarkus extension add opentelemetry
# Using Maven command
./mvnw quarkus:add-extension -Dextensions="opentelemetry"
# Using gradle, add the following to your build.gradle file
implementation 'io.quarkus:quarkus-opentelemetry'
- Update the
application.propertiesfile to enable and configure OpenTelemetry
# Application name and version
quarkus.application.name=quarkus-app
quarkus.application.version=1.0.0
# Ingestion key for authentication (only if using SigNoz Cloud)
quarkus.otel.exporter.otlp.headers=${OTEL_EXPORTER_OTLP_HEADERS:}
# OTLP exporter endpoint (base URL for telemetry data)
quarkus.otel.exporter.otlp.endpoint=${OTEL_EXPORTER_OTLP_ENDPOINT}
# Specific endpoint for exporting trace data
quarkus.otel.exporter.otlp.traces.endpoint=${OTEL_EXPORTER_OTLP_ENDPOINT}/v1/traces
# Additional resource attributes for telemetry data
quarkus.otel.resource.attributes=${OTEL_RESOURCE_ATTRIBUTES}
Quarkus Extensions and the libraries they provide, are directly instrumented, use of OpenTelemetry Agent is not required nor recommended.
Based on your application environment, you can choose the setup below to instrument your application via SigNoz Cloud.
- Export the OTEL Environment variables:
export OTEL_RESOURCE_ATTRIBUTES=service.name=<app-name>
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=SIGNOZ_INGESTION_KEY"
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443
<app_name>is the name for your applicationSIGNOZ_INGESTION_KEYis the Ingestion Key provided by SigNoz.
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
| Region | Endpoint |
|---|---|
| US | ingest.us.signoz.cloud:443 |
| IN | ingest.in.signoz.cloud:443 |
| EU | ingest.eu.signoz.cloud:443 |
- Build and run your application:
# Using Quarkus CLI
quarkus build
java -jar target/quarkus-app/quarkus-run.jar
# Using maven
./mvnw package
java -jar target/quarkus-app/quarkus-run.jar
# Using gradle
./gradlew build
java -jar build/libs/quarkus-app.jar
You can auto-instrument sending traces from Java Quarkus application using one of the following methods:
- Using Kubernetes OTel Operator
- Using OTel Collector Agent
For Java Quarkus application deployed on Kubernetes, you can auto-instrument the traces using Kubernetes OpenTelemetry Operator.
An OpenTelemetry Operator is a Kubernetes Operator that manages OpenTelemetry Collectors and auto-instrumentation of workloads. It basically simplifies the deployment and management of OpenTelemetry in a Kubernetes environment.
The OpenTelemetry Operator provides two Custom Resource Definitions (CRDs):
OpenTelemetryCollectorInstrumentation
The OpenTelemetryCollector CRD allows you to deploy and manage OpenTelemetry Collectors in your Kubernetes cluster.
The Instrumentation CRD allows you to configure and inject OpenTelemetry auto-instrumentation libraries into your workloads.
Here are the steps you need to follow to auto-instrument Quarkus application using OTel Operator:
Step 1: Install cert-manager
Run the following commands to apply cert manager.
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.16.1/cert-manager.yaml
kubectl wait --for=condition=Available deployments/cert-manager -n cert-manager
Step 2: Install OpenTelemetry Operator
To install the operator in the existing K8s cluster, run the following command:
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/download/v0.116.0/opentelemetry-operator.yaml
Installing the OpenTelemetry Operator sets up the necessary components and configurations to enable the observability and monitoring of applications running in the cluster.
Step 3: Setup the OpenTelemetry Collector instance
Once the opentelemetry-operator has been deployed, you can proceed with the creation of the OpenTelemetry Collector (otelcol) instance. The OpenTelemetry Collector collects, processes, and exports telemetry data.
There are different deployment modes for the OpenTelemetryCollector, and you can specify them in the spec.mode section of the custom resource. The available deployment modes are:
- Daemonset
- Sidecar
- StatefulSet
- Deployment (default mode)
The default method - the Deployment mode, will be used here.
To create a simple instance of the OpenTelemetry Collector, create a file otel-collector.yaml with the following contents:
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel-collector
spec:
mode: deployment
config: |
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
processors:
batch: {}
resource/env:
attributes:
- key: deployment.environment
value: prod # can be dev, prod, staging etc. based on your environment
action: upsert
exporters:
debug: {}
otlp:
endpoint: "ingest.<region>.signoz.cloud:443" # replace <region> with your region of SigNoz Cloud
tls:
insecure: false
headers:
"signoz-ingestion-key": "<your-ingestion-key>" # Obtain from https://{your-signoz-tenant-url}/settings/ingestion-settings
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, resource/env]
exporters: [otlp]
- Set the
<region>to match your SigNoz Cloud region - Replace
<your-ingestion-key>with your SigNoz ingestion key
Apply the above yaml file using the following command:
kubectl apply -f otel-collector.yaml
Step 4: Setup the Instrumentation instance
Once the OpenTelemetry Collector instance has been deployed, the next step will be to create an instrumentation instance, which will be responsible for sending OTLP data to the OTel Collector.
Create a file instrumentation.yaml with the following contents:
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: traces-instrumentation
spec:
exporter:
endpoint: https://ingest.<region>.signoz.cloud:443 # replace <region> with your region of SigNoz Cloud
env:
- name: OTEL_EXPORTER_OTLP_HEADERS
value: signoz-ingestion-key="<signoz-token>" # Obtain from https://{your-signoz-url}/settings/ingestion-settings
- name: OTEL_EXPORTER_OTLP_INSECURE
value: "false"
propagators:
- tracecontext
- baggage
- b3
sampler:
type: parentbased_traceidratio
argument: "1"
java:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
Apply the above instrumentation using the following command:
kubectl apply -f instrumentation.yaml
Step 5: Auto-instrument your Quarkus app with OpenTelemetry
Create deployment.yaml file for your Quarkus application as follows:
apiVersion: apps/v1
kind: Deployment
metadata:
name: quarkus-app
spec:
selector:
matchLabels:
app: quarkus-app
replicas: 1
template:
metadata:
labels:
app: quarkus-app
annotations:
instrumentation.opentelemetry.io/inject-java: "true"
resource.opentelemetry.io/service.name: "quarkus-app"
spec:
containers:
- name: app
image: quarkus-app:latest
ports:
- containerPort: 8080
It is important to add the following annotation under spec > template > metadata > annotations:
instrumentation.opentelemetry.io/inject-java: "true"`
This helps in auto-instrumenting the traces from the Java application.
Apply the deployment using the following command:
kubectl apply -f deployment.yaml
With this, the auto-instrumentation of traces for Java Quarkus application is ready.
Step 6: Running the Quarkus application
In order to run the application on port 8080, run the following commands:
export POD_NAME=$(kubectl get pod -l app=<service-name> -o jsonpath="{.items[0].metadata.name}") # service name is `quarkus-app` in this case.
kubectl port-forward ${POD_NAME} 8080:8080
You can now access the application on port 8080.
You can validate if your application is sending traces to SigNoz cloud by following the instructions here.
- Export the OTEL Environment variables:
export OTEL_RESOURCE_ATTRIBUTES=service.name=<app-name>
export OTEL_EXPORTER_OTLP_HEADERS="signoz-ingestion-key=SIGNOZ_INGESTION_KEY"
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.{region}.signoz.cloud:443
<app_name>is the name for your applicationSIGNOZ_INGESTION_KEYis the Ingestion Key provided by SigNoz.
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
| Region | Endpoint |
|---|---|
| US | ingest.us.signoz.cloud:443 |
| IN | ingest.in.signoz.cloud:443 |
| EU | ingest.eu.signoz.cloud:443 |
- Build your application:
quarkus build
./mvnw package
./gradlew build
- Create a docker image for your application or publish your application to a container registry:
docker build -f src/main/docker/Dockerfile.jvm -t quarkus-app-jvm .
docker build -f src/main/docker/Dockerfile.native -t quarkus-app-native .
- Create a
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: quarkus-app
spec:
replicas: 1
selector:
matchLabels:
app: quarkus-app
template:
metadata:
labels:
app: quarkus-app
spec:
containers:
- name: quarkus-app
image: <my-app>:latest
imagePullPolicy: Never # If you have built the image locally
ports:
- containerPort: 8080
env:
- name: OTEL_RESOURCE_ATTRIBUTES
value: "service.name=<app_name>"
- name: OTEL_EXPORTER_OTLP_HEADERS
value: "signoz-ingestion-key=SIGNOZ_INGESTION_KEY"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://ingest.{region}.signoz.cloud:443"
---
apiVersion: v1
kind: Service
metadata:
name: quarkus-app
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: quarkus-app
<my-app>is the name of the docker image you built
- Deploy to Kubernetes:
kubectl apply -f deployment.yaml
You can verify the deployment by running kubectl get pods and checking the status of the pod.

- Set environment variables:
setx OTEL_RESOURCE_ATTRIBUTES "service.name=<app_name>"
setx OTEL_EXPORTER_OTLP_HEADERS "signoz-ingestion-key=SIGNOZ_INGESTION_KEY"
setx OTEL_EXPORTER_OTLP_ENDPOINT "https://ingest.{region}.signoz.cloud:443"
<app_name>is the name for your applicationSIGNOZ_INGESTION_KEYis the Ingestion Key provided by SigNoz.
Depending on the choice of your region for SigNoz cloud, the ingest endpoint will vary according to this table.
| Region | Endpoint |
|---|---|
| US | ingest.us.signoz.cloud:443 |
| IN | ingest.in.signoz.cloud:443 |
| EU | ingest.eu.signoz.cloud:443 |
- Build and run your application:
quarkus build
java -jar target/quarkus-app/quarkus-run.jar
mvnw.cmd package
java -jar target/quarkus-app/quarkus-run.jar
gradlew.bat build
java -jar build/libs/quarkus-app.jar
If you haven't already, signup for SigNoz Cloud.
Based on your application environment, you can choose the setup below to instrument your application via SigNoz Cloud.
- Set the
OTEL_RESOURCE_ATTRIBUTESenvironment variable to the name of your application - Update the
OTEL_EXPORTER_OTLP_ENDPOINTenvironment variable withhttps://<URL of SigNoz Backend>:4317
export OTEL_RESOURCE_ATTRIBUTES=service.name=<app-name>
export OTEL_EXPORTER_OTLP_ENDPOINT=https://<URL of SigNoz Backend>:4317
- Build and run your application:
quarkus build
java -jar target/quarkus-app/quarkus-run.jar
./mvnw package
java -jar target/quarkus-app/quarkus-run.jar
./gradlew build
java -jar build/libs/quarkus-app.jar
Things to note about the command:
OTEL_EXPORTER_OTLP_ENDPOINT - This is the endpoint of the machine where SigNoz is installed.
If you have installed SigNoz on your localhost and your Java JAR is saved at /Users/john/Downloads/, then the final command looks like:
export OTEL_RESOURCE_ATTRIBUTES=service.name=quarkus-app
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
java -jar /Users/john/Downloads/quarkus-app.jar
- Set the
OTEL_RESOURCE_ATTRIBUTESenvironment variable to the name of your application - Update the
OTEL_EXPORTER_OTLP_ENDPOINTenvironment variable withhttps://<URL of SigNoz Backend>:4317
export OTEL_RESOURCE_ATTRIBUTES=service.name=<app-name>
export OTEL_EXPORTER_OTLP_ENDPOINT=https://<URL of SigNoz Backend>:4317
- Build your application:
quarkus build
./mvnw package
./gradlew build
- Create a docker image for your application or publish your application to a container registry:
docker build -f src/main/docker/Dockerfile.jvm -t quarkus-app-jvm .
docker build -f src/main/docker/Dockerfile.native -t quarkus-app-native .
- Create a
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: quarkus-app
spec:
replicas: 1
selector:
matchLabels:
app: quarkus-app
template:
metadata:
labels:
app: quarkus-app
spec:
containers:
- name: quarkus-app
image: <my-app>:latest
imagePullPolicy: Never # If you have built the image locally
ports:
- containerPort: 8080
env:
- name: OTEL_RESOURCE_ATTRIBUTES
value: "service.name=<app_name>"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "https://<URL of SigNoz Backend>:4317" # This is the endpoint of the machine where SigNoz is installed.
---
apiVersion: v1
kind: Service
metadata:
name: quarkus-app
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: quarkus-app
<my-app>is the name of the docker image you built
- Deploy to Kubernetes:
kubectl apply -f deployment.yaml
You can verify the deployment by running kubectl get pods and checking the status of the pod.

- Set environment variables:
setx OTEL_RESOURCE_ATTRIBUTES "service.name=<app_name>"
setx OTEL_EXPORTER_OTLP_ENDPOINT "https://<URL of SigNoz Backend>:4317"
<app_name>is the name for your applicationOTEL_EXPORTER_OTLP_ENDPOINTis the endpoint of the machine where SigNoz is installed.
- Build and run your application:
quarkus build
java -jar target/quarkus-app/quarkus-run.jar
mvnw.cmd package
java -jar target/quarkus-app/quarkus-run.jar
gradlew.bat build
java -jar build/libs/quarkus-app.jar
💡 Remember to allow incoming requests to port 4317 of the machine where SigNoz backend is hosted.
In case you encounter an issue where all applications do not get listed in the services section then please refer to the troubleshooting section.
Note: By default, Java auto-instrumentation does not create spans for user-defined functions. In such scenarios, we can use annotations to quickly create spans for user-defined functions with minimal code change. You can instrument your Quarkus application following this guide on annotations.
Validating Instrumentation
To verify your instrumentation is working:
- Trigger an action in your app that generates a web request. Hit the endpoint a number of times to generate some data. Then, wait for some time. Ex:
curl http://localhost:8080/hello

- Check the Services tab in SigNoz UI for your application

- Navigate to the Traces tab to see detailed traces

Sample Application
- We have included a sample application at:
Troubleshooting
If traces are not appearing:
- Verify your configuration in
application.properties - Check application logs for OpenTelemetry-related errors
- Try enabling debug logging by setting
quarkus.log.category."io.opentelemetry".level=DEBUG - Check logs if your application is able to reach the SigNoz endpoint, If not you will see errors in the logs similar to:or
2024-12-15 12:06:43,469 WARNING [io.ope.exp.int.htt.HttpExporter] (OkHttp https://ingest.in.signoz.cloud/...) Failed to export spans. Server responded with HTTP status code 401. Error message: Unable to parse response body, HTTP status message: Unauthorized2024-12-15 12:17:50,343 SEVERE [io.ope.exp.int.htt.HttpExporter] (OkHttp http://localhost:4318/...) Failed to export spans. The request could not be executed. Full error message: Failed to connect to localhost/[0:0:0:0:0:0:0:1]:4318: java.net.ConnectException: Failed to connect to localhost/[0:0:0:0:0:0:0:1]:4318- If using SigNoz Cloud, check if the ingestion key and endpoint are correct.
- If using self-hosted SigNoz, check if the endpoint is correct and if you have allowed incoming requests to the port 4317 of the machine where SigNoz backend is hosted.
Frequently Asked Questions
How to find what to use in
IP of SigNozif I have installed SigNoz in Kubernetes cluster?Based on where you have installed your application and where you have installed SigNoz, you need to find the right value for this. Please use this grid to find the value you should use for
IP of SigNozI am sending data from my application to SigNoz, but I don't see any events or graphs in the SigNoz dashboard. What should I do?
This could be because of one of the following reasons:
Your application is generating telemetry data, but not able to connect with SigNoz installation
Please use this troubleshooting guide to find if your application is able to access SigNoz installation and send data to it.
Your application is not actually generating telemetry data
Please check if the application is generating telemetry data first. You can use
Console Exporterto just print your telemetry data in console first. Join our Slack Community if you need help on how to export your telemetry data in consoleYour SigNoz installation is not running or behind a firewall
Please double check if the pods in SigNoz installation are running fine.
docker psorkubectl get pods -n platformare your friends for this.
What Cloud Endpoint Should I Use?
The primary method for sending data to SigNoz Cloud is through OTLP exporters. You can either send the data directly from your application using the exporters available in SDKs/language agents or send the data to a collector agent, which batches/enriches telemetry and sends it to the Cloud.
My Collector Sends Data to SigNoz Cloud
Using gRPC Exporter
The endpoint should be ingest.{region}.signoz.cloud:443, where {region} should be replaced with in, us, or eu. Note that the exporter endpoint doesn't require a scheme for the gRPC exporter in the collector.
# Sample config with `us` region
exporters:
otlp:
endpoint: "ingest.us.signoz.cloud:443"
tls:
insecure: false
headers:
"signoz-ingestion-key": "<SIGNOZ_INGESTION_KEY>"
Using HTTP Exporter
The endpoint should be https://ingest.{region}.signoz.cloud:443, where {region} should be replaced with in, us, or eu. Note that the endpoint includes the scheme https for the HTTP exporter in the collector.
# Sample config with `us` region
exporters:
otlphttp:
endpoint: "https://ingest.us.signoz.cloud:443"
tls:
insecure: false
headers:
"signoz-ingestion-key": "<SIGNOZ_INGESTION_KEY>"
My Application Sends Data to SigNoz Cloud
The endpoint should be configured either with environment variables or in the SDK setup code.
Using Environment Variables
Using gRPC Exporter
Examples with us region
OTEL_EXPORTER_OTLP_PROTOCOL=grpc OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.us.signoz.cloud:443 OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<SIGNOZ_INGESTION_KEY>
Using HTTP Exporter
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.us.signoz.cloud:443 OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<SIGNOZ_INGESTION_KEY>
Configuring Endpoint in Code
Please refer to the agent documentation.
Sending Data from a Third-Party Service
The endpoint configuration here depends on the export protocol supported by the third-party service. They may support either gRPC, HTTP, or both. Generally, you will need to adjust the host and port. The host address should be ingest.{region}.signoz.cloud:443, where {region} should be replaced with in, us, or eu, and port 443 should be used.