or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.md

index.mddocs/

0

# Langfuse OpenTelemetry Integration

1

2

Langfuse OpenTelemetry Integration (`@langfuse/otel`) provides an OpenTelemetry span processor that exports spans to the Langfuse observability platform. It enables automatic capture and forwarding of OpenTelemetry traces from AI applications to Langfuse with built-in support for data masking, span filtering, and media content handling.

3

4

## Package Information

5

6

- **Package Name**: @langfuse/otel

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @langfuse/otel`

10

- **Node Version**: >=20

11

- **License**: MIT

12

13

## Core Imports

14

15

```typescript

16

import { LangfuseSpanProcessor } from '@langfuse/otel';

17

import type {

18

LangfuseSpanProcessorParams,

19

MaskFunction,

20

ShouldExportSpan

21

} from '@langfuse/otel';

22

```

23

24

For CommonJS:

25

26

```javascript

27

const { LangfuseSpanProcessor } = require('@langfuse/otel');

28

```

29

30

## Basic Usage

31

32

```typescript

33

import { NodeSDK } from '@opentelemetry/sdk-node';

34

import { LangfuseSpanProcessor } from '@langfuse/otel';

35

36

// Create and configure the Langfuse span processor

37

const sdk = new NodeSDK({

38

spanProcessors: [

39

new LangfuseSpanProcessor({

40

publicKey: 'pk_...',

41

secretKey: 'sk_...',

42

baseUrl: 'https://cloud.langfuse.com',

43

environment: 'production'

44

})

45

]

46

});

47

48

// Start the SDK

49

sdk.start();

50

51

// Your OpenTelemetry instrumented code will now automatically

52

// export spans to Langfuse

53

```

54

55

## Architecture

56

57

The package implements a single main component:

58

59

- **LangfuseSpanProcessor**: A `SpanProcessor` implementation that integrates with OpenTelemetry's tracing pipeline. It extends standard span processing to provide:

60

- Automatic batching and flushing of spans to Langfuse

61

- Media content extraction and upload from base64 data URIs

62

- Data masking capabilities for sensitive information

63

- Conditional span export based on custom logic

64

- Environment and release tagging

65

66

The processor supports two export modes:

67

- **batched** (default): Recommended for production environments with long-running processes. Spans are batched and exported in groups for optimal performance.

68

- **immediate**: Recommended for short-lived environments such as serverless functions. Spans are exported immediately to prevent data loss when the process terminates.

69

70

## Capabilities

71

72

### Span Processor

73

74

OpenTelemetry span processor for exporting spans to Langfuse with advanced features.

75

76

```typescript { .api }

77

/**

78

* Creates a new LangfuseSpanProcessor instance.

79

*

80

* @param params - Configuration parameters for the processor

81

*/

82

class LangfuseSpanProcessor implements SpanProcessor {

83

constructor(params?: LangfuseSpanProcessorParams);

84

85

/**

86

* Called when a span is started. Adds environment and release attributes.

87

*

88

* @param span - The span that was started

89

* @param parentContext - The parent context

90

*/

91

onStart(span: Span, parentContext: any): void;

92

93

/**

94

* Called when a span ends. Processes the span for export to Langfuse.

95

* This method checks if the span should be exported, applies data masking,

96

* handles media content extraction and upload, and passes the span to the

97

* exporter.

98

*

99

* @param span - The span that ended

100

*/

101

onEnd(span: ReadableSpan): void;

102

103

/**

104

* Forces an immediate flush of all pending spans and media uploads.

105

*

106

* @returns Promise that resolves when all pending operations are complete

107

*/

108

forceFlush(): Promise<void>;

109

110

/**

111

* Gracefully shuts down the processor, ensuring all pending operations

112

* are completed.

113

*

114

* @returns Promise that resolves when shutdown is complete

115

*/

116

shutdown(): Promise<void>;

117

}

118

```

119

120

**Usage Example with Data Masking:**

121

122

```typescript

123

import { LangfuseSpanProcessor } from '@langfuse/otel';

124

125

const processor = new LangfuseSpanProcessor({

126

publicKey: 'pk_...',

127

secretKey: 'sk_...',

128

environment: 'staging',

129

mask: ({ data }) => {

130

// Mask sensitive data like passwords and API keys

131

if (typeof data === 'string') {

132

return data

133

.replace(/password=\w+/g, 'password=***')

134

.replace(/api_key=[\w-]+/g, 'api_key=***');

135

}

136

return data;

137

}

138

});

139

```

140

141

**Usage Example with Span Filtering:**

142

143

```typescript

144

import { LangfuseSpanProcessor } from '@langfuse/otel';

145

146

const processor = new LangfuseSpanProcessor({

147

publicKey: 'pk_...',

148

secretKey: 'sk_...',

149

shouldExportSpan: ({ otelSpan }) => {

150

// Only export spans from specific services or that meet certain criteria

151

return otelSpan.name.startsWith('llm-') ||

152

otelSpan.attributes['service.name'] === 'my-ai-service';

153

}

154

});

155

```

156

157

**Usage Example for Serverless:**

158

159

```typescript

160

import { LangfuseSpanProcessor } from '@langfuse/otel';

161

162

const processor = new LangfuseSpanProcessor({

163

publicKey: 'pk_...',

164

secretKey: 'sk_...',

165

exportMode: 'immediate', // Export spans immediately in serverless

166

timeout: 10 // Increase timeout for serverless cold starts

167

});

168

```

169

170

### Configuration

171

172

Configuration parameters for the LangfuseSpanProcessor.

173

174

```typescript { .api }

175

interface LangfuseSpanProcessorParams {

176

/**

177

* Custom OpenTelemetry span exporter. If not provided, a default OTLP

178

* exporter will be used that sends spans to the Langfuse API.

179

*/

180

exporter?: SpanExporter;

181

182

/**

183

* Langfuse public API key. Can also be set via LANGFUSE_PUBLIC_KEY

184

* environment variable.

185

*/

186

publicKey?: string;

187

188

/**

189

* Langfuse secret API key. Can also be set via LANGFUSE_SECRET_KEY

190

* environment variable.

191

*/

192

secretKey?: string;

193

194

/**

195

* Langfuse instance base URL. Can also be set via LANGFUSE_BASE_URL

196

* or LANGFUSE_BASEURL (legacy) environment variable.

197

* @defaultValue "https://cloud.langfuse.com"

198

*/

199

baseUrl?: string;

200

201

/**

202

* Number of spans to batch before flushing. Can also be set via

203

* LANGFUSE_FLUSH_AT environment variable. Only applies when exportMode

204

* is "batched".

205

*/

206

flushAt?: number;

207

208

/**

209

* Flush interval in seconds. Can also be set via LANGFUSE_FLUSH_INTERVAL

210

* environment variable. Only applies when exportMode is "batched".

211

*/

212

flushInterval?: number;

213

214

/**

215

* Function to mask sensitive data in spans before export. Applied to

216

* span attributes containing input, output, and metadata fields.

217

*/

218

mask?: MaskFunction;

219

220

/**

221

* Function to determine whether a span should be exported to Langfuse.

222

* If this function returns false, the span will not be exported.

223

*/

224

shouldExportSpan?: ShouldExportSpan;

225

226

/**

227

* Environment identifier for the traces. Can also be set via

228

* LANGFUSE_TRACING_ENVIRONMENT environment variable. This value is added

229

* as an attribute to all spans.

230

*/

231

environment?: string;

232

233

/**

234

* Release identifier for the traces. Can also be set via LANGFUSE_RELEASE

235

* environment variable. This value is added as an attribute to all spans.

236

*/

237

release?: string;

238

239

/**

240

* Request timeout in seconds. Can also be set via LANGFUSE_TIMEOUT

241

* environment variable.

242

* @defaultValue 5

243

*/

244

timeout?: number;

245

246

/**

247

* Additional HTTP headers to include with requests to the Langfuse API.

248

*/

249

additionalHeaders?: Record<string, string>;

250

251

/**

252

* Span export mode to use.

253

*

254

* - **batched**: Recommended for production environments with long-running

255

* processes. Spans are batched and exported in groups for optimal

256

* performance.

257

* - **immediate**: Recommended for short-lived environments such as

258

* serverless functions. Spans are exported immediately to prevent data

259

* loss when the process terminates or is frozen.

260

*

261

* @defaultValue "batched"

262

*/

263

exportMode?: "immediate" | "batched";

264

}

265

```

266

267

### Mask Function

268

269

Function type for masking sensitive data in spans before export.

270

271

```typescript { .api }

272

/**

273

* Function type for masking sensitive data in spans before export.

274

*

275

* The mask function is applied to span attributes that may contain sensitive

276

* information (input, output, and metadata fields). It receives the data and

277

* should return a masked version of it.

278

*

279

* @param params - Object containing the data to be masked

280

* @param params.data - The data that should be masked (can be of any type)

281

* @returns The masked data (can be of any type)

282

*/

283

type MaskFunction = (params: { data: any }) => any;

284

```

285

286

**Usage Example:**

287

288

```typescript

289

const maskFunction: MaskFunction = ({ data }) => {

290

if (typeof data === 'string') {

291

// Mask credit card numbers

292

data = data.replace(/\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g, 'XXXX-XXXX-XXXX-XXXX');

293

// Mask email addresses

294

data = data.replace(/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g, '***@***.***');

295

} else if (typeof data === 'object' && data !== null) {

296

// Deep clone and mask object properties

297

const masked = JSON.parse(JSON.stringify(data));

298

if ('password' in masked) masked.password = '***';

299

if ('apiKey' in masked) masked.apiKey = '***';

300

return masked;

301

}

302

return data;

303

};

304

```

305

306

### Should Export Span Function

307

308

Function type for determining whether a span should be exported to Langfuse.

309

310

```typescript { .api }

311

/**

312

* Function type for determining whether a span should be exported to Langfuse.

313

*

314

* This function is called for each span before it is exported. If it returns

315

* false, the span will not be exported to Langfuse.

316

*

317

* @param params - Object containing the span to evaluate

318

* @param params.otelSpan - The OpenTelemetry span to evaluate

319

* @returns true if the span should be exported, false otherwise

320

*/

321

type ShouldExportSpan = (params: { otelSpan: ReadableSpan }) => boolean;

322

```

323

324

**Usage Example:**

325

326

```typescript

327

const shouldExportSpan: ShouldExportSpan = ({ otelSpan }) => {

328

// Only export spans that took longer than 100ms

329

const durationMs = otelSpan.duration[0] * 1000 + otelSpan.duration[1] / 1000000;

330

if (durationMs <= 100) return false;

331

332

// Don't export health check spans

333

if (otelSpan.name.includes('health-check')) return false;

334

335

// Only export spans from production environment

336

const env = otelSpan.attributes['deployment.environment'];

337

return env === 'production';

338

};

339

```

340

341

## Environment Variables

342

343

The package can be configured using the following environment variables:

344

345

- `LANGFUSE_PUBLIC_KEY` - Langfuse public API key

346

- `LANGFUSE_SECRET_KEY` - Langfuse secret API key

347

- `LANGFUSE_BASE_URL` - Langfuse instance base URL (defaults to "https://cloud.langfuse.com")

348

- `LANGFUSE_BASEURL` - Legacy alternative for LANGFUSE_BASE_URL

349

- `LANGFUSE_FLUSH_AT` - Number of spans to batch before flushing (batched mode only)

350

- `LANGFUSE_FLUSH_INTERVAL` - Flush interval in seconds (batched mode only)

351

- `LANGFUSE_TRACING_ENVIRONMENT` - Environment identifier for traces

352

- `LANGFUSE_RELEASE` - Release identifier for traces

353

- `LANGFUSE_TIMEOUT` - Request timeout in seconds (defaults to 5)

354

355

## Peer Dependencies

356

357

This package requires the following peer dependencies to be installed:

358

359

- `@opentelemetry/api` ^1.9.0

360

- `@opentelemetry/core` ^2.0.1

361

- `@opentelemetry/exporter-trace-otlp-http` >=0.202.0 <1.0.0

362

- `@opentelemetry/sdk-trace-base` ^2.0.1

363

364

## Types

365

366

The package uses OpenTelemetry types from peer dependencies:

367

368

- `Span` - from `@opentelemetry/sdk-trace-base`

369

- `ReadableSpan` - from `@opentelemetry/sdk-trace-base`

370

- `SpanProcessor` - from `@opentelemetry/sdk-trace-base`

371

- `SpanExporter` - from `@opentelemetry/sdk-trace-base`

372

373

## Error Handling

374

375

The processor handles errors gracefully:

376

377

- If a `MaskFunction` throws an error, the affected attribute is fully masked with the string `"<fully masked due to failed mask function>"` and a warning is logged

378

- If a `ShouldExportSpan` function throws an error, the span is excluded from export and an error is logged

379

- Media upload failures are logged as errors but do not prevent span export

380

- Authentication failures (missing public/secret key) are logged as warnings during initialization

381