Sentry Node SDK using OpenTelemetry for comprehensive error tracking and performance monitoring in Node.js applications
—
OpenTelemetry-based performance monitoring with spans, traces, and distributed tracing support.
Create and manage performance monitoring spans.
/**
* Start a new span and execute a callback within its context
* @param context - Span configuration options
* @param callback - Function to execute within the span
* @returns Return value of the callback function
*/
function startSpan<T>(context: StartSpanOptions, callback: (span: Span) => T): T;
/**
* Start a span manually with callback-based control
* @param context - Span configuration options
* @param callback - Function to execute with span and finish function
* @returns Return value of the callback function
*/
function startSpanManual<T>(context: StartSpanOptions, callback: (span: Span, finish: () => void) => T): T;
/**
* Start an inactive span that won't be automatically set as active
* @param context - Span configuration options
* @returns Inactive span instance
*/
function startInactiveSpan(context: StartSpanOptions): Span;Usage Examples:
import * as Sentry from "@sentry/node";
// Basic span with callback
const result = Sentry.startSpan(
{ name: "database-query", op: "db.query" },
(span) => {
span.setAttribute("db.query", "SELECT * FROM users");
span.setAttribute("db.rows", 150);
return database.query("SELECT * FROM users");
}
);
// Manual span management with callback
const result = Sentry.startSpanManual({
name: "file-processing",
op: "file.process",
attributes: {
"file.name": fileName,
"file.size": fileSize,
},
}, (span, finish) => {
try {
const result = processFile(fileName);
span.setStatus({ code: 1 }); // OK
return result;
} catch (error) {
span.setStatus({ code: 2, message: error.message }); // ERROR
throw error;
} finally {
finish(); // Ends the span
}
});
// Inactive span for custom timing
const inactiveSpan = Sentry.startInactiveSpan({
name: "background-task",
op: "task.background",
});
// Span exists but isn't active in the context
setTimeout(() => {
inactiveSpan.end();
}, 5000);Work with the currently active span.
/**
* Get the currently active span
* @returns Active span or undefined if no span is active
*/
function getActiveSpan(): Span | undefined;
/**
* Execute a callback with a specific span as active
* @param span - Span to set as active (or null to clear active span)
* @param callback - Function to execute with the active span and scope
* @returns Return value of the callback function
*/
function withActiveSpan<T>(span: Span | null, callback: (scope: Scope) => T): T;Usage Examples:
import * as Sentry from "@sentry/node";
// Get current active span
const activeSpan = Sentry.getActiveSpan();
if (activeSpan) {
activeSpan.setAttribute("custom.metric", 42);
activeSpan.addEvent("Processing started");
}
// Execute with specific active span
const parentSpan = Sentry.startSpanManual({ name: "parent-operation" });
Sentry.withActiveSpan(parentSpan, (scope) => {
// Child spans created here will use parentSpan as parent
Sentry.startSpan({ name: "child-operation" }, () => {
// This span will be a child of parentSpan
performChildOperation();
});
});
parentSpan.end();
// Execute with no active span
Sentry.withActiveSpan(null, (scope) => {
// Code here runs without an active span
performIndependentOperation();
});Manage traces and distributed tracing.
/**
* Start a new trace (root span)
* @param callback - Function to execute in the new trace
* @returns Return value of the callback function
*/
function startNewTrace<T>(callback: () => T): T;
/**
* Continue a distributed trace from trace data
* @param tracingData - Trace propagation data
* @param callback - Function to execute in the continued trace
* @returns Return value of the callback function
*/
function continueTrace<T>(tracingData: TracingData, callback: () => T): T;
/**
* Get trace propagation data for the current trace
* @returns Trace data for propagating to downstream services
*/
function getTraceData(): TraceData;
/**
* Get trace meta tags for HTML injection
* @returns HTML meta tags string for trace propagation
*/
function getTraceMetaTags(): string;Usage Examples:
import * as Sentry from "@sentry/node";
import express from "express";
// Start a new trace
const result = Sentry.startNewTrace(() => {
// This creates a new root span
return Sentry.startSpan({ name: "background-job" }, () => {
return processBackgroundJob();
});
});
// Continue trace from incoming request
app.use((req, res, next) => {
const tracingData = {
"sentry-trace": req.headers["sentry-trace"],
baggage: req.headers.baggage,
};
Sentry.continueTrace(tracingData, () => {
Sentry.startSpan({ name: `${req.method} ${req.path}` }, () => {
next();
});
});
});
// Get trace data for outgoing requests
function makeApiCall(url) {
const traceData = Sentry.getTraceData();
return fetch(url, {
headers: {
"sentry-trace": traceData["sentry-trace"],
baggage: traceData.baggage || "",
},
});
}
// Inject trace meta tags in HTML response
app.get("/", (req, res) => {
const metaTags = Sentry.getTraceMetaTags();
res.send(`
<html>
<head>
${metaTags}
</head>
<body>Content here</body>
</html>
`);
});Utility functions for working with spans.
/**
* Convert a span to JSON representation
* @param span - Span to convert
* @returns JSON representation of the span
*/
function spanToJSON(span: Span): SpanJSON;
/**
* Get trace header from a span
* @param span - Span to get header from
* @returns Sentry trace header string
*/
function spanToTraceHeader(span: Span): string;
/**
* Get baggage header from a span
* @param span - Span to get baggage from
* @returns Baggage header string
*/
function spanToBaggageHeader(span: Span): string;
/**
* Update the name of a span
* @param span - Span to update
* @param name - New span name
*/
function updateSpanName(span: Span, name: string): void;
/**
* Get all descendant spans of a span
* @param span - Parent span
* @returns Array of descendant spans
*/
function getSpanDescendants(span: Span): Span[];
/**
* Get the root span of a span hierarchy
* @param span - Span to find root for (optional, uses active span if not provided)
* @returns Root span or undefined
*/
function getRootSpan(span?: Span): Span | undefined;Usage Examples:
import * as Sentry from "@sentry/node";
// Convert span to JSON for logging
const span = Sentry.getActiveSpan();
if (span) {
const spanData = Sentry.spanToJSON(span);
console.log("Span data:", spanData);
}
// Get headers for outgoing requests
function addTracingHeaders(span, headers) {
if (span) {
headers["sentry-trace"] = Sentry.spanToTraceHeader(span);
headers.baggage = Sentry.spanToBaggageHeader(span);
}
return headers;
}
// Update span name based on route
function updateSpanForRoute(span, route) {
if (span) {
Sentry.updateSpanName(span, `${req.method} ${route}`);
}
}
// Get all child spans for debugging
function debugSpanHierarchy(rootSpan) {
const descendants = Sentry.getSpanDescendants(rootSpan);
console.log(`Root span has ${descendants.length} descendants`);
descendants.forEach((span, index) => {
const spanData = Sentry.spanToJSON(span);
console.log(`Child ${index}:`, spanData.description);
});
}Control tracing behavior and suppress instrumentation.
/**
* Execute a callback without tracing
* @param callback - Function to execute without tracing
* @returns Return value of the callback function
*/
function suppressTracing<T>(callback: () => T): T;Usage Examples:
import * as Sentry from "@sentry/node";
// Suppress tracing for sensitive operations
const sensitiveResult = Sentry.suppressTracing(() => {
// This code won't create spans or traces
return performSensitiveOperation();
});
// Suppress tracing for internal health checks
function healthCheck() {
return Sentry.suppressTracing(() => {
// Health check calls won't appear in traces
return {
database: checkDatabase(),
cache: checkCache(),
external_api: checkExternalApi(),
};
});
}
// Suppress tracing for high-frequency operations
function logMetrics() {
return Sentry.suppressTracing(() => {
// Don't trace metric collection to avoid noise
collectAndSendMetrics();
});
}interface StartSpanOptions {
/** Span name/description */
name: string;
/** Span attributes/tags */
attributes?: Record<string, any>;
/** Span start time (timestamp in milliseconds) */
startTime?: number;
/** Parent span (optional, uses active span if not provided) */
parentSpan?: Span;
/** Scope to use for the span */
scope?: Scope;
/** Only create span if there's a parent span */
onlyIfParent?: boolean;
/** Force this span to be a transaction */
forceTransaction?: boolean;
/** Span operation type */
op?: string;
/** Span origin */
origin?: string;
}interface Span {
/** Get span context information */
spanContext(): SpanContext;
/** Set a single attribute */
setAttribute(key: string, value: any): Span;
/** Set multiple attributes */
setAttributes(attributes: Record<string, any>): Span;
/** Set span status */
setStatus(status: SpanStatus): Span;
/** Update span name */
updateName(name: string): Span;
/** Add an event to the span */
addEvent(name: string, attributes?: Record<string, any>): Span;
/** End the span */
end(endTime?: number): void;
/** Check if span is recording */
isRecording(): boolean;
/** Record an exception on the span */
recordException(exception: Exception): void;
}
interface SpanContext {
/** Trace ID */
traceId: string;
/** Span ID */
spanId: string;
/** Trace flags */
traceFlags: number;
/** Trace state */
traceState?: string;
}
interface SpanStatus {
/** Status code (0=unset, 1=ok, 2=error) */
code: number;
/** Optional status message */
message?: string;
}interface TraceData {
/** Sentry trace header */
"sentry-trace": string;
/** Baggage header (optional) */
baggage?: string;
}
interface TracingData {
/** Sentry trace header */
"sentry-trace"?: string;
/** Baggage header */
baggage?: string;
}
interface SpanJSON {
/** Span description */
description?: string;
/** Span ID */
span_id: string;
/** Parent span ID */
parent_span_id?: string;
/** Trace ID */
trace_id: string;
/** Span operation */
op?: string;
/** Span origin */
origin?: string;
/** Span status */
status?: string;
/** Span tags */
tags?: Record<string, any>;
/** Span data */
data?: Record<string, any>;
/** Start timestamp */
start_timestamp: number;
/** End timestamp */
timestamp?: number;
}interface Exception {
/** Exception type */
type?: string;
/** Exception value/message */
value?: string;
/** Exception mechanism */
mechanism?: {
type?: string;
handled?: boolean;
data?: Record<string, any>;
};
/** Exception stacktrace */
stacktrace?: Stacktrace;
}Install with Tessl CLI
npx tessl i tessl/npm-sentry--node