OpenTelemetry Developer Handbook – Azure, GCP & AWS Chapter 1 What is OpenTelemetry? OpenTelemetry (OTel) is an open-source observability framework and toolkit that gives you a single, vendor-neutral way to generate, collect and export telemetry data — the signals your application produces to tell you what it is doing and how healthy it is. It is a CNCF Graduated project (the highest maturity level), widely adopted by Google, Microsoft, AWS, Datadog, and hundreds of others. 💡 Why should you care as a junior developer? When something breaks in production, you need to know where it broke, why, and how long it has been broken. OpenTelemetry gives you that information automatically, with one consistent standard. The Three Pillars of Observability 🔍 Traces A trace follows a single request across multiple services. Each step is a span. 📊 Metrics Numeric measurements over time: request count, error rate, memory usage, custom KPIs. 📝 Logs Timestamped event records. OTel correlates logs with the exact trace and span they belong to. ✅ OTel Collector is your best friend The Collector receives data from your app, transforms or filters it, and forwards it to one or many backends. Switch cloud vendors without changing application code. Chapter 2 Getting Started – Your First Instrumented App We will use Node.js as the example. The same concepts apply to Python, Java, Go, .NET, etc. Step 1 – Install the Core SDK Packages npm install @opentelemetry/api @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/sdk-trace-node @opentelemetry/sdk-metrics @opentelemetry/resources @opentelemetry/semantic-conventions Step 2 – Create instrumentation.js // instrumentation.js — load BEFORE your app const {{ NodeSDK }} = require('@opentelemetry/sdk-node'); const {{ getNodeAutoInstrumentations }} = require('@opentelemetry/auto-instrumentations-node'); const {{ Resource }} = require('@opentelemetry/resources'); const {{ SemanticResourceAttributes }} = require('@opentelemetry/semantic-conventions'); const {{ ConsoleSpanExporter }} = require('@opentelemetry/sdk-trace-node'); const sdk = new NodeSDK({{ resource: new Resource({{ [SemanticResourceAttributes.SERVICE_NAME]: 'my-first-service', [SemanticResourceAttributes.SERVICE_VERSION]: '1.0.0', }}), traceExporter: new ConsoleSpanExporter(), instrumentations: [getNodeAutoInstrumentations()], }}); sdk.start(); process.on('SIGTERM', () => sdk.shutdown().finally(() => process.exit(0))); Step 3 – Run your app node -r ./instrumentation.js app.js ✅ Traces working! ConsoleSpanExporter is only for development. The next chapters replace it with a real cloud exporter. Chapter 3 Connecting to Microsoft Azure Az Azure Monitor + Application Insights The Azure-native observability backend for OTel 1 Create an Application Insights Resource Azure Portal → "Application Insights" → Create. Copy the Connection String from the resource overview. 2 Install the Azure Monitor exporter npm install @azure/monitor-opentelemetry-exporter 3 Update instrumentation.js const {{ AzureMonitorTraceExporter }} = require('@azure/monitor-opentelemetry-exporter'); const {{ AzureMonitorMetricExporter }} = require('@azure/monitor-opentelemetry-exporter'); const {{ PeriodicExportingMetricReader }} = require('@opentelemetry/sdk-metrics'); const connectionString = process.env.APPLICATIONINSIGHTS_CONNECTION_STRING; const sdk = new NodeSDK({{ traceExporter: new AzureMonitorTraceExporter({{ connectionString }}), metricReader: new PeriodicExportingMetricReader({{ exporter: new AzureMonitorMetricExporter({{ connectionString }}), exportIntervalMillis: 60000, }}), instrumentations: [getNodeAutoInstrumentations()], }}); sdk.start(); 4 Set environment variable and run # Linux / macOS export APPLICATIONINSIGHTS_CONNECTION_STRING="InstrumentationKey=xxx;..." node -r ./instrumentation.js app.js # Windows PowerShell $env:APPLICATIONINSIGHTS_CONNECTION_STRING = "InstrumentationKey=xxx;..." node -r ./instrumentation.js app.js 5 Verify in Azure Portal Azure Portal → Application Insights → Transaction Search, Application Map, Performance, Logs (KQL). requests | where timestamp > ago(1h) and duration > 500 | project timestamp, name, duration, resultCode | order by duration desc | take 50 Chapter 4 Connecting to Google Cloud (GCP) G Cloud Trace + Cloud Monitoring Google Cloud's distributed tracing and metrics platform 1 Enable APIs and create a Service Account gcloud services enable cloudtrace.googleapis.com monitoring.googleapis.com gcloud iam service-accounts create otel-exporter gcloud projects add-iam-policy-binding YOUR_PROJECT_ID --member="serviceAccount:otel-exporter@YOUR_PROJECT_ID.iam.gserviceaccount.com" --role="roles/cloudtrace.agent" gcloud iam service-accounts keys create ./gcp-otel-key.json --iam-account="otel-exporter@YOUR_PROJECT_ID.iam.gserviceaccount.com" 2 Install and configure GCP exporters npm install @google-cloud/opentelemetry-cloud-trace-exporter @google-cloud/opentelemetry-cloud-monitoring-exporter const {{ TraceExporter }} = require('@google-cloud/opentelemetry-cloud-trace-exporter'); const {{ MetricExporter }} = require('@google-cloud/opentelemetry-cloud-monitoring-exporter'); const projectId = process.env.GOOGLE_CLOUD_PROJECT; const sdk = new NodeSDK({{ traceExporter: new TraceExporter({{ projectId }}), metricReader: new PeriodicExportingMetricReader({{ exporter: new MetricExporter({{ projectId }}), exportIntervalMillis: 60000, }}), instrumentations: [getNodeAutoInstrumentations()], }}); sdk.start(); 3 Set credentials and run export GOOGLE_APPLICATION_CREDENTIALS="./gcp-otel-key.json" export GOOGLE_CLOUD_PROJECT="your-gcp-project-id" node -r ./instrumentation.js app.js Google Cloud Console → Cloud Trace → Trace Explorer → click any trace for the full span view. Chapter 5 Connecting to Amazon Web Services (AWS) AWS AWS X-Ray + CloudWatch + ADOT AWS Distro for OpenTelemetry — AWS's official OTel distribution 📌 AWS X-Ray uses a special trace format X-Ray requires timestamp-based trace IDs. You must include AWSXRayIdGenerator or traces will not appear correctly. 1 Install ADOT packages npm install @opentelemetry/id-generator-aws-xray @opentelemetry/propagator-aws-xray @opentelemetry/exporter-trace-otlp-grpc 2 Update instrumentation.js const {{ AWSXRayIdGenerator }} = require('@opentelemetry/id-generator-aws-xray'); const {{ AWSXRayPropagator }} = require('@opentelemetry/propagator-aws-xray'); const {{ OTLPTraceExporter }} = require('@opentelemetry/exporter-trace-otlp-grpc'); const {{ propagation }} = require('@opentelemetry/api'); propagation.setGlobalPropagator(new AWSXRayPropagator()); const sdk = new NodeSDK({{ idGenerator: new AWSXRayIdGenerator(), // CRITICAL for X-Ray traceExporter: new OTLPTraceExporter({{ url: 'grpc://localhost:4317' }}), instrumentations: [getNodeAutoInstrumentations()], }}); sdk.start(); 3 Run and verify in AWS Console export AWS_REGION=us-east-1 node -r ./instrumentation.js app.js AWS Console → CloudWatch → X-Ray → Traces. Check X-Ray → Service Map for auto-generated topology. Chapter 6 Best Practices & Quick Reference Quick Comparison: Azure vs GCP vs AWS Feature Azure Monitor GCP Cloud Trace AWS X-Ray Trace backend Application Insights Cloud Trace AWS X-Ray Metric backend Azure Monitor Metrics Cloud Monitoring Amazon CloudWatch Auth method Connection String Service Account JSON IAM Role / Keys Query language KQL (Kusto) Filter expressions CloudWatch Insights Free tier 5 GB/month 2.5M spans/month 100K traces/month Special note None Enable APIs in console X-Ray ID generator required Common Errors and Fixes Error Cause Fix No spans exported SDK not started before app node -r ./instrumentation.js app.js 401 Unauthorized (Azure) Wrong connection string Check APPLICATIONINSIGHTS_CONNECTION_STRING PERMISSION_DENIED (GCP) Missing SA roles Add roles/cloudtrace.agent Traces missing in X-Ray Missing ID generator Add idGenerator: new AWSXRayIdGenerator() ECONNREFUSED :4317 Collector not running Start the Collector container first 🎯 Next steps 1. Add custom spans to your key business functions. 2. Add custom metrics (orders.processed, queue.depth). 3. Set up alerts on error rate and p99 latency. 4. Explore OTel Collector processors: filter, attributes, tail_sampling. 5. Read the official docs at opentelemetry.io. OpenTelemetry Developer Handbook OpenTelemetry is a CNCF Graduated project. All cloud vendor names are trademarks of their respective owners. Targets OTel SDK 1.x and Node.js 18+.