UNPKG

enhanced-adot-node-autoinstrumentation

Version:

This package provides Amazon Web Services distribution of the OpenTelemetry Node Instrumentation, which allows for auto-instrumentation of NodeJS applications.

272 lines (269 loc) 13.2 kB
import { LoggerProvider } from '@opentelemetry/sdk-logs'; import { ReadableSpan } from '@opentelemetry/sdk-trace-base'; /** * Utility class for handling Large Language Objects (LLO) in OpenTelemetry spans. * * LLOHandler performs three primary functions: * 1. Identifies Large Language Objects (LLO) content in spans * 2. Extracts and transforms these attributes into OpenTelemetry Gen AI Events * 3. Filters LLO from spans to maintain privacy and reduce span size * * Supported frameworks and their attribute patterns: * - Standard Gen AI: * - gen_ai.prompt.{n}.content: Structured prompt content * - gen_ai.prompt.{n}.role: Role for prompt content (system, user, assistant, etc.) * - gen_ai.completion.{n}.content: Structured completion content * - gen_ai.completion.{n}.role: Role for completion content (usually assistant) * * - Traceloop: * - traceloop.entity.input: Input text for LLM operations * - traceloop.entity.output: Output text from LLM operations * - traceloop.entity.name: Name of the entity processing the LLO * - crewai.crew.tasks_output: Tasks output data from CrewAI (uses gen_ai.system if available) * - crewai.crew.result: Final result from CrewAI crew (uses gen_ai.system if available) * * - OpenLit: * - gen_ai.prompt: Direct prompt text (treated as user message) * - gen_ai.completion: Direct completion text (treated as assistant message) * - gen_ai.content.revised_prompt: Revised prompt text (treated as system message) * - gen_ai.agent.actual_output: Output from CrewAI agent (treated as assistant message) * * - OpenInference: * - input.value: Direct input prompt * - output.value: Direct output response * - llm.input_messages.{n}.message.content: Individual structured input messages * - llm.input_messages.{n}.message.role: Role for input messages * - llm.output_messages.{n}.message.content: Individual structured output messages * - llm.output_messages.{n}.message.role: Role for output messages * - llm.model_name: Model name used for the LLM operation */ export declare class LLOHandler { private loggerProvider; private eventLoggerProvider; private eventLogger; /** * Initialize an LLOHandler with the specified logger provider. * * This constructor sets up the event logger provider, configures the event logger, * and initializes the patterns used to identify LLO attributes. * * @param loggerProvider The OpenTelemetry LoggerProvider used for emitting events. * Global LoggerProvider instance injected from our AwsOpenTelemetryConfigurator */ constructor(loggerProvider: LoggerProvider); /** * Processes a sequence of spans to extract and filter LLO attributes. * * For each span, this method: * 1. Extracts LLO attributes and emits them as Gen AI Events * 2. Filters out LLO attributes from the span to maintain privacy * 3. Processes any LLO attributes in span events * 4. Preserves non-LLO attributes in the span * * Handles LLO attributes from multiple frameworks: * - Standard Gen AI (structured prompt/completion pattern) * - Traceloop (entity input/output pattern) * - OpenLit (direct prompt/completion pattern) * - OpenInference (input/output value and structured messages pattern) * * @param spans An array of OpenTelemetry ReadableSpan objects to process * @returns {ReadableSpan[]} Modified spans with LLO attributes removed */ processSpans(spans: ReadableSpan[]): ReadableSpan[]; /** * Process events within a span to extract and filter LLO attributes. * * For each event in the span, this method: * 1. Emits LLO attributes found in event attributes as Gen AI Events * 2. Filters out LLO attributes from event attributes * 3. Creates updated events with filtered attributes * 4. Replaces the original span events with updated events * * This ensures that LLO attributes are properly handled even when they appear * in span events rather than directly in the span's attributes. * * @param span The ReadableSpan to process events for */ processSpanEvents(span: ReadableSpan): void; /** * Extract Gen AI Events from LLO attributes and emit them via the event logger. * * This method: * 1. Collects LLO attributes from multiple frameworks using specialized extractors * 2. Converts each LLO attribute into appropriate Gen AI Events * 3. Emits all collected events through the event logger * * Supported frameworks: * - Standard Gen AI: Structured prompt/completion with roles * - Traceloop: Entity input/output and CrewAI outputs * - OpenLit: Direct prompt/completion/revised prompt and agent outputs * - OpenInference: Direct values and structured messages * * @param span The source ReadableSpan containing the attributes * @param attributes Attributes to process * @param eventTimestamp Optional timestamp to override span timestamps */ private emitLloAttributes; /** * Create a new attributes dictionary with LLO attributes removed. * This method creates a new dictionary containing only non-LLO attributes, * preserving the original values while filtering out sensitive LLO content. * This helps maintain privacy and reduces the size of spans. * * @param attributes Span or event attributes * @returns {Attributes} New Attributes with LLO attributes removed */ private filterAttributes; /** * Determine if an attribute key contains LLO content based on pattern matching. * * Checks attribute keys against two types of patterns: * 1. Exact match patterns (complete string equality): * - Traceloop: "traceloop.entity.input", "traceloop.entity.output" * - OpenLit: "gen_ai.prompt", "gen_ai.completion", "gen_ai.content.revised_prompt" * - OpenInference: "input.value", "output.value" * * 2. Regex match patterns (regular expression matching): * - Standard Gen AI: "gen_ai.prompt.{n}.content", "gen_ai.completion.{n}.content" * - OpenInference: "llm.input_messages.{n}.message.content", "llm.output_messages.{n}.message.content" * * @param key The attribute key to check * @returns {boolean} true if the key matches any LLO pattern, false otherwise */ private isLloAttribute; /** * Extract Gen AI Events from structured prompt attributes. * * Processes attributes matching the pattern `gen_ai.prompt.{n}.content` and their * associated `gen_ai.prompt.{n}.role` attributes to create appropriate events. * * Event types are determined by the role: * 1. `system` → `gen_ai.system.message` Event * 2. `user` → `gen_ai.user.message` Event * 3. `assistant` → `gen_ai.assistant.message` Event * 4. `function` → `gen_ai.{gen_ai.system}.message` custom Event * 5. `unknown` → `gen_ai.{gen_ai.system}.message` custom Event * * @param span The source ReadableSpan containing the attributes * @param attributes Attributes to process * @param eventTimestamp Optional timestamp to override span.startTime * @returns {Event[]} Events created from prompt attributes */ private extractGenAiPromptEvents; /** * Extract Gen AI Events from structured completion attributes. * * Processes attributes matching the pattern `gen_ai.completion.{n}.content` and their * associated `gen_ai.completion.{n}.role` attributes to create appropriate events. * * Event types are determined by the role: * 1. `assistant` → `gen_ai.assistant.message` Event (most common) * 2. Other roles → `gen_ai.{gen_ai.system}.message` custom Event * * @param span The source ReadableSpan containing the attributes * @param attributes Attributes to process * @param eventTimestamp Optional timestamp to override span.endTime * @returns {Event[]} Events created from completion attributes */ private extractGenAiCompletionEvents; /** * Extract Gen AI Events from Traceloop attributes. * * Processes Traceloop-specific attributes: * - `traceloop.entity.input`: Input data (uses span.startTime) * - `traceloop.entity.output`: Output data (uses span.endTime) * - `traceloop.entity.name`: Used as the gen_ai.system value when gen_ai.system isn't available * - `crewai.crew.tasksOutput`: Tasks output data from CrewAI (uses span.endTime) * - `crewai.crew.result`: Final result from CrewAI crew (uses span.endTime) * * Creates generic `gen_ai.{entity_name}.message` events for both input and output, * and assistant message events for CrewAI outputs. * * For CrewAI-specific attributes (crewai.crew.tasks_output and crewai.crew.result), * uses span's gen_ai.system attribute if available, otherwise falls back to traceloop.entity.name. * * @param span The source ReadableSpan containing the attributes * @param attributes Attributes to process * @param eventTimestamp Optional timestamp to override span timestamps * @returns {Event[]} Events created from Traceloop attributes */ private extractTraceloopEvents; /** * Extract Gen AI Events from OpenLit direct attributes. * OpenLit uses direct key-value pairs for LLO attributes: * - `gen_ai.prompt`: Direct prompt text (treated as user message) * - `gen_ai.completion`: Direct completion text (treated as assistant message) * - `gen_ai.content.revised_prompt`: Revised prompt text (treated as system message) * - `gen_ai.agent.actual_output`: Output from CrewAI agent (treated as assistant message) * The event timestamps are set based on attribute type: * - Prompt and revised prompt: span.startTime * - Completion and agent output: span.endTime * * @param span The source ReadableSpan containing the attributes * @param attributes Attributes to process * @param eventTimestamp Optional timestamp to override span timestamps * @returns {Event[]} Events created from OpenLit attributes */ private extractOpenlitSpanEventAttributes; /** * Extract Gen AI Events from OpenInference attributes. * * OpenInference uses two patterns for LLO attributes: * 1. Direct values: * - `input.value`: Direct input prompt (treated as user message) * - `output.value`: Direct output response (treated as assistant message) * * 2. Structured messages: * - `llm.input_messages.{n}.message.content`: Individual input messages * - `llm.input_messages.{n}.message.role`: Role for input message * - `llm.output_messages.{n}.message.content`: Individual output messages * - `llm.output_messages.{n}.message.role`: Role for output message * * The LLM model name is extracted from the `llm.model_name` attribute * instead of `gen_ai.system` which other frameworks use. * * Event timestamps are set based on message type: * - Input messages: span.startTime * - Output messages: span.endTime * * @param span The source ReadableSpan containing the attributes * @param attributes Attributes to process * @param eventTimestamp Optional timestamp to override span timestamps * @returns {Event[]} Events created from OpenInference attributes */ private extractOpeninferenceAttributes; /** * Map a message role to the appropriate event name. * * @param role The role of the message (system, user, assistant, etc.) * @param genAiSystem The gen_ai system identifier * @returns {string} The appropriate event name for the given role */ private getEventNameForRole; /** * Determine the appropriate timestamp to use for an event. * * @param span The source span * @param eventTimestamp Optional override timestamp * @param isInput Whether this is an input (true) or output (false) message * @returns {number} The timestamp to use for the event */ private getTimestamp; /** * Create and return a Gen AI Event with the specified parameters. * * This helper method constructs a fully configured OpenTelemetry Event object * that includes all necessary fields for proper event propagation and context. * * @param name Event type name (e.g., gen_ai.system.message, gen_ai.user.message) * @param spanCtx Span context to extract trace/span IDs from * @param timestamp Timestamp for the event (nanoseconds) * @param attributes Additional attributes to include with the event * @param data Event body containing content and role information * @param span A ReadableSpan associated with the Span context * @returns {Event}: A fully configured OpenTelemetry Gen AI Event object with proper trace context propagation */ private getGenAiEvent; } export declare function createContextKey(description: string): symbol; //# sourceMappingURL=llo-handler.d.ts.map