@microsoft/opentelemetry
    Preparing search index...

    @microsoft/opentelemetry

    @microsoft/opentelemetry

    npm version license API Docs

    Microsoft OpenTelemetry distribution for Node.js — one import, one call, full observability across Azure Monitor, OTLP-compatible backends, and A365.

    npm install @microsoft/opentelemetry
    

    Important: Import and call useMicrosoftOpenTelemetry() as early as possible in your application entry point so instrumentations can patch libraries before they are loaded.

    Note: This package requires Node.js 22.0.0 or later. Its ESM loader flow relies on --import and node:module.register(). For background on why startup ordering matters, see the OpenTelemetry ESM Support documentation.

    For ESM applications, instrumentation hooks must be registered before any instrumented modules (for example http, express, axios, or loggers) are loaded. This is a fundamental ESM constraint: modules cannot be instrumented after they are already loaded.

    This pattern is not reliable for auto-instrumentation:

    import { useMicrosoftOpenTelemetry } from "@microsoft/opentelemetry";
    useMicrosoftOpenTelemetry();

    import express from "express";

    Use --import so the loader is registered at process startup.

    node --import @microsoft/opentelemetry/loader ./app.mjs
    

    For example, in package.json:

    {
    "scripts": {
    "start": "node --import @microsoft/opentelemetry/loader ./dist/index.js"
    }
    }

    If you prefer explicit telemetry configuration in a bootstrap file, preload that file instead:

    telemetry.mjs:

    import "@microsoft/opentelemetry/loader";
    import { useMicrosoftOpenTelemetry } from "@microsoft/opentelemetry";

    useMicrosoftOpenTelemetry({
    azureMonitor: {
    azureMonitorExporterOptions: {
    connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING,
    },
    enableLiveMetrics: false,
    },
    instrumentationOptions: {
    bunyan: { enabled: true },
    winston: { enabled: true },
    },
    });

    Start your app:

    node --import ./telemetry.mjs ./app.mjs
    

    Your application code can keep regular static ESM imports in app.mjs.

    import { useMicrosoftOpenTelemetry } from "@microsoft/opentelemetry";

    useMicrosoftOpenTelemetry({
    a365: {
    enabled: true,
    tokenResolver: (agentId, tenantId) => getToken(agentId, tenantId),
    },
    });

    When you enable the A365 HTTP exporter, durable delivery is enabled by default. Tune the durable store if you need a protected persistent volume or different bounds:

    useMicrosoftOpenTelemetry({
    a365: {
    enabled: true,
    enableObservabilityExporter: true,
    tokenResolver: (agentId, tenantId, authScopes) => getToken(agentId, tenantId, authScopes),
    durableDelivery: {
    storageDirectory: process.env.A365_DURABLE_STORAGE_DIRECTORY,
    maxStorageBytes: 50 * 1024 * 1024,
    maxRecordAgeMilliseconds: 2 * 24 * 60 * 60 * 1000,
    },
    },
    });

    Set durableDelivery.enabled: false to force legacy network-only delivery.

    With durable delivery enabled, retryable A365 exporter payloads (including HTTP 401, 408, 429, and 5xx responses) are stored as plaintext local files in a stable per-application partition and replayed with a freshly resolved token plus the exporter's current cluster/domain routing; durable files never store bearer tokens or authoritative route metadata. Delivery is at-least-once, so duplicates are possible. The SDK restricts durable storage to the current user and Administrators on Windows and uses owner-only 0700 directories and 0600 files on POSIX. Use a protected persistent volume if records must survive container or host restarts; ephemeral container storage only survives process restarts and still counts against the container's ephemeral-storage quota. If durable storage permissions cannot be secured, the exporter logs the initialization failure and degrades to network-only delivery; successful and non-retryable live sends still complete, but retryable results that cannot be persisted fail.

    For A365 scenarios, scope APIs, baggage, hosting middleware, and official terminology alignment, see A365_DOCUMENTATION.md.

    import { useMicrosoftOpenTelemetry } from "@microsoft/opentelemetry";

    useMicrosoftOpenTelemetry({
    azureMonitor: {
    azureMonitorExporterOptions: {
    connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING,
    },
    },
    });
    import { useMicrosoftOpenTelemetry } from "@microsoft/opentelemetry";

    // Set OTEL_EXPORTER_OTLP_ENDPOINT in your environment
    useMicrosoftOpenTelemetry();

    That's it — traces, metrics, and logs are collected automatically with built-in instrumentations for HTTP, databases, and more.

    Option Type Default Description
    resource Resource auto-detected OpenTelemetry Resource (service name, version, etc.)
    samplingRatio number 1.0 Ratio of telemetry items to transmit (0.0–1.0)
    tracesPerSecond number 5 Max traces per second. Set to 0 to use samplingRatio instead
    instrumentationOptions InstrumentationOptions all enabled Toggle built-in instrumentations (see below)
    spanProcessors SpanProcessor[] — Additional span processors
    logRecordProcessors LogRecordProcessor[] — Additional log record processors
    metricReaders MetricReader[] — Additional metric readers
    views ViewOptions[] — Metric views
    azureMonitor AzureMonitorOpenTelemetryOptions — Azure Monitor backend config. When provided, Azure Monitor export is enabled
    a365 A365Options — A365 observability config
    enableConsoleExporters boolean auto Enable console exporters for traces, metrics, and logs
    enableSensitiveData boolean false Capture GenAI message content (prompts, completions, tool args/results, system instructions) on LangChain spans. Only enable in trusted, non-production environments

    Most instrumentations use InstrumentationConfig shape ({ enabled?: boolean, ... }).

    • Built-in infra instrumentations (http, azureSdk, mongoDb, mySql, postgreSql, redis, redis4) are enabled by default.
    • Logging instrumentations (bunyan, winston, console) are disabled by default.
    • GenAI instrumentations (openaiAgents, langchain) are enabled by default.
    • When a365.enabled is true, non-GenAI instrumentations (http, azureSdk, DB/cache, and logging) are disabled by default unless explicitly set in instrumentationOptions.

    Set enabled: true or enabled: false explicitly for predictable behavior.

    Key Type Default Description
    http InstrumentationConfig enabled HTTP client/server instrumentation
    azureSdk InstrumentationConfig enabled Azure SDK instrumentation
    mongoDb InstrumentationConfig enabled MongoDB instrumentation
    mySql InstrumentationConfig enabled MySQL instrumentation
    postgreSql InstrumentationConfig enabled PostgreSQL instrumentation
    redis InstrumentationConfig enabled Redis instrumentation
    redis4 InstrumentationConfig enabled Redis 4 instrumentation
    bunyan InstrumentationConfig disabled Bunyan log instrumentation
    winston InstrumentationConfig disabled Winston log instrumentation
    console InstrumentationConfig disabled Console log instrumentation
    openaiAgents OpenAIAgentsInstrumentationConfig enabled OpenAI Agents SDK instrumentation (requires @openai/agents)
    langchain LangChainInstrumentationConfig enabled LangChain instrumentation (requires @langchain/core)
    useMicrosoftOpenTelemetry({
    // Capture GenAI message content on LangChain spans (hidden by default).
    // Only enable in trusted, non-production environments.
    enableSensitiveData: true,
    instrumentationOptions: {
    // Disable specific built-in instrumentations
    http: { enabled: false },
    redis: { enabled: false },

    // Enable GenAI instrumentations
    openaiAgents: {
    enabled: true,
    isContentRecordingEnabled: true,
    },
    langchain: {
    enabled: true,
    },
    },
    });

    Capturing GenAI message content (enableSensitiveData)

    LangChain instrumentation hides sensitive message content, prompts, completions, tool arguments/results, and system instructions, by default. Set the top-level enableSensitiveData: true to record it. Only enable content capture in trusted, non-production environments where capturing message content is intentional.

    Disable most built-in auto-instrumentation:

    useMicrosoftOpenTelemetry({
    instrumentationOptions: {
    http: { enabled: false },
    azureSdk: { enabled: false },
    azureFunctions: { enabled: false },
    mongoDb: { enabled: false },
    mySql: { enabled: false },
    postgreSql: { enabled: false },
    redis: { enabled: false },
    redis4: { enabled: false },
    bunyan: { enabled: false },
    winston: { enabled: false },
    openaiAgents: { enabled: false },
    langchain: { enabled: false },
    },
    });

    Use console exporters when validating local telemetry or debugging setup.

    useMicrosoftOpenTelemetry({
    enableConsoleExporters: true,
    });

    Behavior:

    • enableConsoleExporters: true: always enable console exporters (traces, metrics, logs).
    • enableConsoleExporters: false: do not auto-add the standard console exporters.
    • Omitted: console exporters auto-enable only when no other exporter path is active.
    Option Type Default Description
    azureMonitorExporterOptions AzureMonitorExporterOptions — Exporter config including connectionString, storageDirectory, disableOfflineStorage
    enableLiveMetrics boolean true Enable Live Metrics streaming
    enableStandardMetrics boolean true Enable standard metrics collection
    enableTraceBasedSamplingForLogs boolean false Enable log sampling based on trace
    enablePerformanceCounters boolean true Enable performance counter collection
    browserSdkLoaderOptions BrowserSdkLoaderOptions disabled Application Insights browser SDK loader config (enabled, connectionString)

    Set OTEL_EXPORTER_OTLP_ENDPOINT and OTLP export is enabled automatically — no code changes needed. Signal-specific variables (OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, etc.) override the base endpoint.

    See the OpenTelemetry OTLP Exporter specification for the full list.

    Option Type Default Description
    enabled boolean false Enable A365 observability. Registers the A365SpanProcessor for baggage/attribute enrichment of downstream exporters (Azure Monitor, OTLP, console). Does not send data to the A365 service on its own — set enableObservabilityExporter for that
    enableObservabilityExporter boolean false Enable the A365 HTTP exporter (Agent365Exporter) to send spans to the A365 observability service. Requires enabled: true. Equivalent to ENABLE_A365_OBSERVABILITY_EXPORTER env var
    tokenResolver (agentId, tenantId, authScopes?) => string | Promise<string> — Token resolver for A365 service authentication. When both this and contextualTokenResolver are set, contextualTokenResolver takes precedence
    contextualTokenResolver (context: TokenResolverContext) => string | null | Promise<string | null> — Contextual token resolver with rich context including the agentic user ID. Takes precedence over tokenResolver when set
    clusterCategory ClusterCategory "prod" Cluster category for endpoint resolution (local, dev, test, preprod, firstrelease, prod, gov, high, dod, mooncake, ex, rx)
    domainOverride string — Override the A365 observability service domain
    authScopes string[] ["api://9b975845-388f-4429-889e-eab1ef63949c/.default"] OAuth scopes for A365 service authentication
    observabilityScopeOverride string — Single-string scope override (highest precedence). Equivalent to A365_OBSERVABILITY_SCOPES_OVERRIDE env var
    logLevel string "none" A365 internal log level: none, info, warn, error, or pipe-separated combination. Overrides A365_OBSERVABILITY_LOG_LEVEL env var
    useS2SEndpoint boolean false Use the S2S (service-to-service) endpoint path for export
    durableDelivery Agent365DurableDeliveryOptions enabled with defaults Enabled-by-default local store-and-replay for retryable A365 HTTP export requests when the A365 HTTP exporter is active. Set durableDelivery.enabled: false to force network-only delivery. Replays use fresh tokens/current routing, records stay in bounded plaintext local storage, and storage-init failures degrade to network-only delivery

    When A365 export is enabled, Microsoft OpenTelemetry defaults to GenAI-focused telemetry. To opt back into non-GenAI auto-instrumentation, set explicit overrides:

    useMicrosoftOpenTelemetry({
    a365: {
    enabled: true,
    tokenResolver: (agentId, tenantId) => getToken(agentId, tenantId),
    },
    instrumentationOptions: {
    http: { enabled: true },
    azureSdk: { enabled: true },
    mongoDb: { enabled: true },
    mySql: { enabled: true },
    postgreSql: { enabled: true },
    redis: { enabled: true },
    redis4: { enabled: true },
    bunyan: { enabled: true },
    winston: { enabled: true },
    },
    });

    Hosting middleware is configured separately from a365 exporter options. To use A365 hosting middleware, attach it to your adapter explicitly.

    Use the one-liner helper:

    import { configureA365Hosting } from "@microsoft/opentelemetry";

    configureA365Hosting(adapter);

    By default this registers both BaggageMiddleware and OutputLoggingMiddleware.

    OutputLoggingMiddleware captures outgoing message content as span attributes. If your responses may contain sensitive content, disable output logging:

    configureA365Hosting(adapter, {
    enableBaggage: true,
    enableOutputLogging: false,
    });

    If you need explicit flags:

    configureA365Hosting(adapter, {
    enableBaggage: true,
    enableOutputLogging: true,
    });

    For previously published package versions that do not include configureA365Hosting, use:

    import { ObservabilityHostingManager } from "@microsoft/opentelemetry";

    new ObservabilityHostingManager().configure(adapter as unknown as { use(...m: unknown[]): void }, {
    enableBaggage: true,
    enableOutputLogging: true,
    });
    Option Type Default Description
    maxQueueSize number 2048 Maximum span queue size before drops occur
    scheduledDelayMilliseconds number 5000 Delay (ms) between automatic batch flush attempts
    exporterTimeoutMilliseconds number 90000 Maximum time (ms) for the entire export call
    httpRequestTimeoutMilliseconds number 30000 HTTP request timeout (ms) when sending spans to A365 service
    maxExportBatchSize number 512 Maximum number of spans per export batch
    maxPayloadBytes number 900 * 1024 Maximum estimated payload size (bytes) per HTTP chunk

    Durable delivery applies only to the A365 HTTP exporter, so set both a365.enabled: true and a365.enableObservabilityExporter: true when you use it. Durable delivery is enabled by default; set durableDelivery.enabled: false to force legacy network-only delivery.

    Option Type Default Description
    enabled boolean true Durable delivery stays on unless you explicitly disable it
    storageDirectory string auto Root directory for durable records. When omitted, the SDK probes LOCALAPPDATA, then TEMP, then os.tmpdir() on Windows and appends Microsoft/A365/otel-durable; on POSIX it probes TMPDIR, then /var/tmp, then /tmp and uses the single a365-otel-durable-<uid> leaf. Every base root then gets a stable per-application app-<hash> child
    maxStorageBytes number 50 * 1024 * 1024 Maximum total bytes retained for pending and quarantined durable records
    maxRecordAgeMilliseconds number 2 * 24 * 60 * 60 * 1000 Maximum record age before expiry pruning
    replayIntervalMilliseconds number 2 * 60 * 1000 Delay between scheduled replay passes
    maxReplayBatchSize number 10 Maximum records claimed per replay pass
    leaseDurationMilliseconds number 2 * 60 * 1000 How long a claimed replay lease stays active before recovery
    shutdownTimeoutMilliseconds number 10_000 Shared graceful-shutdown budget for accepted live exports and admitted durable handoff completion
    tokenResolutionTimeoutMilliseconds number 30_000 Timeout for each replay token-resolution attempt

    Operational notes:

    • Durable records are stored as plaintext JSON files. On POSIX, the SDK creates owner-only durable directories/files (0700 / 0600). On Windows, the SDK removes inherited ACLs and grants full control only to the current Windows identity and built-in Administrators. ACL hardening failures cause durable storage initialization to fail and the exporter to use network-only delivery.
    • Durable delivery is enabled by default when the A365 HTTP exporter is active. Set durableDelivery.enabled: false to force legacy network-only delivery.
    • Durable delivery is at-least-once. If a retryable request succeeds immediately before a crash or after replay, duplicates are possible and receivers must be idempotent.
    • Every replay attempt and forceFlush() pass resolves a fresh token and uses the exporter's current cluster/domain routing; durable files do not store bearer tokens or authoritative route metadata.
    • If durable storage cannot initialize, the exporter logs the error and continues in network-only mode. Successful and non-retryable live sends still complete, but retryable results that cannot be persisted are reported as failures.
    • If token resolution returns no token, throws, or times out, live delivery attempts to persist the record for replay and replay releases the claim without extending the shared transmission backoff.
    • Storage is bounded by both maxStorageBytes and maxRecordAgeMilliseconds; expired records are pruned first, then the oldest retained records are evicted until the new record fits.
    • Live delivery and replay share the same Retry-After / exponential-backoff transmission gate, so a retryable response (401, 408, 429, or 5xx) pauses both immediate sends and replay probes until the gate reopens.
    • If you run in containers and need records to survive container restarts, rescheduling, or host restarts outside the current container filesystem, set storageDirectory to a protected persistent volume and size maxStorageBytes within your platform's storage quota.
    • During shutdownMicrosoftOpenTelemetry(), the exporter first waits up to shutdownTimeoutMilliseconds for already accepted live exports to settle. When durable delivery is enabled, it also stops replay scheduling immediately, aborts in-flight durable HTTP, and uses the same deadline for already admitted durable handoff completion. Retryable aborted payloads stay on disk for replay on the next process or startup pass; shutdown does not drain the existing spool. If you use Agent365Exporter directly, you may call forceFlush() before shutdown for one bounded replay pass. The distro shutdown path does not call exporter.forceFlush(). When durable delivery is disabled—or durable storage never initialized and the exporter stayed network-only—shutdown still drains accepted live exports but does not replay or persist anything.

    Example:

    useMicrosoftOpenTelemetry({
    a365: {
    enabled: true,
    enableObservabilityExporter: true,
    tokenResolver: (agentId, tenantId, authScopes) => getToken(agentId, tenantId, authScopes),
    maxQueueSize: 4096,
    maxExportBatchSize: 1024,
    scheduledDelayMilliseconds: 10000,
    httpRequestTimeoutMilliseconds: 15000,
    durableDelivery: {
    storageDirectory: process.env.A365_DURABLE_STORAGE_DIRECTORY,
    maxStorageBytes: 50 * 1024 * 1024,
    maxRecordAgeMilliseconds: 2 * 24 * 60 * 60 * 1000,
    },
    },
    });

    A365 also reads the following environment overrides:

    Environment Variable Description
    ENABLE_A365_OBSERVABILITY_EXPORTER "true" / "false" — secondary toggle for the A365 HTTP exporter when a365 options are provided in code; it does not enable a365.enabled on its own
    A365_OBSERVABILITY_SCOPES_OVERRIDE Space-separated list of OAuth scopes
    A365_OBSERVABILITY_DOMAIN_OVERRIDE Override service domain
    CLUSTER_CATEGORY Override cluster category
    A365_OBSERVABILITY_LOG_LEVEL A365 internal logger filter level (none, info, warn, error, or pipe-delimited combination) — overrides observabilityLogLevel
    A365_PER_REQUEST_MAX_TRACES Max buffered traces (default: 1000)
    A365_PER_REQUEST_MAX_SPANS_PER_TRACE Max spans per trace (default: 5000)
    A365_PER_REQUEST_MAX_CONCURRENT_EXPORTS Max concurrent exports (default: 20)
    A365_PER_REQUEST_FLUSH_GRACE_MS Grace period after root span ends (default: 250)
    A365_PER_REQUEST_MAX_TRACE_AGE_MS Max trace age before forced flush (default: 1800000)
    A365_OBSERVABILITY_TOKEN_EXCHANGE_TIMEOUT_MS Per-attempt timeout (ms) for agentic token exchange; 0 or negative disables (default: 30000)
    import {
    useMicrosoftOpenTelemetry,
    shutdownMicrosoftOpenTelemetry,
    } from "@microsoft/opentelemetry";
    import { resourceFromAttributes } from "@opentelemetry/resources";

    useMicrosoftOpenTelemetry({
    resource: resourceFromAttributes({ "service.name": "my-app" }),
    samplingRatio: 0.5,
    azureMonitor: {
    azureMonitorExporterOptions: {
    connectionString: process.env.APPLICATIONINSIGHTS_CONNECTION_STRING,
    },
    },
    });

    // On shutdown
    await shutdownMicrosoftOpenTelemetry();
    • Fabric Getting Started — Send telemetry to Microsoft Fabric / Azure Data Explorer via OTLP + OTel Collector

    See the samples/ directory for working TypeScript examples covering connection setup, custom metrics, custom traces, sampling, OTLP dual-export, and more.

    See CONTRIBUTING.md.

    This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact opencode@microsoft.com with any additional questions or comments.

    As this SDK is designed to enable applications to perform data collection which is sent to the Microsoft collection endpoints the following is required to identify our privacy statement.

    The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft’s privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.

    Internal telemetry can be disabled by setting the environment variable APPLICATIONINSIGHTS_STATSBEAT_DISABLED to true.

    This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies.

    See SECURITY.md for information on reporting vulnerabilities.

    MIT