Telemetry
The Telemetry module provides OpenTelemetry integration for operations performed against a large language model provider by defining telemetry attributes and utilities that follow the OpenTelemetry GenAI semantic conventions.
Context
CurrentSpanTransformer
Signature
declare class CurrentSpanTransformer extends any {
constructor();
}Example
import { Telemetry } from "@effect/ai"
import * as Effect from "effect/Effect"
declare const myAIOperation: Effect.Effect<void>
// Create a custom span transformer
const loggingTransformer: Telemetry.SpanTransformer = (options) => {
console.log(`AI request completed: ${options.response.length} part(s)`)
options.response.forEach((part, index) => {
console.log(`Part ${index}: ${part.type}`)
})
}
// Provide the transformer to your AI operations
const program = myAIOperation.pipe(
Effect.provideService(
Telemetry.CurrentSpanTransformer,
Telemetry.CurrentSpanTransformer.of(loggingTransformer),
),
)Models
AllAttributes type
All telemetry attributes which are part of the GenAI specification.
Signature
type AllAttributes = BaseAttributes &
OperationAttributes &
TokenAttributes &
UsageAttributes &
RequestAttributes &
ResponseAttributes;BaseAttributes interface
Telemetry attributes which are part of the GenAI specification and are namespaced by gen_ai.
Signature
interface BaseAttributes {
readonly system?: (string & {}) | WellKnownSystem | null;
}GenAITelemetryAttributeOptions type
Configuration options for GenAI telemetry attributes.
Combines base attributes with optional grouped attributes for comprehensive telemetry coverage of AI operations.
Signature
type GenAITelemetryAttributeOptions = BaseAttributes & {
readonly operation?: OperationAttributes;
readonly request?: RequestAttributes;
readonly response?: ResponseAttributes;
readonly token?: TokenAttributes;
readonly usage?: UsageAttributes;
};Example
import { Telemetry } from "@effect/ai"
const telemetryOptions: Telemetry.GenAITelemetryAttributeOptions = {
system: "openai",
operation: {
name: "chat",
},
request: {
model: "gpt-4-turbo",
temperature: 0.7,
maxTokens: 2000,
},
response: {
id: "chatcmpl-123",
model: "gpt-4-turbo-2024-04-09",
finishReasons: ["stop"],
},
usage: {
inputTokens: 50,
outputTokens: 25,
},
}GenAITelemetryAttributes type
The attributes used to describe telemetry in the context of Generative Artificial Intelligence (GenAI) Models requests and responses.
https://opentelemetry.io/docs/specs/semconv/attributes-registry/gen-ai/
Signature
type GenAITelemetryAttributes = Simplify<
AttributesWithPrefix<BaseAttributes, "gen_ai"> &
AttributesWithPrefix<OperationAttributes, "gen_ai.operation"> &
AttributesWithPrefix<TokenAttributes, "gen_ai.token"> &
AttributesWithPrefix<UsageAttributes, "gen_ai.usage"> &
AttributesWithPrefix<RequestAttributes, "gen_ai.request"> &
AttributesWithPrefix<ResponseAttributes, "gen_ai.response">
>;OperationAttributes interface
Telemetry attributes which are part of the GenAI specification and are namespaced by gen_ai.operation.
Signature
interface OperationAttributes {
readonly name?: (string & {}) | WellKnownOperationName | null;
}RequestAttributes interface
Telemetry attributes which are part of the GenAI specification and are namespaced by gen_ai.request.
Signature
interface RequestAttributes {
readonly encodingFormats?: readonly Array<string> | null;
readonly frequencyPenalty?: number | null;
readonly maxTokens?: number | null;
readonly model?: string | null;
readonly presencePenalty?: number | null;
readonly seed?: number | null;
readonly stopSequences?: readonly Array<string> | null;
readonly temperature?: number | null;
readonly topK?: number | null;
readonly topP?: number | null;
}ResponseAttributes interface
Telemetry attributes which are part of the GenAI specification and are namespaced by gen_ai.response.
Signature
interface ResponseAttributes {
readonly finishReasons?: readonly Array<string> | null;
readonly id?: string | null;
readonly model?: string | null;
}SpanTransformer interface
A function that can transform OpenTelemetry spans based on AI operation data.
Span transformers receive the complete request/response context from AI operations and can add custom telemetry attributes, metrics, or other observability data.
Signature
interface SpanTransformer {
(options: ProviderOptions & {
readonly response: readonly Array<AllParts<any>>;
}): void;
}Example
import { Telemetry } from "@effect/ai"
const customTransformer: Telemetry.SpanTransformer = (options) => {
// Add custom attributes based on the response
const textParts = options.response.filter((part) => part.type === "text")
const totalTextLength = textParts.reduce(
(sum, part) => sum + (part.type === "text" ? part.text.length : 0),
0,
)
// Add custom metrics
console.log(`Generated ${totalTextLength} characters of text`)
}TokenAttributes interface
Telemetry attributes which are part of the GenAI specification and are namespaced by gen_ai.token.
Signature
interface TokenAttributes {
readonly type?: string | null;
}UsageAttributes interface
Telemetry attributes which are part of the GenAI specification and are namespaced by gen_ai.usage.
Signature
interface UsageAttributes {
readonly inputTokens?: number | null;
readonly outputTokens?: number | null;
}WellKnownOperationName type
The gen_ai.operation.name attribute has the following list of well-known values.
If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
Signature
type WellKnownOperationName = "chat" | "embeddings" | "text_completion";WellKnownSystem type
The gen_ai.system attribute has the following list of well-known values.
If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
Signature
type WellKnownSystem =
| "anthropic"
| "aws.bedrock"
| "az.ai.inference"
| "az.ai.openai"
| "cohere"
| "deepseek"
| "gemini"
| "groq"
| "ibm.watsonx.ai"
| "mistral_ai"
| "openai"
| "perplexity"
| "vertex_ai"
| "xai";Utilities
addGenAIAnnotations
Applies GenAI telemetry attributes to an OpenTelemetry span.
This function adds standardized GenAI attributes to a span following OpenTelemetry semantic conventions. It supports both curried and direct application patterns.
Note: This function mutates the provided span in-place.
Signature
declare const addGenAIAnnotations: {
(options: GenAITelemetryAttributeOptions): (span: Span) => void;
(span: Span, options: GenAITelemetryAttributeOptions): void;
};Example
import { Telemetry } from "@effect/ai"
import { Effect } from "effect"
const directUsage = Effect.gen(function* () {
const span = yield* Effect.currentSpan
Telemetry.addGenAIAnnotations(span, {
system: "openai",
request: { model: "gpt-4", temperature: 0.7 },
usage: { inputTokens: 100, outputTokens: 50 },
})
})addSpanAttributes
Creates a function to add attributes to a span with a given prefix and key transformation.
This utility function is used internally to create specialized functions for adding different types of telemetry attributes to OpenTelemetry spans.
Signature
declare function addSpanAttributes(
keyPrefix: string,
transformKey: (key: string) => string,
): <Attributes extends Record<string, any>>(span: Span, attributes: Attributes) => void;Utility Types
AttributesWithPrefix type
Utility type for prefixing attribute names with a namespace.
Transforms attribute keys by adding a prefix and formatting them according to OpenTelemetry conventions (camelCase to snake_case).
Signature
type AttributesWithPrefix<Attributes extends Record<string, any>, Prefix extends string> = {
[Name in keyof Attributes]: Attributes[Name];
};Example
import { Telemetry } from "@effect/ai"
type RequestAttrs = {
modelName: string
maxTokens: number
}
type PrefixedAttrs = Telemetry.AttributesWithPrefix<RequestAttrs, "gen_ai.request">
// Results in: {
// "gen_ai.request.model_name": string
// "gen_ai.request.max_tokens": number
// }FormatAttributeName type
Utility type for converting camelCase names to snake_case format.
This type recursively transforms string literal types from camelCase to snake_case, which is the standard format for OpenTelemetry attributes.
Signature
type FormatAttributeName<T extends string | number | symbol> = T extends string
? T extends `${infer First}${infer Rest}`
? `${First extends Uppercase<First> ? "_" : ""}${Lowercase<First>}${FormatAttributeName<Rest>}`
: T
: never;Example
import { Telemetry } from "@effect/ai"
type Formatted1 = Telemetry.FormatAttributeName<"modelName"> // "model_name"
type Formatted2 = Telemetry.FormatAttributeName<"maxTokens"> // "max_tokens"
type Formatted3 = Telemetry.FormatAttributeName<"temperature"> // "temperature"
Context tag for providing a span transformer to large langauge model operations.
The CurrentSpanTransformer allows you to inject custom span transformation logic into AI operations, enabling application-specific telemetry and observability patterns.