DEV Community

Alexandr Bandurchin for Uptrace

Posted on

OpenTelemetry Zero-Code Instrumentation

Adding observability to applications traditionally requires extensive code changes—importing SDKs, creating spans, configuring exporters. Zero-code instrumentation eliminates this friction by automatically capturing telemetry data through agents and runtime modifications, enabling observability without touching application code.

What is Zero-Code Instrumentation?

Zero-code instrumentation (also called automatic instrumentation) uses agents that attach to your application at runtime and automatically instrument popular libraries and frameworks. These agents intercept function calls, network requests, and database queries to generate distributed traces, metrics, and logs without requiring source code changes.

How it works:

  • Java/JVM: Bytecode manipulation at class load time using Java agents
  • Python/Node.js: Runtime monkey-patching of library functions
  • .NET: CLR profiling APIs to modify IL code
  • Go: eBPF-based instrumentation via kernel probes (Kubernetes only)
  • PHP: Zend extension hooks

The agent captures telemetry from instrumented libraries and exports it to OpenTelemetry backends using the OTLP protocol.

Zero-Code vs Manual Instrumentation

Aspect Zero-Code Instrumentation Manual Instrumentation
Setup Time 5-10 minutes Hours to days
Code Changes None required Extensive modifications
Coverage Framework/library operations only Full application including business logic
Customization Limited to agent configuration Complete control over spans and attributes
Maintenance Agent updates only Code changes for new instrumentation
Learning Curve Minimal Requires OpenTelemetry SDK knowledge
Performance Impact Moderate (all libraries instrumented) Lower (instrument only critical paths)
Best For Legacy apps, quick start, third-party libraries Custom business metrics, fine-grained control

Recommendation: Start with zero-code instrumentation for immediate visibility, then add manual instrumentation incrementally for business-specific observability.

Supported Languages

OpenTelemetry provides zero-code instrumentation for these languages:

  • Java (production-ready, most mature)
  • .NET (production-ready)
  • Python (production-ready)
  • Node.js (production-ready)
  • PHP (stable)
  • Go (eBPF-based, Kubernetes only, experimental)

Each language uses different techniques based on runtime capabilities.

Java Zero-Code Instrumentation

Java's bytecode manipulation makes it ideal for zero-code instrumentation. The OpenTelemetry Java agent works with any JVM-based application.

Installation

Download the latest Java agent (v2.23.0):

wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.23.0/opentelemetry-javaagent.jar
Enter fullscreen mode Exit fullscreen mode

Configuration

Configure the agent using environment variables. The examples below use Uptrace as the OTLP backend, but you can use any OpenTelemetry-compatible backend (Jaeger, Grafana Tempo, etc.) by changing the OTEL_EXPORTER_OTLP_ENDPOINT.

export OTEL_SERVICE_NAME=my-java-app
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_uptrace_dsn>

# Run your application with the agent
java -javaagent:opentelemetry-javaagent.jar -jar myapp.jar
Enter fullscreen mode Exit fullscreen mode

Spring Boot Example

No code changes required for Spring Boot applications:

# Download agent
wget https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.23.0/opentelemetry-javaagent.jar

# Set environment variables
export OTEL_SERVICE_NAME=spring-boot-app
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_dsn>

# Run Spring Boot with agent
java -javaagent:opentelemetry-javaagent.jar -jar target/myapp-0.0.1-SNAPSHOT.jar
Enter fullscreen mode Exit fullscreen mode

The agent automatically instruments:

  • Spring Web MVC / Spring WebFlux
  • JDBC database calls
  • HTTP clients (Apache HttpClient, OkHttp, etc.)
  • Kafka, RabbitMQ, Redis
  • RestTemplate, WebClient
  • JPA/Hibernate queries

Dockerfile Example

FROM openjdk:17-slim

WORKDIR /app

# Download OpenTelemetry Java agent
ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/v2.23.0/opentelemetry-javaagent.jar /app/opentelemetry-javaagent.jar

COPY target/myapp.jar /app/app.jar

# Configure OpenTelemetry
ENV OTEL_SERVICE_NAME=my-service
ENV OTEL_TRACES_EXPORTER=otlp
ENV OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317

CMD ["java", "-javaagent:/app/opentelemetry-javaagent.jar", "-jar", "/app/app.jar"]
Enter fullscreen mode Exit fullscreen mode

.NET Zero-Code Instrumentation

The OpenTelemetry .NET automatic instrumentation uses CLR profiling APIs to instrument .NET applications.

Installation (Windows)

Download and install the latest .NET instrumentation (v1.13.0):

# Download installer
Invoke-WebRequest -Uri "https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v1.13.0/opentelemetry-dotnet-instrumentation-windows.zip" -OutFile "otel-dotnet-auto.zip"
# Extract
Expand-Archive -Path otel-dotnet-auto.zip -DestinationPath "C:\otel-dotnet-auto"
# Install
C:\otel-dotnet-auto\install.cmd
Enter fullscreen mode Exit fullscreen mode

Installation (Linux)

Note: .NET CLR profiling requires many environment variables for runtime hooks. Consider using Docker or Kubernetes Operator to simplify configuration and avoid manual setup errors.

# Download and extract
wget https://github.com/open-telemetry/opentelemetry-dotnet-instrumentation/releases/download/v1.13.0/opentelemetry-dotnet-instrumentation-linux-glibc.zip
unzip opentelemetry-dotnet-instrumentation-linux-glibc.zip -d /opt/otel-dotnet-auto

# Set environment variables
export OTEL_DOTNET_AUTO_HOME=/opt/otel-dotnet-auto
export CORECLR_ENABLE_PROFILING=1
export CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}
export CORECLR_PROFILER_PATH=$OTEL_DOTNET_AUTO_HOME/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
export DOTNET_STARTUP_HOOKS=$OTEL_DOTNET_AUTO_HOME/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll
export DOTNET_ADDITIONAL_DEPS=$OTEL_DOTNET_AUTO_HOME/AdditionalDeps
export DOTNET_SHARED_STORE=$OTEL_DOTNET_AUTO_HOME/store
Enter fullscreen mode Exit fullscreen mode

Configuration

# Service configuration
export OTEL_SERVICE_NAME=my-dotnet-app
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_dsn>

# Run your application
dotnet myapp.dll
Enter fullscreen mode Exit fullscreen mode

ASP.NET Core Example

# Set required environment variables
export CORECLR_ENABLE_PROFILING=1
export CORECLR_PROFILER={918728DD-259F-4A6A-AC2B-B85E1B658318}
export CORECLR_PROFILER_PATH=/opt/otel-dotnet-auto/linux-x64/OpenTelemetry.AutoInstrumentation.Native.so
export DOTNET_STARTUP_HOOKS=/opt/otel-dotnet-auto/net/OpenTelemetry.AutoInstrumentation.StartupHook.dll

# Service configuration
export OTEL_SERVICE_NAME=aspnet-app
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_dsn>

# Run ASP.NET Core app
dotnet MyWebApp.dll
Enter fullscreen mode Exit fullscreen mode

Automatically instruments:

  • ASP.NET Core MVC / Web API
  • HttpClient requests
  • Entity Framework Core
  • SQL Client (SqlConnection)
  • MongoDB, Redis, Elasticsearch

Python Zero-Code Instrumentation

Python uses the opentelemetry-instrument wrapper to automatically inject instrumentation.

Installation

# Install OpenTelemetry auto-instrumentation
pip install opentelemetry-distro opentelemetry-exporter-otlp

# Bootstrap auto-instrumentation (downloads instrumentation packages)
opentelemetry-bootstrap -a install
Enter fullscreen mode Exit fullscreen mode

Configuration and Usage

Run your Python application with the opentelemetry-instrument wrapper:

export OTEL_SERVICE_NAME=my-python-app
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_dsn>

# Run with automatic instrumentation
opentelemetry-instrument python app.py
Enter fullscreen mode Exit fullscreen mode

Flask Example

Zero-code setup (5 minutes) - just install dependencies and run with the wrapper:

# Install Flask and auto-instrumentation
pip install flask opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install

# app.py (no code changes needed)
# from flask import Flask
# app = Flask(__name__)
#
# @app.route('/')
# def hello():
#     return 'Hello World!'

# Run with auto-instrumentation
export OTEL_SERVICE_NAME=flask-app
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
opentelemetry-instrument flask run
Enter fullscreen mode Exit fullscreen mode

Django Example

Zero-code setup (5 minutes) - just install dependencies and run with the wrapper:

# Install dependencies
pip install django opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install

# Run Django with auto-instrumentation
export OTEL_SERVICE_NAME=django-app
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
opentelemetry-instrument python manage.py runserver
Enter fullscreen mode Exit fullscreen mode

Automatically instruments:

Node.js Zero-Code Instrumentation

Node.js uses the @opentelemetry/auto-instrumentations-node package for automatic instrumentation.

Installation

npm install @opentelemetry/sdk-node \
  @opentelemetry/auto-instrumentations-node \
  @opentelemetry/exporter-trace-otlp-http
Enter fullscreen mode Exit fullscreen mode

Configuration

Create tracing.js in your project root:

// tracing.js
const { NodeSDK } = require('@opentelemetry/sdk-node')
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node')
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http')
const { Resource } = require('@opentelemetry/resources')
const { ATTR_SERVICE_NAME } = require('@opentelemetry/semantic-conventions')

const sdk = new NodeSDK({
  resource: new Resource({
    [ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME || 'nodejs-app',
  }),
  traceExporter: new OTLPTraceExporter({
    url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://localhost:4318/v1/traces',
    headers: {
      'uptrace-dsn': process.env.UPTRACE_DSN,
    },
  }),
  instrumentations: [getNodeAutoInstrumentations()],
})

sdk.start()
Enter fullscreen mode Exit fullscreen mode

Usage

Use the --require flag to load instrumentation before your application:

export OTEL_SERVICE_NAME=nodejs-app
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4318
export UPTRACE_DSN=<your_dsn>

# Run with automatic instrumentation
node --require ./tracing.js app.js
Enter fullscreen mode Exit fullscreen mode

Express.js Example

Zero-code setup (10 minutes) - create tracing file and use --require flag:

// app.js (no changes needed)
const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(3000, () => {
  console.log('Server running on port 3000')
})
Enter fullscreen mode Exit fullscreen mode

Run with instrumentation:

node --require ./tracing.js app.js
Enter fullscreen mode Exit fullscreen mode

Automatically instruments:

  • Express.js, Fastify, Koa, Nest.js
  • HTTP/HTTPS clients
  • MongoDB, MySQL, PostgreSQL, Redis
  • GraphQL, gRPC

PHP Zero-Code Instrumentation

PHP uses a Zend extension for automatic instrumentation.

Installation

# Install via PECL
pecl install opentelemetry

# Or download from releases
wget https://github.com/open-telemetry/opentelemetry-php-instrumentation/releases/latest/download/opentelemetry.so

# Enable extension in php.ini
echo "extension=opentelemetry.so" >> /etc/php/8.2/cli/php.ini
Enter fullscreen mode Exit fullscreen mode

Configuration

export OTEL_SERVICE_NAME=php-app
export OTEL_TRACES_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4318
export OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_dsn>

# Run PHP application
php app.php
Enter fullscreen mode Exit fullscreen mode

Laravel Example

Zero-code setup (5 minutes) with PHP extension - no code changes required:

# Install extension
pecl install opentelemetry

# Configure
export OTEL_SERVICE_NAME=laravel-app
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4318

# Run Laravel
php artisan serve
Enter fullscreen mode Exit fullscreen mode

Go Zero-Code Instrumentation (Kubernetes)

Go doesn't support traditional agent-based instrumentation due to its compiled nature. However, the OpenTelemetry Operator for Kubernetes can use eBPF to instrument Go applications without code changes.

Why Kubernetes only: eBPF (extended Berkeley Packet Filter) requires Linux kernel 4.14+ and CAP_SYS_ADMIN capability to attach kernel probes. This level of system access is only safely available in Kubernetes with proper security contexts and Pod Security Policies.

Prerequisites

  • Kubernetes cluster
  • OpenTelemetry Operator installed

Install OpenTelemetry Operator

# Install cert-manager (required)
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml

# Install OpenTelemetry Operator
kubectl apply -f https://github.com/open-telemetry/opentelemetry-operator/releases/latest/download/opentelemetry-operator.yaml
Enter fullscreen mode Exit fullscreen mode

Configure Instrumentation

Create an Instrumentation resource:

# instrumentation.yaml
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: auto-instrumentation
  namespace: default
spec:
  exporter:
    endpoint: https://api.uptrace.dev:4317
  propagators:
    - tracecontext
    - baggage
  sampler:
    type: parentbased_traceidratio
    argument: "1.0"
  go:
    image: ghcr.io/open-telemetry/opentelemetry-go-instrumentation/autoinstrumentation-go:latest
Enter fullscreen mode Exit fullscreen mode

Apply the configuration:

kubectl apply -f instrumentation.yaml
Enter fullscreen mode Exit fullscreen mode

Instrument Go Deployment

Add the annotation to your deployment:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-app
  template:
    metadata:
      labels:
        app: go-app
      annotations:
        instrumentation.opentelemetry.io/inject-go: "true"  # Enable auto-instrumentation
    spec:
      containers:
      - name: app
        image: my-go-app:latest
        env:
        - name: OTEL_SERVICE_NAME
          value: "go-app"
        - name: OTEL_EXPORTER_OTLP_ENDPOINT
          value: "https://api.uptrace.dev:4317"
        - name: OTEL_EXPORTER_OTLP_HEADERS
          value: "uptrace-dsn=<your_dsn>"
Enter fullscreen mode Exit fullscreen mode

The operator injects an init container and sidecar that use eBPF to instrument the Go application at runtime.
Limitations:

  • Kubernetes only (eBPF requires Linux kernel capabilities)
  • Experimental (not production-ready as of 2025)
  • Limited coverage compared to manual instrumentation ## Kubernetes Multi-Language Auto-Instrumentation The OpenTelemetry Operator can automatically instrument multiple languages in Kubernetes without code changes. ### Example: Multi-Language Application
# instrumentation.yaml
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: multi-lang-instrumentation
  namespace: default
spec:
  exporter:
    endpoint: https://api.uptrace.dev:4317
  propagators:
    - tracecontext
    - baggage
  # Java configuration
  java:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:2.23.0
  # Node.js configuration
  nodejs:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:0.67.3
  # Python configuration
  python:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:0.49b0
  # .NET configuration
  dotnet:
    image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-dotnet:1.13.0
Enter fullscreen mode Exit fullscreen mode

Java Service Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: java-service
spec:
  template:
    metadata:
      annotations:
        instrumentation.opentelemetry.io/inject-java: "true"
    spec:
      containers:
      - name: app
        image: my-java-service:latest
        env:
        - name: OTEL_SERVICE_NAME
          value: "java-service"
Enter fullscreen mode Exit fullscreen mode

Node.js Service Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nodejs-service
spec:
  template:
    metadata:
      annotations:
        instrumentation.opentelemetry.io/inject-nodejs: "true"
    spec:
      containers:
      - name: app
        image: my-nodejs-service:latest
        env:
        - name: OTEL_SERVICE_NAME
          value: "nodejs-service"
Enter fullscreen mode Exit fullscreen mode

The operator automatically injects agents for each language without requiring code changes or custom Dockerfiles.

Configuration Options

Common Environment Variables

These variables work across all languages:

# Service identification
OTEL_SERVICE_NAME=my-service
OTEL_SERVICE_VERSION=1.0.0

# Exporter configuration
OTEL_TRACES_EXPORTER=otlp
OTEL_METRICS_EXPORTER=otlp
OTEL_LOGS_EXPORTER=otlp
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.uptrace.dev:4317
OTEL_EXPORTER_OTLP_HEADERS=uptrace-dsn=<your_dsn>

# Sampling
OTEL_TRACES_SAMPLER=parentbased_traceidratio
OTEL_TRACES_SAMPLER_ARG=0.1  # Sample 10% of traces

# Resource attributes
OTEL_RESOURCE_ATTRIBUTES=deployment.environment=production,service.namespace=ecommerce

# Propagators
OTEL_PROPAGATORS=tracecontext,baggage
Enter fullscreen mode Exit fullscreen mode

Language-Specific Configuration

Java:

# Disable specific instrumentations
OTEL_INSTRUMENTATION_JDBC_ENABLED=false
OTEL_INSTRUMENTATION_SPRING_WEBMVC_ENABLED=true

# JVM system properties
-Dotel.javaagent.debug=true
-Dotel.instrumentation.common.db-statement-sanitizer.enabled=false
Enter fullscreen mode Exit fullscreen mode

.NET:

# Disable specific instrumentations
OTEL_DOTNET_AUTO_TRACES_INSTRUMENTATION_ENABLED=true
OTEL_DOTNET_AUTO_TRACES_ASPNETCORE_INSTRUMENTATION_ENABLED=true
OTEL_DOTNET_AUTO_TRACES_HTTPCLIENT_INSTRUMENTATION_ENABLED=true
Enter fullscreen mode Exit fullscreen mode

Python:

# Disable specific instrumentations
OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=flask,django

# Enable/disable
OTEL_PYTHON_FLASK_EXCLUDED_URLS=/health,/metrics
Enter fullscreen mode Exit fullscreen mode

Node.js:

Disable instrumentations in tracing.js:

instrumentations: [
  getNodeAutoInstrumentations({
    '@opentelemetry/instrumentation-fs': { enabled: false },
    '@opentelemetry/instrumentation-http': { enabled: true },
  }),
]
Enter fullscreen mode Exit fullscreen mode

Limitations of Zero-Code Instrumentation

While zero-code instrumentation provides quick observability, it has limitations:

Generic Span Names

Automatic instrumentation generates generic span names based on framework operations:

❌ Automatic: "GET /api/users"
✅ Manual:    "fetch_active_users_for_dashboard"
Enter fullscreen mode Exit fullscreen mode

No Business Context

Zero-code instrumentation can't capture domain-specific information:

❌ Missing: order.id, user.subscription_tier, cart.total_value
✅ Manual:  Custom attributes for business logic
Enter fullscreen mode Exit fullscreen mode

Framework Coverage Only

Only instrumented libraries generate spans. Custom code remains invisible:

# Automatically traced (HTTP request)
response = requests.get('https://api.example.com/data')

# NOT traced (custom business logic)
def calculate_discount(user, cart):
    # This logic is invisible without manual instrumentation
    return apply_business_rules(user, cart)
Enter fullscreen mode Exit fullscreen mode

Performance Overhead

Instrumenting all libraries can introduce overhead:

  • Java agent adds ~50-100ms startup time
  • Runtime overhead: 1-5% CPU increase (varies by traffic)
  • Memory overhead: 50-200MB additional heap usage

Version Compatibility

Agents may not support the latest library versions immediately. Check compatibility matrix before deploying.

When to Use Zero-Code Instrumentation

Ideal for:

  • Legacy applications: No budget for code refactoring
  • Quick POC: Evaluate OpenTelemetry before committing
  • Third-party libraries: Instrument dependencies you don't control
  • Getting started: Immediate visibility while learning OpenTelemetry
  • Kubernetes environments: Operator-based injection across services

Not ideal for:

  • Business metrics: Custom KPIs require manual instrumentation
  • Performance-critical paths: Lower overhead with selective manual instrumentation
  • Complex transactions: Fine-grained control needs manual spans
  • Proprietary frameworks: Zero-code only supports popular libraries

Hybrid Solution

The most effective strategy combines zero-code and manual instrumentation:

Phase 1: Zero-Code Foundation

Deploy automatic instrumentation to get immediate visibility into framework operations, HTTP requests, and database queries.

Phase 2: Selective Manual Instrumentation

Add manual instrumentation for:

  • Business-critical operations
  • Custom metrics (e.g., checkout success rate)
  • Domain-specific context (user ID, subscription tier)

Example:

// Spring Boot automatically instrumented (zero-code)
@RestController
public class OrderController {

    // HTTP request automatically traced
    @PostMapping("/orders")
    public Order createOrder(@RequestBody OrderRequest request) {

        // Add manual span for business logic
        Span span = tracer.spanBuilder("process_order")
            .setAttribute("order.type", request.getType())
            .setAttribute("user.subscription", getCurrentUser().getSubscription())
            .startSpan();

        try (Scope scope = span.makeCurrent()) {
            // Business logic with custom attributes
            Order order = orderService.create(request);
            span.setAttribute("order.id", order.getId());
            span.setAttribute("order.total", order.getTotal());
            return order;
        } finally {
            span.end();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This approach provides comprehensive coverage: automatic instrumentation for infrastructure, manual instrumentation for business logic.

Troubleshooting

Issue: Agent Not Loading

Symptom: No traces appear in backend.

Solution:

Check agent is attached:

# Java: Look for "opentelemetry-javaagent" in JVM arguments
jps -v | grep opentelemetry

# .NET: Verify profiler environment variables
env | grep CORECLR_PROFILER

# Python: Ensure bootstrap ran successfully
opentelemetry-bootstrap -a list
Enter fullscreen mode Exit fullscreen mode

Enable debug logging:

# Java
export OTEL_JAVAAGENT_DEBUG=true

# .NET
export OTEL_DOTNET_AUTO_LOG_DIRECTORY=/tmp/otel-logs

# Python
export OTEL_LOG_LEVEL=debug

# Node.js
export OTEL_LOG_LEVEL=debug
Enter fullscreen mode Exit fullscreen mode

Issue: Missing Instrumentations

Symptom: Some libraries not instrumented (e.g., Redis calls missing).

Solution:

Verify instrumentation is enabled:

# Java: Check instrumentation status
java -javaagent:opentelemetry-javaagent.jar -jar app.jar --help | grep redis

# Python: List installed instrumentations
pip list | grep opentelemetry-instrumentation

# Node.js: Check auto-instrumentations version
npm list @opentelemetry/auto-instrumentations-node
Enter fullscreen mode Exit fullscreen mode

Some libraries require specific versions. Check compatibility matrix.

Issue: High Performance Overhead

Symptom: CPU usage increased by >10% after enabling instrumentation.

Solution:

Disable unnecessary instrumentations:

# Java: Disable specific instrumentations
export OTEL_INSTRUMENTATION_JDBC_ENABLED=false
export OTEL_INSTRUMENTATION_LOGBACK_ENABLED=false

# Python
export OTEL_PYTHON_DISABLED_INSTRUMENTATIONS=urllib3,requests
Enter fullscreen mode Exit fullscreen mode

Reduce sampling rate:

export OTEL_TRACES_SAMPLER=traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1  # Sample only 10%
Enter fullscreen mode Exit fullscreen mode

Issue: Conflicting Agents

Symptom: Application fails to start with multiple profiling agents.

Solution:

Remove conflicting APM agents (New Relic, AppDynamics, Datadog) before deploying OpenTelemetry. Most JVM profilers cannot coexist.

What is Uptrace?

Uptrace is an open source APM for OpenTelemetry that supports distributed tracing, metrics, and logs. You can use it to monitor applications and troubleshoot issues. For language-specific instrumentation guides, see the instrumentation guides and compare with top APM tools.

Uptrace Overview

Uptrace comes with an intuitive query builder, rich dashboards, alerting rules, notifications, and integrations for most languages and frameworks.

Uptrace can process billions of spans and metrics on a single server and allows you to monitor your applications at 10x lower cost.

In just a few minutes, you can try Uptrace by visiting the cloud demo (no login required) or running it locally with Docker. The source code is available on GitHub.

Next Steps

Top comments (0)