Overview
This guide walks you through migrating distributed tracing and APM from the ELK Stack (Elastic APM) to SigNoz. You will:
- Assess your current Elastic APM services
- Replace Elastic APM agents with OpenTelemetry instrumentation
- Validate traces are flowing correctly to SigNoz
SigNoz is built natively on OpenTelemetry, so migration involves replacing proprietary Elastic APM agents with standard OpenTelemetry SDKs.
Prerequisites
Before starting, ensure you have:
- A SigNoz account (Cloud) or a running SigNoz instance (Self-Hosted)
- Access to your application source code
- List of services currently instrumented with Elastic APM
Step 1: Assess Your Current Tracing Setup
Inventory which services are using Elastic APM agents.
Identify Instrumented Services
Check your applications for Elastic APM dependencies:
- Java:
elastic-apm-agent.jar - Node.js:
elastic-apm-nodepackage - Python:
elastic-apmpackage - Go:
go.elastic.co/apmmodule - .NET: Elastic APM .NET Agent
Categorize Your Services
Group services by language to plan the migration path:
| Language | Elastic Agent | Migration Path |
|---|---|---|
| Java | Java Agent | Replace with OTel Java Agent |
| Node.js | Node.js Agent | Replace with OTel Node.js SDK |
| Python | Python Agent | Replace with OTel Python SDK |
| Go | Go Agent | Replace with OTel Go SDK |
| .NET | .NET Agent | Replace with OTel .NET SDK |
Step 2: Migrate Each Service
Work through each service from your inventory.
From Elastic APM Java Agent
Step 1: Remove Elastic APM
- Remove the
-javaagent:/path/to/elastic-apm-agent.jarflag. - Remove
elasticapm.propertiesif present.
Step 2: Add OpenTelemetry Java Agent Download the agent:
curl -L -o opentelemetry-javaagent.jar \
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
Step 3: Configure and Run
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.service.name=your-service-name \
-Dotel.exporter.otlp.endpoint=https://ingest.<region>.signoz.cloud:443 \
-Dotel.exporter.otlp.headers=signoz-ingestion-key=<SIGNOZ_INGESTION_KEY> \
-jar your-application.jar
See Java Instrumentation for details.
From Elastic APM Node.js Agent
Step 1: Remove Elastic APM
npm uninstall elastic-apm-node
Remove require('elastic-apm-node').start(...) from your code.
Step 2: Add OpenTelemetry
npm install @opentelemetry/auto-instrumentations-node
Step 3: Configure and Run
export OTEL_SERVICE_NAME=your-service-name
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<region>.signoz.cloud:443
export OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<SIGNOZ_INGESTION_KEY>
export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
node app.js
See Node.js Instrumentation for details.
From Elastic APM Python Agent
Step 1: Remove Elastic APM
pip uninstall elastic-apm
Remove elasticapm imports and initialization from your code.
Step 2: Add OpenTelemetry
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
Step 3: Configure and Run
export OTEL_SERVICE_NAME=your-service-name
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<region>.signoz.cloud:443
export OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<SIGNOZ_INGESTION_KEY>
opentelemetry-instrument python app.py
See Python Instrumentation for details.
From Elastic APM Go Agent
Step 1: Remove Elastic APM Remove go.elastic.co/apm imports and initialization code.
Step 2: Install OpenTelemetry
go get go.opentelemetry.io/otel \
go.opentelemetry.io/otel/sdk \
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
Step 3: Instrument Code Initialize the OTel tracer and replace Elastic transactions with OTel spans.
See Go Instrumentation for complete setup.
From Elastic APM .NET Agent
Step 1: Remove Elastic APM Uninstall the Elastic APM .NET agent and remove Elastic.Apm packages.
Step 2: Add OpenTelemetry Use the OpenTelemetry .NET Automatic Instrumentation.
Step 3: Configure and Run
export OTEL_SERVICE_NAME=your-service-name
export OTEL_EXPORTER_OTLP_ENDPOINT=https://ingest.<region>.signoz.cloud:443
export OTEL_EXPORTER_OTLP_HEADERS=signoz-ingestion-key=<SIGNOZ_INGESTION_KEY>
. $HOME/.otel-dotnet-auto/instrument.sh
dotnet run
Other Languages
For languages not listed above (Ruby, PHP, Rust, Elixir, etc.), please refer to the SigNoz Instrumentation Documentation to find the specific guide for your application.
Validate
Verify traces are flowing correctly by comparing against your service inventory.
Check Services Are Reporting
- In SigNoz, navigate to Services in the left sidebar.
- Verify each service from your inventory appears in the list.
- Click a service to see its metrics (latency, error rate, throughput).
Verify Traces
- Navigate to Traces in the left sidebar.
- Select a service and time range.
- Verify spans appear with expected attributes.
- Check that trace context propagates across service boundaries.
Troubleshooting
Traces not appearing in SigNoz
- Check connectivity: Verify your application can reach
ingest.<region>.signoz.cloud:443. - Verify service name: Ensure
OTEL_SERVICE_NAMEis set. - Check application logs: Look for OpenTelemetry exporter errors.
- Enable debug logging: Set
OTEL_LOG_LEVEL=debugto see detailed SDK logs.
Broken or incomplete traces
- Check context propagation: Ensure all services use compatible propagation (W3C Trace Context).
- Verify all services are instrumented: Missing instrumentation on any service breaks the trace chain.
Next Steps
Once your traces are flowing to SigNoz:
- Create dashboards with trace-based panels
- Set up trace-based alerts for latency and errors
- Correlate traces with logs for debugging
- Explore the Service Map