0
# Performance Monitoring and Tracing
1
2
OpenTelemetry-based performance monitoring with spans, traces, and distributed tracing support.
3
4
## Capabilities
5
6
### Span Creation and Management
7
8
Create and manage performance monitoring spans.
9
10
```typescript { .api }
11
/**
12
* Start a new span and execute a callback within its context
13
* @param context - Span configuration options
14
* @param callback - Function to execute within the span
15
* @returns Return value of the callback function
16
*/
17
function startSpan<T>(context: StartSpanOptions, callback: (span: Span) => T): T;
18
19
/**
20
* Start a span manually with callback-based control
21
* @param context - Span configuration options
22
* @param callback - Function to execute with span and finish function
23
* @returns Return value of the callback function
24
*/
25
function startSpanManual<T>(context: StartSpanOptions, callback: (span: Span, finish: () => void) => T): T;
26
27
/**
28
* Start an inactive span that won't be automatically set as active
29
* @param context - Span configuration options
30
* @returns Inactive span instance
31
*/
32
function startInactiveSpan(context: StartSpanOptions): Span;
33
```
34
35
**Usage Examples:**
36
37
```typescript
38
import * as Sentry from "@sentry/node";
39
40
// Basic span with callback
41
const result = Sentry.startSpan(
42
{ name: "database-query", op: "db.query" },
43
(span) => {
44
span.setAttribute("db.query", "SELECT * FROM users");
45
span.setAttribute("db.rows", 150);
46
return database.query("SELECT * FROM users");
47
}
48
);
49
50
// Manual span management with callback
51
const result = Sentry.startSpanManual({
52
name: "file-processing",
53
op: "file.process",
54
attributes: {
55
"file.name": fileName,
56
"file.size": fileSize,
57
},
58
}, (span, finish) => {
59
try {
60
const result = processFile(fileName);
61
span.setStatus({ code: 1 }); // OK
62
return result;
63
} catch (error) {
64
span.setStatus({ code: 2, message: error.message }); // ERROR
65
throw error;
66
} finally {
67
finish(); // Ends the span
68
}
69
});
70
71
// Inactive span for custom timing
72
const inactiveSpan = Sentry.startInactiveSpan({
73
name: "background-task",
74
op: "task.background",
75
});
76
// Span exists but isn't active in the context
77
setTimeout(() => {
78
inactiveSpan.end();
79
}, 5000);
80
```
81
82
### Active Span Management
83
84
Work with the currently active span.
85
86
```typescript { .api }
87
/**
88
* Get the currently active span
89
* @returns Active span or undefined if no span is active
90
*/
91
function getActiveSpan(): Span | undefined;
92
93
/**
94
* Execute a callback with a specific span as active
95
* @param span - Span to set as active (or null to clear active span)
96
* @param callback - Function to execute with the active span and scope
97
* @returns Return value of the callback function
98
*/
99
function withActiveSpan<T>(span: Span | null, callback: (scope: Scope) => T): T;
100
```
101
102
**Usage Examples:**
103
104
```typescript
105
import * as Sentry from "@sentry/node";
106
107
// Get current active span
108
const activeSpan = Sentry.getActiveSpan();
109
if (activeSpan) {
110
activeSpan.setAttribute("custom.metric", 42);
111
activeSpan.addEvent("Processing started");
112
}
113
114
// Execute with specific active span
115
const parentSpan = Sentry.startSpanManual({ name: "parent-operation" });
116
117
Sentry.withActiveSpan(parentSpan, (scope) => {
118
// Child spans created here will use parentSpan as parent
119
Sentry.startSpan({ name: "child-operation" }, () => {
120
// This span will be a child of parentSpan
121
performChildOperation();
122
});
123
});
124
125
parentSpan.end();
126
127
// Execute with no active span
128
Sentry.withActiveSpan(null, (scope) => {
129
// Code here runs without an active span
130
performIndependentOperation();
131
});
132
```
133
134
### Trace Management
135
136
Manage traces and distributed tracing.
137
138
```typescript { .api }
139
/**
140
* Start a new trace (root span)
141
* @param callback - Function to execute in the new trace
142
* @returns Return value of the callback function
143
*/
144
function startNewTrace<T>(callback: () => T): T;
145
146
/**
147
* Continue a distributed trace from trace data
148
* @param tracingData - Trace propagation data
149
* @param callback - Function to execute in the continued trace
150
* @returns Return value of the callback function
151
*/
152
function continueTrace<T>(tracingData: TracingData, callback: () => T): T;
153
154
/**
155
* Get trace propagation data for the current trace
156
* @returns Trace data for propagating to downstream services
157
*/
158
function getTraceData(): TraceData;
159
160
/**
161
* Get trace meta tags for HTML injection
162
* @returns HTML meta tags string for trace propagation
163
*/
164
function getTraceMetaTags(): string;
165
```
166
167
**Usage Examples:**
168
169
```typescript
170
import * as Sentry from "@sentry/node";
171
import express from "express";
172
173
// Start a new trace
174
const result = Sentry.startNewTrace(() => {
175
// This creates a new root span
176
return Sentry.startSpan({ name: "background-job" }, () => {
177
return processBackgroundJob();
178
});
179
});
180
181
// Continue trace from incoming request
182
app.use((req, res, next) => {
183
const tracingData = {
184
"sentry-trace": req.headers["sentry-trace"],
185
baggage: req.headers.baggage,
186
};
187
188
Sentry.continueTrace(tracingData, () => {
189
Sentry.startSpan({ name: `${req.method} ${req.path}` }, () => {
190
next();
191
});
192
});
193
});
194
195
// Get trace data for outgoing requests
196
function makeApiCall(url) {
197
const traceData = Sentry.getTraceData();
198
199
return fetch(url, {
200
headers: {
201
"sentry-trace": traceData["sentry-trace"],
202
baggage: traceData.baggage || "",
203
},
204
});
205
}
206
207
// Inject trace meta tags in HTML response
208
app.get("/", (req, res) => {
209
const metaTags = Sentry.getTraceMetaTags();
210
res.send(`
211
<html>
212
<head>
213
${metaTags}
214
</head>
215
<body>Content here</body>
216
</html>
217
`);
218
});
219
```
220
221
### Span Utilities
222
223
Utility functions for working with spans.
224
225
```typescript { .api }
226
/**
227
* Convert a span to JSON representation
228
* @param span - Span to convert
229
* @returns JSON representation of the span
230
*/
231
function spanToJSON(span: Span): SpanJSON;
232
233
/**
234
* Get trace header from a span
235
* @param span - Span to get header from
236
* @returns Sentry trace header string
237
*/
238
function spanToTraceHeader(span: Span): string;
239
240
/**
241
* Get baggage header from a span
242
* @param span - Span to get baggage from
243
* @returns Baggage header string
244
*/
245
function spanToBaggageHeader(span: Span): string;
246
247
/**
248
* Update the name of a span
249
* @param span - Span to update
250
* @param name - New span name
251
*/
252
function updateSpanName(span: Span, name: string): void;
253
254
/**
255
* Get all descendant spans of a span
256
* @param span - Parent span
257
* @returns Array of descendant spans
258
*/
259
function getSpanDescendants(span: Span): Span[];
260
261
/**
262
* Get the root span of a span hierarchy
263
* @param span - Span to find root for (optional, uses active span if not provided)
264
* @returns Root span or undefined
265
*/
266
function getRootSpan(span?: Span): Span | undefined;
267
```
268
269
**Usage Examples:**
270
271
```typescript
272
import * as Sentry from "@sentry/node";
273
274
// Convert span to JSON for logging
275
const span = Sentry.getActiveSpan();
276
if (span) {
277
const spanData = Sentry.spanToJSON(span);
278
console.log("Span data:", spanData);
279
}
280
281
// Get headers for outgoing requests
282
function addTracingHeaders(span, headers) {
283
if (span) {
284
headers["sentry-trace"] = Sentry.spanToTraceHeader(span);
285
headers.baggage = Sentry.spanToBaggageHeader(span);
286
}
287
return headers;
288
}
289
290
// Update span name based on route
291
function updateSpanForRoute(span, route) {
292
if (span) {
293
Sentry.updateSpanName(span, `${req.method} ${route}`);
294
}
295
}
296
297
// Get all child spans for debugging
298
function debugSpanHierarchy(rootSpan) {
299
const descendants = Sentry.getSpanDescendants(rootSpan);
300
console.log(`Root span has ${descendants.length} descendants`);
301
302
descendants.forEach((span, index) => {
303
const spanData = Sentry.spanToJSON(span);
304
console.log(`Child ${index}:`, spanData.description);
305
});
306
}
307
```
308
309
### Tracing Control
310
311
Control tracing behavior and suppress instrumentation.
312
313
```typescript { .api }
314
/**
315
* Execute a callback without tracing
316
* @param callback - Function to execute without tracing
317
* @returns Return value of the callback function
318
*/
319
function suppressTracing<T>(callback: () => T): T;
320
```
321
322
**Usage Examples:**
323
324
```typescript
325
import * as Sentry from "@sentry/node";
326
327
// Suppress tracing for sensitive operations
328
const sensitiveResult = Sentry.suppressTracing(() => {
329
// This code won't create spans or traces
330
return performSensitiveOperation();
331
});
332
333
// Suppress tracing for internal health checks
334
function healthCheck() {
335
return Sentry.suppressTracing(() => {
336
// Health check calls won't appear in traces
337
return {
338
database: checkDatabase(),
339
cache: checkCache(),
340
external_api: checkExternalApi(),
341
};
342
});
343
}
344
345
// Suppress tracing for high-frequency operations
346
function logMetrics() {
347
return Sentry.suppressTracing(() => {
348
// Don't trace metric collection to avoid noise
349
collectAndSendMetrics();
350
});
351
}
352
```
353
354
## Types
355
356
### Span Options and Configuration
357
358
```typescript { .api }
359
interface StartSpanOptions {
360
/** Span name/description */
361
name: string;
362
/** Span attributes/tags */
363
attributes?: Record<string, any>;
364
/** Span start time (timestamp in milliseconds) */
365
startTime?: number;
366
/** Parent span (optional, uses active span if not provided) */
367
parentSpan?: Span;
368
/** Scope to use for the span */
369
scope?: Scope;
370
/** Only create span if there's a parent span */
371
onlyIfParent?: boolean;
372
/** Force this span to be a transaction */
373
forceTransaction?: boolean;
374
/** Span operation type */
375
op?: string;
376
/** Span origin */
377
origin?: string;
378
}
379
```
380
381
### Span Interface
382
383
```typescript { .api }
384
interface Span {
385
/** Get span context information */
386
spanContext(): SpanContext;
387
388
/** Set a single attribute */
389
setAttribute(key: string, value: any): Span;
390
391
/** Set multiple attributes */
392
setAttributes(attributes: Record<string, any>): Span;
393
394
/** Set span status */
395
setStatus(status: SpanStatus): Span;
396
397
/** Update span name */
398
updateName(name: string): Span;
399
400
/** Add an event to the span */
401
addEvent(name: string, attributes?: Record<string, any>): Span;
402
403
/** End the span */
404
end(endTime?: number): void;
405
406
/** Check if span is recording */
407
isRecording(): boolean;
408
409
/** Record an exception on the span */
410
recordException(exception: Exception): void;
411
}
412
413
interface SpanContext {
414
/** Trace ID */
415
traceId: string;
416
/** Span ID */
417
spanId: string;
418
/** Trace flags */
419
traceFlags: number;
420
/** Trace state */
421
traceState?: string;
422
}
423
424
interface SpanStatus {
425
/** Status code (0=unset, 1=ok, 2=error) */
426
code: number;
427
/** Optional status message */
428
message?: string;
429
}
430
```
431
432
### Trace Data Types
433
434
```typescript { .api }
435
interface TraceData {
436
/** Sentry trace header */
437
"sentry-trace": string;
438
/** Baggage header (optional) */
439
baggage?: string;
440
}
441
442
interface TracingData {
443
/** Sentry trace header */
444
"sentry-trace"?: string;
445
/** Baggage header */
446
baggage?: string;
447
}
448
449
interface SpanJSON {
450
/** Span description */
451
description?: string;
452
/** Span ID */
453
span_id: string;
454
/** Parent span ID */
455
parent_span_id?: string;
456
/** Trace ID */
457
trace_id: string;
458
/** Span operation */
459
op?: string;
460
/** Span origin */
461
origin?: string;
462
/** Span status */
463
status?: string;
464
/** Span tags */
465
tags?: Record<string, any>;
466
/** Span data */
467
data?: Record<string, any>;
468
/** Start timestamp */
469
start_timestamp: number;
470
/** End timestamp */
471
timestamp?: number;
472
}
473
```
474
475
### Exception Type
476
477
```typescript { .api }
478
interface Exception {
479
/** Exception type */
480
type?: string;
481
/** Exception value/message */
482
value?: string;
483
/** Exception mechanism */
484
mechanism?: {
485
type?: string;
486
handled?: boolean;
487
data?: Record<string, any>;
488
};
489
/** Exception stacktrace */
490
stacktrace?: Stacktrace;
491
}
492
```