Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions .aiAutoMinify.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"ePendingOp",
"CallbackType",
"eTraceStateKeyType",
"eDependencyTypes",
"eEventsDiscardedReason",
"eBatchDiscardedReason",
"FeatureOptInMode",
Expand All @@ -19,7 +20,14 @@
"TelemetryUnloadReason",
"TelemetryUpdateReason",
"eTraceHeadersMode",
"eW3CTraceFlags"
"eW3CTraceFlags",
"eAttributeSource",
"AddAttributeResult",
"eAttributeFilter",
"eAttributeChangeOp",
"eOTelSamplingDecision",
"eOTelSpanKind",
"eOTelSpanStatusCode"
]
},
"@microsoft/applicationinsights-perfmarkmeasure-js": {
Expand Down Expand Up @@ -50,7 +58,9 @@
"constEnums": []
},
"@microsoft/applicationinsights-channel-js": {
"constEnums": []
"constEnums": [
"eSerializeType"
]
},
"@microsoft/applicationinsights-react-native": {
"constEnums": []
Expand All @@ -64,10 +74,14 @@
"constEnums": []
},
"@microsoft/applicationinsights-analytics-js": {
"constEnums": []
"constEnums": [
"eRouteTraceStrategy"
]
},
"@microsoft/applicationinsights-web": {
"constEnums": []
"constEnums": [
"eMaxPropertyLengths"
]
},
"@microsoft/applicationinsights-react-js": {
"constEnums": []
Expand All @@ -91,7 +105,8 @@
"_eExtendedInternalMessageId",
"GuidStyle",
"FieldValueSanitizerType",
"TransportType"
"TransportType",
"eMaxPropertyLengths"
]
},
"@microsoft/1ds-post-js": {
Expand Down
136 changes: 136 additions & 0 deletions AISKU/OpenTelemetry_Trace_API_Implementation_Summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# OpenTelemetry Trace API Implementation Summary

## ✅ Completed Implementation

I have successfully added an OpenTelemetry-compatible "trace" property to the AISku instance that implements the standard OpenTelemetry trace API.

## New Files Created

### 1. `AISKU/src/OpenTelemetry/trace/ITrace.ts`
- **ITracer Interface**: Standard OpenTelemetry tracer interface with `startSpan()` method
- **ITrace Interface**: Standard OpenTelemetry trace interface with `getTracer()` method

### 2. `AISKU/src/OpenTelemetry/trace/trace.ts`
- **ApplicationInsightsTracer Class**: Implements ITracer, delegates to ApplicationInsights core
- **ApplicationInsightsTrace Class**: Implements ITrace, manages tracer instances with caching

## Modified Files

### 1. `AISKU/src/AISku.ts`
- **Added trace property declaration** to the AppInsightsSku class
- **Added trace property implementation** using `objDefine()` in the dynamic proto section
- **Added imports** for trace-related classes

### 2. `AISKU/src/IApplicationInsights.ts`
- **Added trace property** to the IApplicationInsights interface
- **Added import** for ApplicationInsightsTrace type

### 3. `AISKU/src/applicationinsights-web.ts`
- **Exported trace interfaces** (ITrace, ITracer) for public API
- **Exported implementation classes** (ApplicationInsightsTrace, ApplicationInsightsTracer)

### 4. `examples/dependency/src/appinsights-init.ts`
- **Added example functions** demonstrating the new trace API usage
- **Updated imports** to include trace interfaces

## API Usage Examples

### Basic Usage
```typescript
// Get the OpenTelemetry trace API
const trace = appInsights.trace;

// Get a tracer instance
const tracer = trace.getTracer("my-service", "1.0.0");

// Create a span
const span = tracer.startSpan("operation-name", {
kind: SpanKind.SERVER,
attributes: {
"component": "user-service",
"operation": "checkout"
}
});

// Set additional attributes
span.setAttribute("user.id", "12345");
span.setAttributes({
"request.size": 1024,
"response.status": 200
});

// End the span (automatically creates telemetry)
span.end();
```

### Multiple Tracers
```typescript
const trace = appInsights.trace;

// Get different tracers for different components
const userServiceTracer = trace.getTracer("user-service", "1.2.3");
const paymentTracer = trace.getTracer("payment-service", "2.1.0");

// Create spans from different tracers
const userSpan = userServiceTracer.startSpan("validate-user");
const paymentSpan = paymentTracer.startSpan("process-payment");
```

## Technical Implementation Details

### Tracer Caching
- **Smart Caching**: Tracers are cached by name@version combination
- **Memory Efficient**: Reuses tracer instances for same name/version
- **Multiple Services**: Supports different tracers for different components

### Span Integration
- **Automatic Telemetry**: Spans automatically create trace telemetry when ended
- **Span Context**: Full span context (trace ID, span ID) included in telemetry
- **Attributes**: All span attributes included as custom properties
- **Timing**: Start time, end time, and duration automatically calculated

### Delegation to Core
- **Seamless Integration**: Trace API delegates to existing `core.startSpan()` method
- **Consistent Behavior**: Same span implementation as direct core usage
- **Compatibility**: Works with existing trace provider setup

## Benefits

1. **Standard API**: Provides OpenTelemetry-compatible trace API
2. **Developer Experience**: Familiar interface for OpenTelemetry users
3. **Service Identification**: Different tracers for different services/components
4. **Automatic Telemetry**: Spans automatically generate ApplicationInsights telemetry
5. **Backward Compatible**: Existing `core.startSpan()` usage still works
6. **Type Safety**: Full TypeScript support with proper interfaces

## Usage Pattern Comparison

### Before (Direct Core Access)
```typescript
const span = appInsights.core.startSpan("operation", options);
```

### After (OpenTelemetry API)
```typescript
const tracer = appInsights.trace.getTracer("service-name", "1.0.0");
const span = tracer.startSpan("operation", options);
```

Both approaches work and create the same telemetry, but the trace API provides better organization and follows OpenTelemetry standards.

## Files Structure
```
AISKU/src/
├── OpenTelemetry/trace/
│ ├── ITrace.ts # OpenTelemetry trace interfaces
│ ├── trace.ts # Implementation classes
│ ├── AppInsightsTraceProvider.ts # Factory function (existing)
│ └── span.ts # Inline span implementation (existing)
├── AISku.ts # Added trace property
├── IApplicationInsights.ts # Added trace property to interface
└── applicationinsights-web.ts # Exported trace APIs
```

## ✅ Status: COMPLETE

The OpenTelemetry trace API has been successfully implemented and integrated into the ApplicationInsights JavaScript SDK. Users can now access the standard OpenTelemetry trace API through `appInsights.trace` and create spans using the familiar `getTracer().startSpan()` pattern.
156 changes: 156 additions & 0 deletions AISKU/SpanImplementation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# OpenTelemetry-like Span Implementation

## Overview

ApplicationInsights now includes an OpenTelemetry-like span implementation that uses a provider pattern. This allows different SKUs to provide their own span implementations while the core SDK manages the lifecycle.

## Architecture

### Provider Pattern

The implementation uses a provider pattern similar to OpenTelemetry's TracerProvider:

- **Core SDK**: Manages span lifecycle through `ITraceProvider` interface
- **Web Package**: Provides concrete `AppInsightsTraceProvider` implementation
- **Other SKUs**: Can provide their own implementations

### Key Interfaces

- `IOTelSpan`: OpenTelemetry-like span interface (simplified)
- `IOTelSpanContext`: Span context with trace information
- `ITraceProvider`: Provider interface for creating spans
- `SpanOptions`: Options for creating spans

## Usage

### 1. Setup the Provider

```typescript
import { ApplicationInsights, AppInsightsTraceProvider } from "@microsoft/applicationinsights-web";

// Initialize ApplicationInsights
const appInsights = new ApplicationInsights({
config: {
connectionString: "YOUR_CONNECTION_STRING_HERE"
}
});
appInsights.loadAppInsights();

// Register the trace provider
const traceProvider = new AppInsightsTraceProvider();
appInsights.appInsightsCore?.setTraceProvider(traceProvider);
```

### 2. Create and Use Spans

```typescript
import { SpanKind } from "@microsoft/applicationinsights-core-js";

// Start a span
const span = appInsights.appInsightsCore?.startSpan("operation-name", {
kind: SpanKind.CLIENT,
attributes: {
"user.id": "12345",
"operation.type": "http-request"
}
});

if (span) {
try {
// Do some work...
span.setAttribute("result", "success");

// Create a child span
const childSpan = appInsights.appInsightsCore?.startSpan(
"child-operation",
{
kind: SpanKind.INTERNAL
},
span.spanContext() // Parent context
);

if (childSpan) {
childSpan.setAttribute("step", "processing");
childSpan.end();
}

} catch (error) {
span.setAttribute("error", true);
span.setAttribute("error.message", error.message);
} finally {
span.end();
}
}
```

### 3. Check Provider Availability

```typescript
// Check if a trace provider is registered
const provider = appInsights.appInsightsCore?.getTraceProvider();
if (provider && provider.isAvailable()) {
console.log(`Provider: ${provider.getProviderId()}`);
// Use spans...
} else {
console.log("No trace provider available");
}
```

## Provider Implementation

To create a custom trace provider for a different SKU:

```typescript
import { ITraceProvider, IOTelSpan, SpanOptions, IDistributedTraceContext } from "@microsoft/applicationinsights-core-js";

export class CustomTraceProvider implements ITraceProvider {
public getProviderId(): string {
return "custom-provider";
}

public isAvailable(): boolean {
return true;
}

public createSpan(
name: string,
options?: SpanOptions,
parent?: IDistributedTraceContext
): IOTelSpan {
// Return your custom span implementation
return new CustomSpan(name, options, parent);
}
}
```

## Span Interface

The `IOTelSpan` interface provides these methods:

```typescript
interface IOTelSpan {
// Core methods
spanContext(): IOTelSpanContext;
setAttribute(key: string, value: string | number | boolean): IOTelSpan;
setAttributes(attributes: Record<string, string | number | boolean>): IOTelSpan;
updateName(name: string): IOTelSpan;
end(endTime?: number): void;
isRecording(): boolean;
}
```

## Differences from OpenTelemetry

This is a simplified implementation focused on ApplicationInsights needs:

- **Removed**: `addEvent()` and `setStatus()` methods
- **Simplified**: Attribute handling for ES5 compatibility
- **Focused**: Integration with ApplicationInsights telemetry system

## Benefits

1. **Flexibility**: Different SKUs can provide tailored implementations
2. **Clean Separation**: Core manages lifecycle, providers handle creation
3. **OpenTelemetry-like**: Familiar API for developers
4. **Extensible**: Easy to add new span providers
5. **Type Safe**: Full TypeScript support with proper interfaces
Loading
Loading