0
# OpenTelemetry Span Attributes
1
2
The `LangfuseOtelSpanAttributes` enum provides constant keys for OpenTelemetry span attributes used by Langfuse. These constants are primarily used internally by the `createTraceAttributes()` and `createObservationAttributes()` functions but are exported for advanced use cases where you need direct access to the underlying OpenTelemetry attribute keys.
3
4
## Usage
5
6
```typescript
7
import { LangfuseOtelSpanAttributes } from '@langfuse/tracing';
8
import { trace } from '@opentelemetry/api';
9
10
// Advanced: Directly set OpenTelemetry attributes
11
const span = trace.getActiveSpan();
12
if (span) {
13
span.setAttribute(
14
LangfuseOtelSpanAttributes.TRACE_USER_ID,
15
'user-123'
16
);
17
}
18
```
19
20
## Attribute Constants
21
22
### Trace Attributes
23
24
Constants for trace-level attributes:
25
26
```typescript { .api }
27
enum LangfuseOtelSpanAttributes {
28
/** Trace name attribute key */
29
TRACE_NAME = "langfuse.trace.name",
30
31
/** User ID attribute key (OpenTelemetry standard) */
32
TRACE_USER_ID = "user.id",
33
34
/** Session ID attribute key (OpenTelemetry standard) */
35
TRACE_SESSION_ID = "session.id",
36
37
/** Trace tags attribute key */
38
TRACE_TAGS = "langfuse.trace.tags",
39
40
/** Trace public visibility attribute key */
41
TRACE_PUBLIC = "langfuse.trace.public",
42
43
/** Trace metadata prefix key */
44
TRACE_METADATA = "langfuse.trace.metadata",
45
46
/** Trace input attribute key */
47
TRACE_INPUT = "langfuse.trace.input",
48
49
/** Trace output attribute key */
50
TRACE_OUTPUT = "langfuse.trace.output",
51
}
52
```
53
54
### Observation Attributes
55
56
Constants for observation-level attributes:
57
58
```typescript { .api }
59
enum LangfuseOtelSpanAttributes {
60
/** Observation type attribute key */
61
OBSERVATION_TYPE = "langfuse.observation.type",
62
63
/** Observation metadata prefix key */
64
OBSERVATION_METADATA = "langfuse.observation.metadata",
65
66
/** Observation severity level attribute key */
67
OBSERVATION_LEVEL = "langfuse.observation.level",
68
69
/** Observation status message attribute key */
70
OBSERVATION_STATUS_MESSAGE = "langfuse.observation.status_message",
71
72
/** Observation input attribute key */
73
OBSERVATION_INPUT = "langfuse.observation.input",
74
75
/** Observation output attribute key */
76
OBSERVATION_OUTPUT = "langfuse.observation.output",
77
}
78
```
79
80
### Generation Attributes
81
82
Constants for generation-specific (LLM) attributes:
83
84
```typescript { .api }
85
enum LangfuseOtelSpanAttributes {
86
/** Completion start time attribute key */
87
OBSERVATION_COMPLETION_START_TIME = "langfuse.observation.completion_start_time",
88
89
/** Model name attribute key */
90
OBSERVATION_MODEL = "langfuse.observation.model.name",
91
92
/** Model parameters attribute key */
93
OBSERVATION_MODEL_PARAMETERS = "langfuse.observation.model.parameters",
94
95
/** Usage details attribute key */
96
OBSERVATION_USAGE_DETAILS = "langfuse.observation.usage_details",
97
98
/** Cost details attribute key */
99
OBSERVATION_COST_DETAILS = "langfuse.observation.cost_details",
100
101
/** Prompt name attribute key */
102
OBSERVATION_PROMPT_NAME = "langfuse.observation.prompt.name",
103
104
/** Prompt version attribute key */
105
OBSERVATION_PROMPT_VERSION = "langfuse.observation.prompt.version",
106
}
107
```
108
109
### General Attributes
110
111
Constants for general attributes applicable to both traces and observations:
112
113
```typescript { .api }
114
enum LangfuseOtelSpanAttributes {
115
/** Environment attribute key */
116
ENVIRONMENT = "langfuse.environment",
117
118
/** Release identifier attribute key */
119
RELEASE = "langfuse.release",
120
121
/** Version attribute key */
122
VERSION = "langfuse.version",
123
}
124
```
125
126
### Internal Attributes
127
128
Constants for internal use:
129
130
```typescript { .api }
131
enum LangfuseOtelSpanAttributes {
132
/** Internal flag for root span marking */
133
AS_ROOT = "langfuse.internal.as_root",
134
}
135
```
136
137
### Compatibility Attributes
138
139
Legacy attribute keys maintained for backward compatibility:
140
141
```typescript { .api }
142
enum LangfuseOtelSpanAttributes {
143
/** Legacy user ID attribute key */
144
TRACE_COMPAT_USER_ID = "langfuse.user.id",
145
146
/** Legacy session ID attribute key */
147
TRACE_COMPAT_SESSION_ID = "langfuse.session.id",
148
}
149
```
150
151
## When to Use
152
153
### Typical Usage (Recommended)
154
155
Use the high-level Langfuse functions which handle attribute keys automatically:
156
157
```typescript
158
import { startObservation } from '@langfuse/tracing';
159
160
// Recommended: Use high-level API
161
const span = startObservation('my-operation', {
162
input: { userId: '123' },
163
metadata: { source: 'api' }
164
});
165
166
span.updateTrace({
167
userId: 'user-123',
168
sessionId: 'session-456'
169
});
170
```
171
172
### Advanced Usage (Direct OpenTelemetry)
173
174
Use attribute constants when working directly with OpenTelemetry spans:
175
176
```typescript
177
import { LangfuseOtelSpanAttributes } from '@langfuse/tracing';
178
import { trace } from '@opentelemetry/api';
179
180
// Advanced: Direct OpenTelemetry span manipulation
181
const activeSpan = trace.getActiveSpan();
182
183
if (activeSpan) {
184
// Set Langfuse-specific attributes directly
185
activeSpan.setAttributes({
186
[LangfuseOtelSpanAttributes.TRACE_USER_ID]: 'user-123',
187
[LangfuseOtelSpanAttributes.OBSERVATION_LEVEL]: 'DEFAULT',
188
[LangfuseOtelSpanAttributes.ENVIRONMENT]: 'production'
189
});
190
}
191
```
192
193
### Custom Span Processor
194
195
Use constants when implementing custom OpenTelemetry span processors:
196
197
```typescript
198
import { LangfuseOtelSpanAttributes } from '@langfuse/tracing';
199
import { SpanProcessor, ReadableSpan } from '@opentelemetry/sdk-trace-base';
200
201
class CustomSpanProcessor implements SpanProcessor {
202
onStart(span: Span): void {
203
// Add default environment to all spans
204
span.setAttribute(
205
LangfuseOtelSpanAttributes.ENVIRONMENT,
206
process.env.NODE_ENV || 'development'
207
);
208
}
209
210
onEnd(span: ReadableSpan): void {
211
const attributes = span.attributes;
212
213
// Read Langfuse-specific attributes
214
const userId = attributes[LangfuseOtelSpanAttributes.TRACE_USER_ID];
215
const observationType = attributes[LangfuseOtelSpanAttributes.OBSERVATION_TYPE];
216
217
// Custom processing logic
218
if (observationType === 'generation') {
219
const model = attributes[LangfuseOtelSpanAttributes.OBSERVATION_MODEL];
220
console.log(`LLM call with model: ${model}`);
221
}
222
}
223
224
forceFlush(): Promise<void> {
225
return Promise.resolve();
226
}
227
228
shutdown(): Promise<void> {
229
return Promise.resolve();
230
}
231
}
232
```
233
234
## Metadata Attribute Keys
235
236
Metadata attributes use a dot-notation naming convention:
237
238
```typescript
239
// Metadata is flattened with dot notation
240
// For observation metadata:
241
// { metadata: { database: { host: 'localhost', port: 5432 } } }
242
// becomes:
243
// {
244
// 'langfuse.observation.metadata.database.host': 'localhost',
245
// 'langfuse.observation.metadata.database.port': '5432'
246
// }
247
248
// For trace metadata:
249
// { metadata: { apiVersion: '2.1.0' } }
250
// becomes:
251
// {
252
// 'langfuse.trace.metadata.apiVersion': '2.1.0'
253
// }
254
```
255
256
The `TRACE_METADATA` and `OBSERVATION_METADATA` constants provide the base prefix for all metadata keys. Individual metadata fields are appended with dot notation.
257
258
## OpenTelemetry Standard Attributes
259
260
Langfuse uses OpenTelemetry semantic conventions where applicable:
261
262
**User ID**: Uses the standard OpenTelemetry `user.id` attribute key rather than a custom Langfuse-specific key, ensuring compatibility with other OpenTelemetry tools.
263
264
**Session ID**: Uses the standard OpenTelemetry `session.id` attribute key for consistency with the broader ecosystem.
265
266
For attributes without established semantic conventions, Langfuse uses the `langfuse.*` namespace.
267
268
## Best Practices
269
270
### Prefer High-Level APIs
271
272
```typescript
273
// Good: Use high-level API
274
import { updateActiveTrace } from '@langfuse/tracing';
275
276
updateActiveTrace({
277
userId: 'user-123',
278
environment: 'production'
279
});
280
281
// Avoid: Direct attribute manipulation (unless necessary)
282
import { LangfuseOtelSpanAttributes } from '@langfuse/tracing';
283
import { trace } from '@opentelemetry/api';
284
285
trace.getActiveSpan()?.setAttributes({
286
[LangfuseOtelSpanAttributes.TRACE_USER_ID]: 'user-123',
287
[LangfuseOtelSpanAttributes.ENVIRONMENT]: 'production'
288
});
289
```
290
291
### Use Constants for Type Safety
292
293
```typescript
294
// Good: Use enum constants
295
activeSpan.setAttribute(
296
LangfuseOtelSpanAttributes.OBSERVATION_LEVEL,
297
'ERROR'
298
);
299
300
// Avoid: Magic strings
301
activeSpan.setAttribute('langfuse.observation.level', 'ERROR');
302
```
303
304
### Check Span Existence
305
306
```typescript
307
import { trace } from '@opentelemetry/api';
308
import { LangfuseOtelSpanAttributes } from '@langfuse/tracing';
309
310
const span = trace.getActiveSpan();
311
312
if (span) {
313
span.setAttribute(
314
LangfuseOtelSpanAttributes.ENVIRONMENT,
315
'production'
316
);
317
} else {
318
console.warn('No active span found');
319
}
320
```
321