Sentry Node SDK using OpenTelemetry for comprehensive error tracking and performance monitoring in Node.js applications
—
Built-in support for cron job monitoring and session tracking.
Monitor cron jobs and scheduled tasks with automatic check-ins.
/**
* Execute a function with monitor tracking and automatic check-ins
* @param monitorSlug - Unique identifier for the monitor
* @param callback - Function to execute
* @param upsertMonitorConfig - Optional monitor configuration
* @returns Return value of the callback function
*/
function withMonitor<T>(
monitorSlug: string,
callback: () => T,
upsertMonitorConfig?: MonitorConfig
): T;
/**
* Manually capture a cron check-in
* @param checkIn - Check-in data object
* @param upsertMonitorConfig - Optional monitor configuration
* @returns Event ID of the captured check-in
*/
function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorConfig): string;Usage Examples:
import * as Sentry from "@sentry/node";
// Monitor a cron job with automatic check-ins
const result = Sentry.withMonitor("daily-cleanup", () => {
console.log("Running daily cleanup...");
cleanupOldFiles();
processExpiredData();
generateReports();
return { processed: 1000, cleaned: 50 };
}, {
// Optional: specify expected schedule for more accurate monitoring
schedule: {
type: "crontab",
value: "0 2 * * *", // Daily at 2 AM
},
checkin_margin: 300, // 5 minutes margin
max_runtime: 3600, // 1 hour max runtime
});
// Monitor with error handling
Sentry.withMonitor("backup-task", () => {
try {
performBackup();
console.log("Backup completed successfully");
} catch (error) {
console.error("Backup failed:", error);
throw error; // Will be captured as a failed check-in
}
});
// Manual check-in management
const checkInId = Sentry.captureCheckIn({
monitorSlug: "manual-task",
status: "in_progress",
}, {
schedule: {
type: "crontab",
value: "0 0 * * MON", // Weekly on Monday
},
checkin_margin: 300, // 5 minutes margin
max_runtime: 3600, // 1 hour max runtime
});
try {
performWeeklyTask();
// Mark as successful
Sentry.captureCheckIn({
monitorSlug: "manual-task",
check_in_id: checkInId,
status: "ok",
});
} catch (error) {
// Mark as failed
Sentry.captureCheckIn({
monitorSlug: "manual-task",
check_in_id: checkInId,
status: "error",
});
throw error;
}Track user sessions for release health monitoring.
/**
* Start a new session
* @param context - Session context data
* @returns Session instance
*/
function startSession(context?: SessionContext): Session;
/**
* Capture the current session
* @param endSession - Whether to end the session after capturing
*/
function captureSession(endSession?: boolean): void;
/**
* End the current session
*/
function endSession(): void;Usage Examples:
import * as Sentry from "@sentry/node";
// Start a session for a user request
function handleUserRequest(req, res) {
const session = Sentry.startSession({
user: { id: req.user.id },
environment: "production",
});
try {
processRequest(req);
res.json({ success: true });
// Session will be marked as healthy
} catch (error) {
// Session will be marked as errored
throw error;
} finally {
Sentry.endSession();
}
}
// Background job session tracking
function runBackgroundJob() {
Sentry.startSession({
release: process.env.APP_VERSION,
environment: process.env.NODE_ENV,
});
try {
performBackgroundWork();
console.log("Background job completed");
} catch (error) {
console.error("Background job failed:", error);
throw error;
} finally {
Sentry.captureSession(true); // End session after capturing
}
}
// Long-running process session management
function startLongRunningProcess() {
Sentry.startSession();
// Periodically capture session health
setInterval(() => {
Sentry.captureSession(false); // Don't end session, just report health
}, 60000); // Every minute
process.on("SIGTERM", () => {
console.log("Process terminating, ending session");
Sentry.endSession();
process.exit(0);
});
}CPU profiling for performance analysis.
/**
* Start CPU profiling session
*/
function startProfiling(): void;
/**
* Stop CPU profiling session and return profile data
* @returns Profile data or null if profiling wasn't active
*/
function stopProfiling(): Profile | null;Usage Examples:
import * as Sentry from "@sentry/node";
// Profile a specific operation
function profiledOperation() {
Sentry.profiler.startProfiling();
try {
// Perform CPU-intensive work
performComplexCalculation();
processLargeDataset();
const profile = Sentry.profiler.stopProfiling();
if (profile) {
console.log("Profiling data captured");
}
} catch (error) {
Sentry.profiler.stopProfiling(); // Stop profiling even on error
throw error;
}
}
// Profile with automatic cleanup
function profileWithCleanup<T>(callback: () => T): T {
Sentry.profiler.startProfiling();
try {
return callback();
} finally {
const profile = Sentry.profiler.stopProfiling();
if (profile) {
console.log("Profile captured for operation");
}
}
}For existing cron libraries, use instrumentation functions to add Sentry monitoring:
/**
* Instrument a generic cron library constructor
* @param OriginalCron - Original cron constructor
* @param monitorSlug - Monitor identifier
* @returns Instrumented cron constructor
*/
function instrumentCron<T>(OriginalCron: T, monitorSlug: string): T;
/**
* Instrument node-cron library
* @param nodeCron - node-cron library
* @returns Instrumented node-cron library
*/
function instrumentNodeCron<T>(nodeCron: T): T;
/**
* Instrument node-schedule library
* @param nodeSchedule - node-schedule library
* @returns Instrumented node-schedule library
*/
function instrumentNodeSchedule<T>(nodeSchedule: T): T;These functions are available through the cron namespace:
import * as Sentry from "@sentry/node";
// Instrument existing cron libraries
const CronJobWithSentry = Sentry.cron.instrumentCron(CronJob, "my-cron-job");
const cronWithSentry = Sentry.cron.instrumentNodeCron(require("node-cron"));
const scheduleWithSentry = Sentry.cron.instrumentNodeSchedule(require("node-schedule"));interface MonitorConfig {
/** Cron schedule */
schedule?: Schedule;
/** Timezone for the schedule */
timezone?: string;
/** Check-in margin in seconds */
checkin_margin?: number;
/** Maximum runtime in seconds */
max_runtime?: number;
/** Failure issue threshold */
failure_issue_threshold?: number;
/** Recovery threshold */
recovery_threshold?: number;
}
interface Schedule {
/** Schedule type */
type: "crontab" | "interval";
/** Schedule value (cron expression or interval) */
value: string;
/** Unit for interval schedules */
unit?: "minute" | "hour" | "day" | "week" | "month";
}
interface CheckIn {
/** Check-in ID (generated automatically) */
check_in_id?: string;
/** Check-in status */
status: "in_progress" | "ok" | "error";
/** Check-in duration in seconds */
duration?: number;
/** Monitor configuration for this check-in */
monitor_config?: MonitorConfig;
}interface Session {
/** Session ID */
sid: string;
/** Session status */
status: SessionStatus;
/** Session start time */
started: Date;
/** Session duration */
duration?: number;
/** Number of errors in session */
errors: number;
/** User information */
user?: User;
/** Release version */
release?: string;
/** Environment */
environment?: string;
}
interface SessionContext {
/** User information */
user?: User;
/** Release version */
release?: string;
/** Environment */
environment?: string;
/** Initial session status */
status?: SessionStatus;
}
type SessionStatus = "ok" | "exited" | "crashed" | "abnormal";interface Profile {
/** Profile ID */
profile_id: string;
/** Profiling data */
data: ProfileData;
/** Profile start time */
start_time: number;
/** Profile end time */
end_time: number;
/** Profile duration */
duration: number;
}
interface ProfileData {
/** CPU samples */
samples: ProfileSample[];
/** Stack traces */
stacks: ProfileStack[];
/** Frame information */
frames: ProfileFrame[];
}
interface ProfileSample {
/** Stack ID */
stack_id: number;
/** Thread ID */
thread_id: string;
/** Elapsed time */
elapsed_since_start_ns: number;
}
interface ProfileStack {
/** Frame IDs in the stack */
frame_ids: number[];
}
interface ProfileFrame {
/** Function name */
function?: string;
/** File name */
filename?: string;
/** Line number */
lineno?: number;
/** Column number */
colno?: number;
}Install with Tessl CLI
npx tessl i tessl/npm-sentry--node