# OpenTelemetry Developer Handbook – Azure, GCP & AWS

<div id="bkmrk-chapter-1-what-is-op" style="font-family: Arial,Helvetica,sans-serif; font-size: 15px; color: #2c2c2c; line-height: 1.65;"><table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;"><tbody><tr><td style="width: 52px; vertical-align: top; padding-right: 14px; padding-top: 2px;"><div style="font-size: 9px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; color: #1abb9c; text-align: center; margin-bottom: 2px;">Chapter</div><div style="width: 38px; height: 38px; background: #1f3863; color: #ffffff; font-weight: bold; font-size: 18px; text-align: center; line-height: 38px; border-radius: 2px;">1</div></td><td style="vertical-align: middle; border-bottom: 2px solid #1f3863; padding-bottom: 12px;">## What is OpenTelemetry?

</td></tr></tbody></table>

</div>**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.

<div id="bkmrk-%F0%9F%92%A1-why-should-you-car" style="font-family: Arial,Helvetica,sans-serif; font-size: 15px; color: #2c2c2c; line-height: 1.65;"><table style="width: 100%; border-collapse: collapse; margin: 14px 0;"><tbody><tr><td style="border-left: 4px solid #2d75b6; background: #eef4fb; padding: 12px 16px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="width: 28px; vertical-align: top; padding-right: 10px; font-size: 16px;">💡</td><td style="vertical-align: top;">**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.

</td></tr></tbody></table>

</td></tr></tbody></table>

</div>### The Three Pillars of Observability

<div id="bkmrk-%F0%9F%94%8D-traces-a-trace-fol" style="font-family: Arial,Helvetica,sans-serif; font-size: 15px; color: #2c2c2c; line-height: 1.65;"><table style="width: 100%; border-collapse: collapse; margin: 12px 0;"><tbody><tr><td style="width: 33%; vertical-align: top; padding-right: 6px;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="background: #ffffff; border: 1px solid #c8d4e0; border-top: 3px solid #1abb9c; padding: 14px; vertical-align: top;"><div style="font-size: 20px; margin-bottom: 6px;">🔍</div>**Traces**A trace follows a single request across multiple services. Each step is a **span**.

</td></tr></tbody></table>

</td><td style="width: 33%; vertical-align: top; padding: 0 3px;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="background: #ffffff; border: 1px solid #c8d4e0; border-top: 3px solid #1abb9c; padding: 14px; vertical-align: top;"><div style="font-size: 20px; margin-bottom: 6px;">📊</div>**Metrics**Numeric measurements over time: request count, error rate, memory usage, custom KPIs.

</td></tr></tbody></table>

</td><td style="width: 33%; vertical-align: top; padding-left: 6px;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="background: #ffffff; border: 1px solid #c8d4e0; border-top: 3px solid #1abb9c; padding: 14px; vertical-align: top;"><div style="font-size: 20px; margin-bottom: 6px;">📝</div>**Logs**Timestamped event records. OTel correlates logs with the exact trace and span they belong to.

</td></tr></tbody></table>

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin: 14px 0;"><tbody><tr><td style="border-left: 4px solid #1abb9c; background: #eefaf7; padding: 12px 16px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="width: 28px; vertical-align: top; padding-right: 10px; font-size: 16px;">✅</td><td style="vertical-align: top;">**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.

</td></tr></tbody></table>

</td></tr></tbody></table>

---

<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;"><tbody><tr><td style="width: 52px; vertical-align: top; padding-right: 14px; padding-top: 2px;"><div style="font-size: 9px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; color: #1abb9c; text-align: center; margin-bottom: 2px;">Chapter</div><div style="width: 38px; height: 38px; background: #1f3863; color: #ffffff; font-weight: bold; font-size: 18px; text-align: center; line-height: 38px; border-radius: 2px;">2</div></td><td style="vertical-align: middle; border-bottom: 2px solid #1f3863; padding-bottom: 12px;">## Getting Started – Your First Instrumented App

</td></tr></tbody></table>

</div>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
```

<div id="bkmrk-%E2%9C%85-traces-working%21-co" style="font-family: Arial,Helvetica,sans-serif; font-size: 15px; color: #2c2c2c; line-height: 1.65;"><table style="width: 100%; border-collapse: collapse; margin: 14px 0;"><tbody><tr><td style="border-left: 4px solid #1abb9c; background: #eefaf7; padding: 12px 16px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="width: 28px; vertical-align: top; padding-right: 10px; font-size: 16px;">✅</td><td style="vertical-align: top;">**Traces working!**ConsoleSpanExporter is only for development. The next chapters replace it with a real cloud exporter.

</td></tr></tbody></table>

</td></tr></tbody></table>

---

<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;"><tbody><tr><td style="width: 52px; vertical-align: top; padding-right: 14px; padding-top: 2px;"><div style="font-size: 9px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; color: #1abb9c; text-align: center; margin-bottom: 2px;">Chapter</div><div style="width: 38px; height: 38px; background: #0078d4; color: #ffffff; font-weight: bold; font-size: 18px; text-align: center; line-height: 38px; border-radius: 2px;">3</div></td><td style="vertical-align: middle; border-bottom: 2px solid #1f3863; padding-bottom: 12px;">## Connecting to Microsoft Azure

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin: 0 0 36px;"><tbody><tr><td style="border-left: 4px solid #0078d4; background: #f0f6fd; padding: 18px 22px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse; margin-bottom: 14px; border-bottom: 1px solid #c8d4e0; padding-bottom: 12px;"><tbody><tr><td style="width: 50px; vertical-align: middle; padding-right: 12px;"><div style="width: 36px; height: 36px; background: #0078d4; color: #ffffff; font-weight: 800; font-size: 12px; text-align: center; line-height: 36px; border-radius: 3px;">Az</div></td><td style="vertical-align: middle;">**Azure Monitor + Application Insights** <span style="font-size: 11px; color: #5a6a80;">The Azure-native observability backend for OTel</span></td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #0078d4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">1</div></td><td style="vertical-align: top;">**Create an Application Insights Resource**Azure Portal → "Application Insights" → Create. Copy the **Connection String** from the resource overview.

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #0078d4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">2</div></td><td style="vertical-align: top;">**Install the Azure Monitor exporter**```
npm install @azure/monitor-opentelemetry-exporter
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #0078d4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">3</div></td><td style="vertical-align: top;">**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();
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #0078d4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">4</div></td><td style="vertical-align: top;">**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
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #0078d4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">5</div></td><td style="vertical-align: top;">**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
```

</td></tr></tbody></table>

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;"><tbody><tr><td style="width: 52px; vertical-align: top; padding-right: 14px; padding-top: 2px;"><div style="font-size: 9px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; color: #1abb9c; text-align: center; margin-bottom: 2px;">Chapter</div><div style="width: 38px; height: 38px; background: #4285f4; color: #ffffff; font-weight: bold; font-size: 18px; text-align: center; line-height: 38px; border-radius: 2px;">4</div></td><td style="vertical-align: middle; border-bottom: 2px solid #1f3863; padding-bottom: 12px;">## Connecting to Google Cloud (GCP)

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin: 0 0 36px;"><tbody><tr><td style="border-left: 4px solid #4285f4; background: #f0f4ff; padding: 18px 22px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse; margin-bottom: 14px; border-bottom: 1px solid #c8d4e0; padding-bottom: 12px;"><tbody><tr><td style="width: 50px; vertical-align: middle; padding-right: 12px;"><div style="width: 36px; height: 36px; background: #4285f4; color: #ffffff; font-weight: 800; font-size: 12px; text-align: center; line-height: 36px; border-radius: 3px;">G</div></td><td style="vertical-align: middle;">**Cloud Trace + Cloud Monitoring** <span style="font-size: 11px; color: #5a6a80;">Google Cloud's distributed tracing and metrics platform</span></td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #4285f4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">1</div></td><td style="vertical-align: top;">**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" 
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #4285f4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">2</div></td><td style="vertical-align: top;">**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();
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #4285f4; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">3</div></td><td style="vertical-align: top;">**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.

</td></tr></tbody></table>

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;"><tbody><tr><td style="width: 52px; vertical-align: top; padding-right: 14px; padding-top: 2px;"><div style="font-size: 9px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; color: #1abb9c; text-align: center; margin-bottom: 2px;">Chapter</div><div style="width: 38px; height: 38px; background: #e67d21; color: #ffffff; font-weight: bold; font-size: 18px; text-align: center; line-height: 38px; border-radius: 2px;">5</div></td><td style="vertical-align: middle; border-bottom: 2px solid #1f3863; padding-bottom: 12px;">## Connecting to Amazon Web Services (AWS)

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin: 0 0 36px;"><tbody><tr><td style="border-left: 4px solid #e67d21; background: #fff6ee; padding: 18px 22px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse; margin-bottom: 14px; border-bottom: 1px solid #c8d4e0; padding-bottom: 12px;"><tbody><tr><td style="width: 50px; vertical-align: middle; padding-right: 12px;"><div style="width: 36px; height: 36px; background: #232f3e; color: #e67d21; font-weight: 800; font-size: 12px; text-align: center; line-height: 36px; border-radius: 3px;">AWS</div></td><td style="vertical-align: middle;">**AWS X-Ray + CloudWatch + ADOT** <span style="font-size: 11px; color: #5a6a80;">AWS Distro for OpenTelemetry — AWS's official OTel distribution</span></td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin: 14px 0;"><tbody><tr><td style="border-left: 4px solid #2d75b6; background: #eef4fb; padding: 12px 16px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="width: 28px; vertical-align: top; padding-right: 10px; font-size: 16px;">📌</td><td style="vertical-align: top;">**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.

</td></tr></tbody></table>

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #e67d21; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">1</div></td><td style="vertical-align: top;">**Install ADOT packages**```
npm install @opentelemetry/id-generator-aws-xray @opentelemetry/propagator-aws-xray @opentelemetry/exporter-trace-otlp-grpc
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #e67d21; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">2</div></td><td style="vertical-align: top;">**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();
```

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 14px;"><tbody><tr><td style="width: 38px; vertical-align: top; padding-right: 12px; padding-top: 2px;"><div style="width: 26px; height: 26px; background: #e67d21; color: #ffffff; font-weight: bold; font-size: 13px; text-align: center; line-height: 26px; border-radius: 2px;">3</div></td><td style="vertical-align: top;">**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.

</td></tr></tbody></table>

</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin-bottom: 20px;"><tbody><tr><td style="width: 52px; vertical-align: top; padding-right: 14px; padding-top: 2px;"><div style="font-size: 9px; font-weight: bold; letter-spacing: 2px; text-transform: uppercase; color: #1abb9c; text-align: center; margin-bottom: 2px;">Chapter</div><div style="width: 38px; height: 38px; background: #1f3863; color: #ffffff; font-weight: bold; font-size: 18px; text-align: center; line-height: 38px; border-radius: 2px;">6</div></td><td style="vertical-align: middle; border-bottom: 2px solid #1f3863; padding-bottom: 12px;">## Best Practices &amp; Quick Reference

</td></tr></tbody></table>

</div>### Quick Comparison: Azure vs GCP vs AWS

<div id="bkmrk-feature-azure-monito" style="font-family: Arial,Helvetica,sans-serif; font-size: 15px; color: #2c2c2c; line-height: 1.65;"><table style="width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 13px; border: 1px solid #c8d4e0;"><thead><tr><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">Feature</th><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">Azure Monitor</th><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">GCP Cloud Trace</th><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">AWS X-Ray</th></tr></thead><tbody><tr><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">**Trace backend**</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Application Insights</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Cloud Trace</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">AWS X-Ray</td></tr><tr style="background: #f4f8fc;"><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">**Metric backend**</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Azure Monitor Metrics</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Cloud Monitoring</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Amazon CloudWatch</td></tr><tr><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">**Auth method**</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Connection String</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Service Account JSON</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">IAM Role / Keys</td></tr><tr style="background: #f4f8fc;"><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">**Query language**</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">KQL (Kusto)</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Filter expressions</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">CloudWatch Insights</td></tr><tr><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">**Free tier**</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">5 GB/month</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">2.5M spans/month</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">100K traces/month</td></tr><tr style="background: #f4f8fc;"><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">**Special note**</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">None</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Enable APIs in console</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">X-Ray ID generator required</td></tr></tbody></table>

</div>### Common Errors and Fixes

<div id="bkmrk-error-cause-fix-no-s" style="font-family: Arial,Helvetica,sans-serif; font-size: 15px; color: #2c2c2c; line-height: 1.65;"><table style="width: 100%; border-collapse: collapse; margin: 12px 0; font-size: 13px; border: 1px solid #c8d4e0;"><thead><tr><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">Error</th><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">Cause</th><th style="background: #1f3863; color: #ffffff; font-weight: bold; text-align: left; padding: 8px 12px; font-size: 11px; text-transform: uppercase;">Fix</th></tr></thead><tbody><tr><td style="padding: 7px 12px; border: 1px solid #c8d4e0; font-family: 'Courier New',monospace; font-size: 11px;">No spans exported</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">SDK not started before app</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0; font-family: 'Courier New',monospace; font-size: 11px;">node -r ./instrumentation.js app.js</td></tr><tr style="background: #f4f8fc;"><td style="padding: 7px 12px; border: 1px solid #c8d4e0; font-family: 'Courier New',monospace; font-size: 11px;">401 Unauthorized (Azure)</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Wrong connection string</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Check APPLICATIONINSIGHTS\_CONNECTION\_STRING</td></tr><tr><td style="padding: 7px 12px; border: 1px solid #c8d4e0; font-family: 'Courier New',monospace; font-size: 11px;">PERMISSION\_DENIED (GCP)</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Missing SA roles</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0; font-family: 'Courier New',monospace; font-size: 11px;">Add roles/cloudtrace.agent</td></tr><tr style="background: #f4f8fc;"><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Traces missing in X-Ray</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Missing ID generator</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Add idGenerator: new AWSXRayIdGenerator()</td></tr><tr><td style="padding: 7px 12px; border: 1px solid #c8d4e0; font-family: 'Courier New',monospace; font-size: 11px;">ECONNREFUSED :4317</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Collector not running</td><td style="padding: 7px 12px; border: 1px solid #c8d4e0;">Start the Collector container first</td></tr></tbody></table>

<table style="width: 100%; border-collapse: collapse; margin: 14px 0;"><tbody><tr><td style="border-left: 4px solid #1abb9c; background: #eefaf7; padding: 12px 16px; vertical-align: top;"><table style="width: 100%; border-collapse: collapse;"><tbody><tr><td style="width: 28px; vertical-align: top; padding-right: 10px; font-size: 16px;">🎯</td><td style="vertical-align: top;">**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.

</td></tr></tbody></table>

</td></tr></tbody></table>

---

</div>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+.