The IOTelApi interface is the main entry point for OpenTelemetry functionality in the Application Insights JavaScript SDK. It provides access to tracers, the trace API, and configuration settings. This API closely follows the OpenTelemetry specification while integrating seamlessly with Application Insights.
- Getting the OTel API
- Interface Definition
- Properties
- Creating an OTel API Instance
- Usage Examples
- Best Practices
import { ApplicationInsights } from '@microsoft/applicationinsights-web';
const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING'
}
});
appInsights.loadAppInsights();
// Get the OpenTelemetry API
const otelApi = appInsights.otelApi;Note: The otelApi and trace properties are only available on the AISKU (appInsights) instance, not on AppInsightsCore.
export interface IOTelApi extends IOTelTracerProvider {
/**
* The configuration object that contains all OpenTelemetry-specific settings.
*/
cfg: IOTelConfig;
/**
* The current ITraceHost instance for this IOTelApi instance.
*/
host: ITraceHost;
/**
* The current ITraceApi instance for this IOTelApi instance.
*/
trace: ITraceApi;
}Extended from IOTelTracerProvider
Since IOTelApi extends IOTelTracerProvider, it also provides:
/**
* Get a tracer for a specific instrumentation scope
* @param name - The name of the tracer/instrumentation library
* @param version - Optional version of the instrumentation library
* @param options - Optional tracer configuration options
* @returns A tracer instance
*/
getTracer(name: string, version?: string, options?: IOTelTracerOptions): IOTelTracer;The configuration object containing all OpenTelemetry-specific settings.
Type: IOTelConfig
Description: Provides access to tracing configuration, error handlers, and other OpenTelemetry options. Changes to this configuration after initialization may not take effect until the next telemetry operation.
Example:
const otelApi = appInsights.otelApi;
// Access trace configuration
if (otelApi.cfg.traceCfg) {
console.log('Tracing enabled:', !otelApi.cfg.traceCfg.suppressTracing);
}
// Check for error handlers
if (otelApi.cfg.errorHandlers) {
console.log('Custom error handlers configured');
}The trace host instance that manages span lifecycle and active span context.
Type: ITraceHost
Description: This is effectively the OpenTelemetry ContextAPI without the static methods. It provides methods for managing the active span context and creating spans.
Key Methods:
startSpan(name, options?, context?)- Create a new spangetActiveSpan()- Get the current active spansetActiveSpan(span)- Set a span as the active spangetTraceCtx()- Get the current trace context
setActiveSpan requires a non-null span (IReadableSpan); clearing the active span by passing null is not supported.
Example:
const otelApi = appInsights.otelApi;
// Get the current active span
const activeSpan = otelApi.host.getActiveSpan();
if (activeSpan) {
console.log('Active span:', activeSpan.name);
console.log('Trace ID:', activeSpan.spanContext().traceId);
}
// Create a span directly via host
const span = otelApi.host.startSpan('operation-name', {
kind: OTelSpanKind.INTERNAL,
attributes: { 'custom.attribute': 'value' }
});The trace API providing utilities for tracer and span management.
Type: ITraceApi
Description: Provides the OpenTelemetry TraceAPI interface without static methods. This is the recommended way to get tracers and manage span contexts.
Key Methods:
getTracer(name, version?, options?)- Get or create a tracergetActiveSpan()- Get the current active spansetActiveSpan(span)- Set the active spanwrapSpanContext(spanContext)- Create a non-recording span from contextisSpanContextValid(spanContext)- Validate a span context
Example:
const otelApi = appInsights.otelApi;
// Get a tracer via trace API
const tracer = otelApi.trace.getTracer('my-service');
// Check for active span
const activeSpan = otelApi.trace.getActiveSpan();
if (activeSpan) {
console.log('Current operation:', activeSpan.name);
}
// Validate a span context
const isValid = otelApi.trace.isSpanContextValid(spanContext);Typically, you don't create IOTelApi instances directly. They are created and managed by the Application Insights core. However, for advanced scenarios, you can use the createOTelApi function:
function createOTelApi(otelApiCtx: IOTelApiCtx): IOTelApi;Parameters:
otelApiCtx: IOTelApiCtx- The context containing the host instance
Returns: A new IOTelApi instance
Example:
import { createOTelApi } from '@microsoft/applicationinsights-core-js';
// Advanced: Create a custom OTel API instance
const otelApiCtx = {
host: appInsightsCore
};
const customOtelApi = createOTelApi(otelApiCtx);export interface IOTelApiCtx {
/**
* The host instance (AppInsightsCore) that provides tracing capabilities
*/
host: ITraceHost;
}import { ApplicationInsights } from '@microsoft/applicationinsights-web';
const appInsights = new ApplicationInsights({
config: {
connectionString: 'YOUR_CONNECTION_STRING',
traceCfg: {
suppressTracing: false
}
}
});
appInsights.loadAppInsights();
// Get the OTel API
const otelApi = appInsights.otelApi;
// Access different parts of the API
console.log('Has trace API:', !!otelApi.trace);
console.log('Has host:', !!otelApi.host);
console.log('Configuration available:', !!otelApi.cfg);const otelApi = appInsights.otelApi;
// Get a tracer directly from the API
const tracer1 = otelApi.getTracer('service-a');
// Or get it via the trace property (recommended)
const tracer2 = otelApi.trace.getTracer('service-b');
// Both approaches work and return cached instances
const tracer3 = otelApi.trace.getTracer('service-a');
console.log(tracer1 === tracer3); // true - same cached instanceconst otelApi = appInsights.otelApi;
const tracer = otelApi.trace.getTracer('my-app');
// Create and set an active span
const span = tracer.startSpan('operation');
otelApi.trace.setActiveSpan(span);
// Later, get the active span
const activeSpan = otelApi.trace.getActiveSpan();
if (activeSpan) {
activeSpan.setAttribute('additional.info', 'added later');
}
// Clear the active span
otelApi.trace.setActiveSpan(null);
span.end();const otelApi = appInsights.otelApi;
// Check if a span context is valid
const spanContext = {
traceId: '00000000000000000000000000000001',
spanId: '0000000000000001',
traceFlags: 1
};
if (otelApi.trace.isSpanContextValid(spanContext)) {
// Wrap the context in a non-recording span
const wrappedSpan = otelApi.trace.wrapSpanContext(spanContext);
// Use the wrapped span (e.g., for context propagation)
otelApi.trace.setActiveSpan(wrappedSpan);
// ... perform operations that should have this context
otelApi.trace.setActiveSpan(null);
}const otelApi = appInsights.otelApi;
// Define different tracers for different parts of your application
const tracers = {
userService: otelApi.trace.getTracer('user-service'),
paymentService: otelApi.trace.getTracer('payment-service'),
notificationService: otelApi.trace.getTracer('notification-service')
};
// Use the appropriate tracer for each operation
function authenticateUser(userId: string) {
const span = tracers.userService.startSpan('authenticate');
span.setAttribute('user.id', userId);
// ... authentication logic
span.end();
}
function processPayment(amount: number) {
const span = tracers.paymentService.startSpan('process-payment');
span.setAttribute('payment.amount', amount);
// ... payment logic
span.end();
}
function sendNotification(type: string) {
const span = tracers.notificationService.startSpan('send-notification');
span.setAttribute('notification.type', type);
// ... notification logic
span.end();
}const otelApi = appInsights.otelApi;
// Check if tracing is enabled
function isTracingEnabled(): boolean {
return otelApi.cfg?.traceCfg?.suppressTracing !== true;
}
// Conditionally create spans based on configuration
function createSpanIfEnabled(name: string): IReadableSpan | null {
if (!isTracingEnabled()) {
return null;
}
const tracer = otelApi.trace.getTracer('my-service');
return tracer.startSpan(name);
}
// Use the conditional span creation
const span = createSpanIfEnabled('optional-trace');
if (span) {
span.setAttribute('traced', true);
// ... do work
span.end();
}const otelApi = appInsights.otelApi;
// Use host methods directly for lower-level control
const span = otelApi.host.startSpan('low-level-operation', {
kind: OTelSpanKind.INTERNAL,
attributes: {
'operation.type': 'direct-host-call'
}
});
// Set it as active using the host
const scope = otelApi.host.setActiveSpan(span);
try {
// Perform work with span active
console.log('Current trace context:', otelApi.host.getTraceCtx());
// Create child span (automatically uses active span as parent)
const childSpan = otelApi.host.startSpan('child-operation');
childSpan?.end();
} finally {
// Restore previous context
scope?.restore();
span.end();
}Recommended approach:
// Direct startSpan from AISKU - simplest for most use cases
appInsights.startSpan('operation-name', (span) => {
span.setAttribute('key', 'value');
// operation code
});Use getTracer for service organization:
// Only needed when organizing multiple services/components
const tracer = otelApi.trace.getTracer('my-service');
tracer.startActiveSpan('operation', (span) => {
// ...
});Recommended:
const tracer = otelApi.trace.getTracer('my-service');Also Valid:
const tracer = otelApi.getTracer('my-service');Both work, but using otelApi.trace.getTracer() is more explicit and follows OpenTelemetry conventions.
// Good - cache the reference
const otelApi = appInsights.otelApi;
const tracer = otelApi.trace.getTracer('my-service');
// Less efficient - repeated property access
appInsights.otelApi.trace.getTracer('my-service');While rare, always check for null when working with spans:
const span = tracer.startSpan('operation');
if (span) {
// Safe to use span
span.setAttribute('key', 'value');
span.end();
}// Good - clear organization
class UserService {
private tracer = otelApi.trace.getTracer('user-service');
authenticate(userId: string) {
const span = this.tracer.startSpan('authenticate');
// ...
}
}
class PaymentService {
private tracer = otelApi.trace.getTracer('payment-service');
processPayment(amount: number) {
const span = this.tracer.startSpan('process-payment');
// ...
}
}// Safe configuration access with fallbacks
function getTraceCfg(otelApi: IOTelApi): ITraceCfg | null {
return otelApi?.cfg?.traceCfg || null;
}
// Check before using
const traceCfg = getTraceCfg(otelApi);
if (traceCfg && !traceCfg.suppressTracing) {
// Create spans
}Recommended:
const activeSpan = otelApi.trace.getActiveSpan();
otelApi.trace.setActiveSpan(span);Direct (lower level):
const activeSpan = otelApi.host.getActiveSpan();
otelApi.host.setActiveSpan(span);The trace API methods provide better abstraction and follow OpenTelemetry conventions.
- Trace API Documentation - Detailed tracer and span management
- withSpan Helper - Executing code with active span context
- useSpan Helper - Executing code with span scope parameter
- Examples Guide - Comprehensive usage examples
- Main README - OpenTelemetry compatibility overview
IOTelConfig- OpenTelemetry configuration settingsITraceHost- Host interface for span managementITraceApi- Trace API interfaceIOTelTracer- Tracer interface for creating spansIOTelTracerProvider- Provider interface for getting tracersIOTelTracerOptions- Options for tracer creation