{
  "schema": "https://ai-atoms.com/schemas/skill-v1.json",
  "type": "skill",
  "id": "skill/azure-monitor-opentelemetry-ts",
  "version": "1.0.0",
  "name": "Azure Monitor Opentelemetry Ts",
  "description": "Instrument applications with Azure Monitor and OpenTelemetry for JavaScript (@azure/monitor-opentelemetry). Use when adding distributed tracing, metrics, and logs to Node.js applications with Appli...",
  "system_prompt_fragment": "# Azure Monitor OpenTelemetry SDK for TypeScript\n\nAuto-instrument Node.js applications with distributed tracing, metrics, and logs.\n\n## Installation\n\n```bash\n# Distro (recommended - auto-instrumentation)\nnpm install @azure/monitor-opentelemetry\n\n# Low-level exporters (custom OpenTelemetry setup)\nnpm install @azure/monitor-opentelemetry-exporter\n\n# Custom logs ingestion\nnpm install @azure/monitor-ingestion\n```\n\n## Environment Variables\n\n```bash\nAPPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=...;IngestionEndpoint=...\n```\n\n## Quick Start (Auto-Instrumentation)\n\n**IMPORTANT:** Call `useAzureMonitor()` BEFORE importing other modules.\n\n```typescript\nimport { useAzureMonitor } from \"@azure/monitor-opentelemetry\";\n\nuseAzureMonitor({\n  azureMonitorExporterOptions: {\n    connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING\n  }\n});\n\n// Now import your application\nimport express from \"express\";\nconst app = express();\n```\n\n## ESM Support (Node.js 18.19+)\n\n```bash\nnode --import @azure/monitor-opentelemetry/loader ./dist/index.js\n```\n\n**package.json:**\n```json\n{\n  \"scripts\": {\n    \"start\": \"node --import @azure/monitor-opentelemetry/loader ./dist/index.js\"\n  }\n}\n```\n\n## Full Configuration\n\n```typescript\nimport { useAzureMonitor, AzureMonitorOpenTelemetryOptions } from \"@azure/monitor-opentelemetry\";\nimport { resourceFromAttributes } from \"@opentelemetry/resources\";\n\nconst options: AzureMonitorOpenTelemetryOptions = {\n  azureMonitorExporterOptions: {\n    connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING,\n    storageDirectory: \"/path/to/offline/storage\",\n    disableOfflineStorage: false\n  },\n  \n  // Sampling\n  samplingRatio: 1.0,  // 0-1, percentage of traces\n  \n  // Features\n  enableLiveMetrics: true,\n  enableStandardMetrics: true,\n  enablePerformanceCounters: true,\n  \n  // Instrumentation libraries\n  instrumentationOptions: {\n    azureSdk: { enabled: true },\n    http: { enabled: true },\n    mongoDb: { enabled: true },\n    mySql: { enabled: true },\n    postgreSql: { enabled: true },\n    redis: { enabled: true },\n    bunyan: { enabled: false },\n    winston: { enabled: false }\n  },\n  \n  // Custom resource\n  resource: resourceFromAttributes({ \"service.name\": \"my-service\" })\n};\n\nuseAzureMonitor(options);\n```\n\n## Custom Traces\n\n```typescript\nimport { trace } from \"@opentelemetry/api\";\n\nconst tracer = trace.getTracer(\"my-tracer\");\n\nconst span = tracer.startSpan(\"doWork\");\ntry {\n  span.setAttribute(\"component\", \"worker\");\n  span.setAttribute(\"operation.id\", \"42\");\n  span.addEvent(\"processing started\");\n  \n  // Your work here\n  \n} catch (error) {\n  span.recordException(error as Error);\n  span.setStatus({ code: 2, message: (error as Error).message });\n} finally {\n  span.end();\n}\n```\n\n## Custom Metrics\n\n```typescript\nimport { metrics } from \"@opentelemetry/api\";\n\nconst meter = metrics.getMeter(\"my-meter\");\n\n// Counter\nconst counter = meter.createCounter(\"requests_total\");\ncounter.add(1, { route: \"/api/users\", method: \"GET\" });\n\n// Histogram\nconst histogram = meter.createHistogram(\"request_duration_ms\");\nhistogram.record(150, { route: \"/api/users\" });\n\n// Observable Gauge\nconst gauge = meter.createObservableGauge(\"active_connections\");\ngauge.addCallback((result) => {\n  result.observe(getActiveConnections(), { pool: \"main\" });\n});\n```\n\n## Manual Exporter Setup\n\n### Trace Exporter\n\n```typescript\nimport { AzureMonitorTraceExporter } from \"@azure/monitor-opentelemetry-exporter\";\nimport { NodeTracerProvider, BatchSpanProcessor } from \"@opentelemetry/sdk-trace-node\";\n\nconst exporter = new AzureMonitorTraceExporter({\n  connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING\n});\n\nconst provider = new NodeTracerProvider({\n  spanProcessors: [new BatchSpanProcessor(exporter)]\n});\n\nprovider.register();\n```\n\n### Metric Exporter\n\n```typescript\nimport { AzureMonitorMetricExporter } from \"@azure/monitor-opentelemetry-exporter\";\nimport { PeriodicExportingMetricReader, MeterProvider } from \"@opentelemetry/sdk-metrics\";\nimport { metrics } from \"@opentelemetry/api\";\n\nconst exporter = new AzureMonitorMetricExporter({\n  connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING\n});\n\nconst meterProvider = new MeterProvider({\n  readers: [new PeriodicExportingMetricReader({ exporter })]\n});\n\nmetrics.setGlobalMeterProvider(meterProvider);\n```\n\n### Log Exporter\n\n```typescript\nimport { AzureMonitorLogExporter } from \"@azure/monitor-opentelemetry-exporter\";\nimport { BatchLogRecordProcessor, LoggerProvider } from \"@opentelemetry/sdk-logs\";\nimport { logs } from \"@opentelemetry/api-logs\";\n\nconst exporter = new AzureMonitorLogExporter({\n  connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING\n});\n\nconst loggerProvider = new LoggerProvider();\nloggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(exporter));\n\nlogs.setGlobalLoggerProvider(loggerProvider);\n```\n\n## Custom Logs Ingestion\n\n```typescript\nimport { DefaultAzureCredential } from \"@azure/identity\";\nimport { LogsIngestionClient, isAggregateLogsUploadError } from \"@azure/monitor-ingestion\";\n\nconst endpoint = \"https://<dce>.ingest.monitor.azure.com\";\nconst ruleId = \"<data-collection-rule-id>\";\nconst streamName = \"Custom-MyTable_CL\";\n\nconst client = new LogsIngestionClient(endpoint, new DefaultAzureCredential());\n\nconst logs = [\n  {\n    Time: new Date().toISOString(),\n    Computer: \"Server1\",\n    Message: \"Application started\",\n    Level: \"Information\"\n  }\n];\n\ntry {\n  await client.upload(ruleId, streamName, logs);\n} catch (error) {\n  if (isAggregateLogsUploadError(error)) {\n    for (const uploadError of error.errors) {\n      console.error(\"Failed logs:\", uploadError.failedLogs);\n    }\n  }\n}\n```\n\n## Custom Span Processor\n\n```typescript\nimport { SpanProcessor, ReadableSpan } from \"@opentelemetry/sdk-trace-base\";\nimport { Span, Context, SpanKind, TraceFlags } from \"@opentelemetry/api\";\nimport { useAzureMonitor } from \"@azure/monitor-opentelemetry\";\n\nclass FilteringSpanProcessor implements SpanProcessor {\n  forceFlush(): Promise<void> { return Promise.resolve(); }\n  shutdown(): Promise<void> { return Promise.resolve(); }\n  onStart(span: Span, context: Context): void {}\n  \n  onEnd(span: ReadableSpan): void {\n    // Add custom attributes\n    span.attributes[\"CustomDimension\"] = \"value\";\n    \n    // Filter out internal spans\n    if (span.kind === SpanKind.INTERNAL) {\n      span.spanContext().traceFlags = TraceFlags.NONE;\n    }\n  }\n}\n\nuseAzureMonitor({\n  spanProcessors: [new FilteringSpanProcessor()]\n});\n```\n\n## Sampling\n\n```typescript\nimport { ApplicationInsightsSampler } from \"@azure/monitor-opentelemetry-exporter\";\nimport { NodeTracerProvider } from \"@opentelemetry/sdk-trace-node\";\n\n// Sample 75% of traces\nconst sampler = new ApplicationInsightsSampler(0.75);\n\nconst provider = new NodeTracerProvider({ sampler });\n```\n\n## Shutdown\n\n```typescript\nimport { useAzureMonitor, shutdownAzureMonitor } from \"@azure/monitor-opentelemetry\";\n\nuseAzureMonitor();\n\n// On application shutdown\nprocess.on(\"SIGTERM\", async () => {\n  await shutdownAzureMonitor();\n  process.exit(0);\n});\n```\n\n## Key Types\n\n```typescript\nimport {\n  useAzureMonitor,\n  shutdownAzureMonitor,\n  AzureMonitorOpenTelemetryOptions,\n  InstrumentationOptions\n} from \"@azure/monitor-opentelemetry\";\n\nimport {\n  AzureMonitorTraceExporter,\n  AzureMonitorMetricExporter,\n  AzureMonitorLogExporter,\n  ApplicationInsightsSampler,\n  AzureMonitorExporterOptions\n} from \"@azure/monitor-opentelemetry-exporter\";\n\nimport {\n  LogsIngestionClient,\n  isAggregateLogsUploadError\n} from \"@azure/monitor-ingestion\";\n```\n\n## Best Practices\n\n1. **Call useAzureMonitor() first** - Before importing other modules\n2. **Use ESM loader for ESM projects** - `--import @azure/monitor-opentelemetry/loader`\n3. **Enable offline storage** - For reliable telemetry in disconnected scenarios\n4. **Set sampling ratio** - For high-traffic applications\n5. **Add custom dimensions** - Use span processors for enrichment\n6. **Graceful shutdown** - Call `shutdownAzureMonitor()` to flush telemetry\n\n## When to Use\nThis skill is applicable to execute the workflow or actions described in the overview.",
  "applicable_domains": [
    "devops"
  ],
  "category": "devops",
  "invocation": [
    "/azure-monitor-opentelemetry-ts"
  ],
  "authored_by": "claudeskills.in community",
  "source_url": "https://claudeskills.in/skill/azure-monitor-opentelemetry-ts",
  "provenance": {
    "source": "claudeskills.in",
    "source_url": "https://claudeskills.in/skill/azure-monitor-opentelemetry-ts",
    "license": "unknown",
    "imported_at": "2026-09-03",
    "notes": "Aggregated by claudeskills.in from community GitHub lists."
  },
  "tags": [
    "claudeskills",
    "devops"
  ],
  "lifecycle": "draft"
}