Langfuse instrumentation methods based on OpenTelemetry
npx @tessl/cli install tessl/npm-langfuse--tracing@4.2.0OpenTelemetry-based instrumentation methods for observability and tracing of LLM (Large Language Model) applications. This package provides comprehensive functions and decorators for creating and managing observations with automatic lifecycle management, supporting multiple observation types including spans, generations, agents, tools, chains, retrievers, evaluators, guardrails, embeddings, and events, with full TypeScript type safety and automatic type inference.
npm install @langfuse/tracing @opentelemetry/api@opentelemetry/api@^1.9.0import {
startObservation,
startActiveObservation,
observe,
updateActiveTrace,
updateActiveObservation,
getActiveTraceId,
getActiveSpanId,
createTraceId,
createTraceAttributes,
createObservationAttributes,
setLangfuseTracerProvider,
getLangfuseTracerProvider,
getLangfuseTracer
} from '@langfuse/tracing';Type imports:
import type {
// Core observation types
LangfuseObservationType,
ObservationLevel,
// Attribute types
LangfuseSpanAttributes,
LangfuseEventAttributes,
LangfuseGenerationAttributes,
LangfuseObservationAttributes,
LangfuseTraceAttributes,
// Option types
StartObservationOptions,
StartActiveObservationContext,
StartObservationOpts,
StartActiveObservationOpts,
ObserveOptions,
// Context types
TraceContext,
// Observation class types
LangfuseObservation,
LangfuseSpan,
LangfuseGeneration,
LangfuseEvent,
LangfuseAgent,
LangfuseTool,
LangfuseChain,
LangfuseRetriever,
LangfuseEvaluator,
LangfuseGuardrail,
LangfuseEmbedding,
// OpenTelemetry constants
LangfuseOtelSpanAttributes
} from '@langfuse/tracing';Note: Observation-specific attribute types (LangfuseAgentAttributes, LangfuseToolAttributes, etc.) are not exported from the package. Instead, use LangfuseSpanAttributes for span-based observations (agent, tool, chain, retriever, evaluator, guardrail, event) or LangfuseGenerationAttributes for generation-based observations (embedding). These specialized types are type aliases internally but are not part of the public API.
For CommonJS:
const {
startObservation,
startActiveObservation,
observe
} = require('@langfuse/tracing');import { startObservation, startActiveObservation } from '@langfuse/tracing';
// Manual lifecycle management
const span = startObservation('data-processing', {
input: { userId: '123', dataSize: 1024 },
metadata: { processor: 'fast-lane' }
});
try {
const result = await processData();
span.update({ output: { processed: true, records: result.count } });
} finally {
span.end();
}
// Automatic lifecycle management
const response = await startActiveObservation(
'llm-call',
async (generation) => {
generation.update({
input: [{ role: 'user', content: 'Explain AI' }],
model: 'gpt-4',
modelParameters: { temperature: 0.7 }
});
const result = await openai.chat.completions.create({
model: 'gpt-4',
messages: [{ role: 'user', content: 'Explain AI' }]
});
generation.update({
output: result.choices[0].message,
usageDetails: {
promptTokens: result.usage.prompt_tokens,
completionTokens: result.usage.completion_tokens
}
});
return result.choices[0].message.content;
},
{ asType: 'generation' }
);
// Zero-code-change function wrapping
const processOrder = observe(
async (orderId: string, items: CartItem[]) => {
const validation = await validateOrder(orderId, items);
const payment = await processPayment(validation);
return { orderId, status: 'confirmed' };
},
{
name: 'process-order',
asType: 'span',
captureInput: true,
captureOutput: true
}
);The @langfuse/tracing package is built around several key components:
startObservation() for manual lifecycle controlstartActiveObservation() for function-scoped automatic managementobserve() decorator for wrapping existing functionsCreate observations with explicit control over start and end timing. Ideal for complex workflows requiring precise timing control or long-running operations.
function startObservation(
name: string,
attributes?: LangfuseObservationAttributes,
options?: StartObservationOpts
): LangfuseObservation;
type StartObservationOpts = {
asType?: LangfuseObservationType;
startTime?: Date;
parentSpanContext?: SpanContext;
};Execute functions within observation contexts with automatic lifecycle management, context propagation, and error handling. Perfect for function-scoped operations.
function startActiveObservation<F extends (observation: LangfuseObservation) => unknown>(
name: string,
fn: F,
options?: StartActiveObservationOpts
): ReturnType<F>;
type StartActiveObservationOpts = {
asType?: LangfuseObservationType;
startTime?: Date;
parentSpanContext?: SpanContext;
endOnExit?: boolean;
};Automatic Observation Lifecycle
Wrap existing functions with observability without modifying their implementation. Zero-code-change instrumentation for any function.
function observe<T extends (...args: any[]) => any>(
fn: T,
options?: ObserveOptions
): T;
interface ObserveOptions {
name?: string;
asType?: LangfuseObservationType;
captureInput?: boolean;
captureOutput?: boolean;
parentSpanContext?: SpanContext;
endOnExit?: boolean;
}Ten specialized observation types for different AI workflow scenarios: spans for general operations, generations for LLM calls, agents for autonomous workflows, tools for API calls, chains for multi-step pipelines, retrievers for document search, evaluators for quality assessment, guardrails for safety checks, embeddings for vector operations, and events for point-in-time logging.
type LangfuseObservationType =
| "span"
| "generation"
| "event"
| "agent"
| "tool"
| "chain"
| "retriever"
| "evaluator"
| "guardrail"
| "embedding";Access and update the currently active trace and observation contexts from anywhere in your code execution flow.
function updateActiveTrace(attributes: LangfuseTraceAttributes): void;
function updateActiveObservation(
attributes: LangfuseObservationAttributes,
options?: { asType?: LangfuseObservationType }
): void;
function getActiveTraceId(): string | undefined;
function getActiveSpanId(): string | undefined;Configure custom OpenTelemetry tracer providers for isolated or customized tracing setups, enabling integration with existing OpenTelemetry infrastructure.
function setLangfuseTracerProvider(provider: TracerProvider | null): void;
function getLangfuseTracerProvider(): TracerProvider;
function getLangfuseTracer(): Tracer;Create deterministic or random trace IDs for custom trace correlation and external system integration.
async function createTraceId(seed?: string): Promise<string>;Low-level functions for creating OpenTelemetry attributes from Langfuse-specific attribute types. Typically used internally but available for advanced use cases.
function createTraceAttributes(attributes?: LangfuseTraceAttributes): Attributes;
function createObservationAttributes(
type: LangfuseObservationType,
attributes: LangfuseObservationAttributes
): Attributes;Enum of OpenTelemetry attribute key constants used by Langfuse for trace and observation attributes. Primarily used internally but exported for advanced use cases requiring direct OpenTelemetry span manipulation.
enum LangfuseOtelSpanAttributes {
// Trace attributes
TRACE_NAME = "langfuse.trace.name",
TRACE_USER_ID = "user.id",
TRACE_SESSION_ID = "session.id",
// Observation attributes
OBSERVATION_TYPE = "langfuse.observation.type",
OBSERVATION_INPUT = "langfuse.observation.input",
OBSERVATION_OUTPUT = "langfuse.observation.output",
// ... and more (see full documentation)
}type LangfuseSpanAttributes = {
input?: unknown;
output?: unknown;
metadata?: Record<string, unknown>;
level?: ObservationLevel;
statusMessage?: string;
version?: string;
environment?: string;
};
type ObservationLevel = "DEBUG" | "DEFAULT" | "WARNING" | "ERROR";
type LangfuseGenerationAttributes = LangfuseSpanAttributes & {
completionStartTime?: Date;
model?: string;
modelParameters?: { [key: string]: string | number };
usageDetails?: { [key: string]: number };
costDetails?: { [key: string]: number };
prompt?: {
name: string;
version: number;
isFallback: boolean;
};
};type LangfuseTraceAttributes = {
name?: string;
userId?: string;
sessionId?: string;
version?: string;
release?: string;
input?: unknown;
output?: unknown;
metadata?: unknown;
tags?: string[];
public?: boolean;
environment?: string;
};type LangfuseObservation =
| LangfuseSpan
| LangfuseGeneration
| LangfuseEvent
| LangfuseAgent
| LangfuseTool
| LangfuseChain
| LangfuseRetriever
| LangfuseEvaluator
| LangfuseGuardrail
| LangfuseEmbedding;Context information for linking observations to traces, used internally for maintaining parent-child relationships between observations.
type TraceContext = {
/** The trace ID that observations should be linked to */
traceId: string;
/** Optional parent observation ID for creating hierarchical relationships */
parentObservationId?: string;
};The following observation types use specialized attribute structures:
Span-based observations (all extend LangfuseSpanAttributes):
type LangfuseEventAttributes = LangfuseSpanAttributes;
type LangfuseAgentAttributes = LangfuseSpanAttributes;
type LangfuseToolAttributes = LangfuseSpanAttributes;
type LangfuseChainAttributes = LangfuseSpanAttributes;
type LangfuseRetrieverAttributes = LangfuseSpanAttributes;
type LangfuseEvaluatorAttributes = LangfuseSpanAttributes;
type LangfuseGuardrailAttributes = LangfuseSpanAttributes;Generation-based observations (extend LangfuseGenerationAttributes):
type LangfuseEmbeddingAttributes = LangfuseGenerationAttributes;These type aliases provide semantic clarity while inheriting all properties from their base types. When using observation-specific types (agent, tool, chain, etc.), you have access to all the same attributes as LangfuseSpanAttributes (input, output, metadata, level, statusMessage, version, environment).