skills/azure-monitor-opentelemetry-ts/SKILL.md
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...
npx skillsauth add benjaminastera/antigravity-awesome-skills azure-monitor-opentelemetry-tsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Auto-instrument Node.js applications with distributed tracing, metrics, and logs.
# Distro (recommended - auto-instrumentation)
npm install @azure/monitor-opentelemetry
# Low-level exporters (custom OpenTelemetry setup)
npm install @azure/monitor-opentelemetry-exporter
# Custom logs ingestion
npm install @azure/monitor-ingestion
APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=...;IngestionEndpoint=...
IMPORTANT: Call useAzureMonitor() BEFORE importing other modules.
import { useAzureMonitor } from "@azure/monitor-opentelemetry";
useAzureMonitor({
azureMonitorExporterOptions: {
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
}
});
// Now import your application
import express from "express";
const app = express();
node --import @azure/monitor-opentelemetry/loader ./dist/index.js
package.json:
{
"scripts": {
"start": "node --import @azure/monitor-opentelemetry/loader ./dist/index.js"
}
}
import { useAzureMonitor, AzureMonitorOpenTelemetryOptions } from "@azure/monitor-opentelemetry";
import { resourceFromAttributes } from "@opentelemetry/resources";
const options: AzureMonitorOpenTelemetryOptions = {
azureMonitorExporterOptions: {
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING,
storageDirectory: "/path/to/offline/storage",
disableOfflineStorage: false
},
// Sampling
samplingRatio: 1.0, // 0-1, percentage of traces
// Features
enableLiveMetrics: true,
enableStandardMetrics: true,
enablePerformanceCounters: true,
// Instrumentation libraries
instrumentationOptions: {
azureSdk: { enabled: true },
http: { enabled: true },
mongoDb: { enabled: true },
mySql: { enabled: true },
postgreSql: { enabled: true },
redis: { enabled: true },
bunyan: { enabled: false },
winston: { enabled: false }
},
// Custom resource
resource: resourceFromAttributes({ "service.name": "my-service" })
};
useAzureMonitor(options);
import { trace } from "@opentelemetry/api";
const tracer = trace.getTracer("my-tracer");
const span = tracer.startSpan("doWork");
try {
span.setAttribute("component", "worker");
span.setAttribute("operation.id", "42");
span.addEvent("processing started");
// Your work here
} catch (error) {
span.recordException(error as Error);
span.setStatus({ code: 2, message: (error as Error).message });
} finally {
span.end();
}
import { metrics } from "@opentelemetry/api";
const meter = metrics.getMeter("my-meter");
// Counter
const counter = meter.createCounter("requests_total");
counter.add(1, { route: "/api/users", method: "GET" });
// Histogram
const histogram = meter.createHistogram("request_duration_ms");
histogram.record(150, { route: "/api/users" });
// Observable Gauge
const gauge = meter.createObservableGauge("active_connections");
gauge.addCallback((result) => {
result.observe(getActiveConnections(), { pool: "main" });
});
import { AzureMonitorTraceExporter } from "@azure/monitor-opentelemetry-exporter";
import { NodeTracerProvider, BatchSpanProcessor } from "@opentelemetry/sdk-trace-node";
const exporter = new AzureMonitorTraceExporter({
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
});
const provider = new NodeTracerProvider({
spanProcessors: [new BatchSpanProcessor(exporter)]
});
provider.register();
import { AzureMonitorMetricExporter } from "@azure/monitor-opentelemetry-exporter";
import { PeriodicExportingMetricReader, MeterProvider } from "@opentelemetry/sdk-metrics";
import { metrics } from "@opentelemetry/api";
const exporter = new AzureMonitorMetricExporter({
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
});
const meterProvider = new MeterProvider({
readers: [new PeriodicExportingMetricReader({ exporter })]
});
metrics.setGlobalMeterProvider(meterProvider);
import { AzureMonitorLogExporter } from "@azure/monitor-opentelemetry-exporter";
import { BatchLogRecordProcessor, LoggerProvider } from "@opentelemetry/sdk-logs";
import { logs } from "@opentelemetry/api-logs";
const exporter = new AzureMonitorLogExporter({
connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING
});
const loggerProvider = new LoggerProvider();
loggerProvider.addLogRecordProcessor(new BatchLogRecordProcessor(exporter));
logs.setGlobalLoggerProvider(loggerProvider);
import { DefaultAzureCredential } from "@azure/identity";
import { LogsIngestionClient, isAggregateLogsUploadError } from "@azure/monitor-ingestion";
const endpoint = "https://<dce>.ingest.monitor.azure.com";
const ruleId = "<data-collection-rule-id>";
const streamName = "Custom-MyTable_CL";
const client = new LogsIngestionClient(endpoint, new DefaultAzureCredential());
const logs = [
{
Time: new Date().toISOString(),
Computer: "Server1",
Message: "Application started",
Level: "Information"
}
];
try {
await client.upload(ruleId, streamName, logs);
} catch (error) {
if (isAggregateLogsUploadError(error)) {
for (const uploadError of error.errors) {
console.error("Failed logs:", uploadError.failedLogs);
}
}
}
import { SpanProcessor, ReadableSpan } from "@opentelemetry/sdk-trace-base";
import { Span, Context, SpanKind, TraceFlags } from "@opentelemetry/api";
import { useAzureMonitor } from "@azure/monitor-opentelemetry";
class FilteringSpanProcessor implements SpanProcessor {
forceFlush(): Promise<void> { return Promise.resolve(); }
shutdown(): Promise<void> { return Promise.resolve(); }
onStart(span: Span, context: Context): void {}
onEnd(span: ReadableSpan): void {
// Add custom attributes
span.attributes["CustomDimension"] = "value";
// Filter out internal spans
if (span.kind === SpanKind.INTERNAL) {
span.spanContext().traceFlags = TraceFlags.NONE;
}
}
}
useAzureMonitor({
spanProcessors: [new FilteringSpanProcessor()]
});
import { ApplicationInsightsSampler } from "@azure/monitor-opentelemetry-exporter";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
// Sample 75% of traces
const sampler = new ApplicationInsightsSampler(0.75);
const provider = new NodeTracerProvider({ sampler });
import { useAzureMonitor, shutdownAzureMonitor } from "@azure/monitor-opentelemetry";
useAzureMonitor();
// On application shutdown
process.on("SIGTERM", async () => {
await shutdownAzureMonitor();
process.exit(0);
});
import {
useAzureMonitor,
shutdownAzureMonitor,
AzureMonitorOpenTelemetryOptions,
InstrumentationOptions
} from "@azure/monitor-opentelemetry";
import {
AzureMonitorTraceExporter,
AzureMonitorMetricExporter,
AzureMonitorLogExporter,
ApplicationInsightsSampler,
AzureMonitorExporterOptions
} from "@azure/monitor-opentelemetry-exporter";
import {
LogsIngestionClient,
isAggregateLogsUploadError
} from "@azure/monitor-ingestion";
--import @azure/monitor-opentelemetry/loadershutdownAzureMonitor() to flush telemetryThis skill is applicable to execute the workflow or actions described in the overview.
development
Multi-agent autonomous startup system for Claude Code. Triggers on "Loki Mode". Orchestrates 100+ specialized agents across engineering, QA, DevOps, security, data/ML, business operations,...
testing
Implement comprehensive evaluation strategies for LLM applications using automated metrics, human feedback, and benchmarking. Use when testing LLM performance, measuring AI application quality, or ...
development
You are an expert prompt engineer specializing in crafting effective prompts for LLMs through advanced techniques including constitutional AI, chain-of-thought reasoning, and model-specific optimizati
development
You are an expert LangChain agent developer specializing in production-grade AI systems using LangChain 0.1+ and LangGraph.