Skip to content

Commit

Permalink
feat(core): Add cron monitor wrapper helper (#9395)
Browse files Browse the repository at this point in the history
This PR adds `Sentry.withMonitor`, a wrapping function similar to
`Sentry.startSpan` that wraps a callback with a cron monitor. Under the
hood it uses `Sentry.captureCheckIn`, but having this as a callback
means that users don't have to think about passing `checkInId` around.

```ts
import * as Sentry from '@sentry/node';

// with monitor will send checkin when callback is started/finished
// works with async and sync callbacks.
const result = Sentry.withMonitor(
  'dailyEmail',
  () => {
    // withCheckIn return value is same return value here
    return sendEmail();
  },
  {
    schedule: {
      type: 'crontab',
      value: '0 * * * *',
    },
    // 🇨🇦🫡
    timezone: 'Canada/Eastern',
  },
);
```
  • Loading branch information
AbhiPrasad committed Oct 27, 2023
1 parent 3545fd5 commit 697f406
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 3 deletions.
1 change: 1 addition & 0 deletions packages/astro/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export {
captureEvent,
captureMessage,
captureCheckIn,
withMonitor,
configureScope,
createTransport,
extractTraceparentData,
Expand Down
1 change: 1 addition & 0 deletions packages/bun/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export {
trace,
withScope,
captureCheckIn,
withMonitor,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down
46 changes: 45 additions & 1 deletion packages/core/src/exports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ import type {
EventHint,
Extra,
Extras,
FinishedCheckIn,
MonitorConfig,
Primitive,
Severity,
SeverityLevel,
TransactionContext,
User,
} from '@sentry/types';
import { logger, uuid4 } from '@sentry/utils';
import { isThenable, logger, timestampInSeconds, uuid4 } from '@sentry/utils';

import type { Hub } from './hub';
import { getCurrentHub } from './hub';
Expand Down Expand Up @@ -210,6 +211,49 @@ export function captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorCo
return uuid4();
}

/**
* Wraps a callback with a cron monitor check in. The check in will be sent to Sentry when the callback finishes.
*
* @param monitorSlug The distinct slug of the monitor.
* @param upsertMonitorConfig An optional object that describes a monitor config. Use this if you want
* to create a monitor automatically when sending a check in.
*/
export function withMonitor<T>(
monitorSlug: CheckIn['monitorSlug'],
callback: () => T,
upsertMonitorConfig?: MonitorConfig,
): T {
const checkInId = captureCheckIn({ monitorSlug, status: 'in_progress' }, upsertMonitorConfig);
const now = timestampInSeconds();

function finishCheckIn(status: FinishedCheckIn['status']): void {
captureCheckIn({ monitorSlug, status, checkInId, duration: timestampInSeconds() - now });
}

let maybePromiseResult: T;
try {
maybePromiseResult = callback();
} catch (e) {
finishCheckIn('error');
throw e;
}

if (isThenable(maybePromiseResult)) {
Promise.resolve(maybePromiseResult).then(
() => {
finishCheckIn('ok');
},
() => {
finishCheckIn('error');
},
);
} else {
finishCheckIn('ok');
}

return maybePromiseResult;
}

/**
* Call `flush()` on the current client, if there is one. See {@link Client.flush}.
*
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export * from './tracing';
export {
addBreadcrumb,
captureCheckIn,
withMonitor,
captureException,
captureEvent,
captureMessage,
Expand Down
1 change: 1 addition & 0 deletions packages/deno/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export {
trace,
withScope,
captureCheckIn,
withMonitor,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down
1 change: 1 addition & 0 deletions packages/node-experimental/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export {
trace,
withScope,
captureCheckIn,
withMonitor,
} from '@sentry/node';

export type {
Expand Down
1 change: 1 addition & 0 deletions packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export {
trace,
withScope,
captureCheckIn,
withMonitor,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down
1 change: 1 addition & 0 deletions packages/remix/src/index.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export {
addGlobalEventProcessor,
addBreadcrumb,
captureCheckIn,
withMonitor,
captureException,
captureEvent,
captureMessage,
Expand Down
1 change: 1 addition & 0 deletions packages/serverless/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export {
captureException,
captureMessage,
captureCheckIn,
withMonitor,
configureScope,
createTransport,
getActiveTransaction,
Expand Down
1 change: 1 addition & 0 deletions packages/sveltekit/src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export {
captureEvent,
captureMessage,
captureCheckIn,
withMonitor,
configureScope,
createTransport,
extractTraceparentData,
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/checkin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface SerializedCheckIn {
};
}

interface InProgressCheckIn {
export interface InProgressCheckIn {
// The distinct slug of the monitor.
monitorSlug: SerializedCheckIn['monitor_slug'];
// The status of the check-in.
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,4 +125,4 @@ export type { Instrumenter } from './instrumenter';
export type { HandlerDataFetch, HandlerDataXhr, SentryXhrData, SentryWrappedXMLHttpRequest } from './instrument';

export type { BrowserClientReplayOptions, BrowserClientProfilingOptions } from './browseroptions';
export type { CheckIn, MonitorConfig, SerializedCheckIn } from './checkin';
export type { CheckIn, MonitorConfig, FinishedCheckIn, InProgressCheckIn, SerializedCheckIn } from './checkin';
1 change: 1 addition & 0 deletions packages/vercel-edge/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export {
trace,
withScope,
captureCheckIn,
withMonitor,
setMeasurement,
getActiveSpan,
startSpan,
Expand Down

0 comments on commit 697f406

Please sign in to comment.