Skip to content

Commit

Permalink
ref: Hoist createCheckinEnvelope to core package (#8082)
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst committed May 9, 2023
1 parent 0e36397 commit 6462e0d
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 86 deletions.
File renamed without changes.
26 changes: 26 additions & 0 deletions packages/core/src/exports.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import type {
Breadcrumb,
CaptureContext,
CheckIn,
CustomSamplingContext,
Event,
EventHint,
Extra,
Extras,
MonitorConfig,
Primitive,
Severity,
SeverityLevel,
TransactionContext,
User,
} from '@sentry/types';
import { logger, uuid4 } from '@sentry/utils';

import type { Hub } from './hub';
import { getCurrentHub } from './hub';
Expand Down Expand Up @@ -184,3 +187,26 @@ export function startTransaction(
): ReturnType<Hub['startTransaction']> {
return getCurrentHub().startTransaction({ ...context }, customSamplingContext);
}

/**
* Create a cron monitor check in and send it to Sentry.
*
* @param checkIn An object that describes a check in.
* @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 captureCheckIn(checkIn: CheckIn, upsertMonitorConfig?: MonitorConfig): string {
const capturedCheckIn =
checkIn.status !== 'in_progress' && checkIn.checkInId ? checkIn : { ...checkIn, checkInId: uuid4() };

const client = getCurrentHub().getClient();
if (!client) {
__DEBUG_BUILD__ && logger.warn('Cannot capture check-in. No client defined.');
} else if (!client.captureCheckIn) {
__DEBUG_BUILD__ && logger.warn('Cannot capture check-in. Client does not support sending check-ins.');
} else {
client.captureCheckIn(capturedCheckIn, upsertMonitorConfig);
}

return capturedCheckIn.checkInId;
}
2 changes: 2 additions & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export {
setTags,
setUser,
withScope,
captureCheckIn,
} from './exports';
export {
getCurrentHub,
Expand All @@ -42,6 +43,7 @@ export { SDK_VERSION } from './version';
export { getIntegrationsToSetup } from './integration';
export { FunctionToString, InboundFilters } from './integrations';
export { prepareEvent } from './utils/prepareEvent';
export { createCheckInEnvelope } from './checkin';
export { hasTracingEnabled } from './utils/hasTracingEnabled';
export { DEFAULT_ENVIRONMENT } from './constants';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { SerializedCheckIn } from '@sentry/types';

import { createCheckInEnvelope } from '../src/checkin';
import { createCheckInEnvelope } from '../../src/checkin';

describe('CheckIn', () => {
describe('createCheckInEnvelope', () => {
test('creates a check in envelope header', () => {
const envelope = createCheckInEnvelope(
{
Expand Down
47 changes: 21 additions & 26 deletions packages/core/test/lib/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Scope } from '@sentry/core';
import { captureCheckIn, getCurrentHub } from '@sentry/core';
import type { Client, Integration } from '@sentry/types';

import { installedIntegrations } from '../../src/integration';
Expand All @@ -10,31 +10,6 @@ declare var global: any;

const PUBLIC_DSN = 'https://username@domain/123';

jest.mock('@sentry/core', () => {
const original = jest.requireActual('@sentry/core');
return {
...original,
getCurrentHub(): {
bindClient(client: Client): boolean;
getClient(): boolean;
getScope(): Scope;
} {
return {
getClient(): boolean {
return false;
},
getScope(): Scope {
return new Scope();
},
bindClient(client: Client): boolean {
client.setupIntegrations();
return true;
},
};
},
};
});

export class MockIntegration implements Integration {
public name: string;
public setupOnce: () => void = jest.fn();
Expand Down Expand Up @@ -62,3 +37,23 @@ describe('SDK', () => {
});
});
});

describe('captureCheckIn', () => {
it('returns an id when client is defined', () => {
const hub = getCurrentHub();
jest.spyOn(hub, 'getClient').mockImplementation(() => {
return {
captureCheckIn: () => 'some-id-wasd-1234',
} as unknown as Client;
});

expect(captureCheckIn({ monitorSlug: 'gogogo', status: 'in_progress' })).toStrictEqual(expect.any(String));
});

it('returns an id when client is undefined', () => {
const hub = getCurrentHub();
jest.spyOn(hub, 'getClient').mockImplementation(() => undefined);

expect(captureCheckIn({ monitorSlug: 'gogogo', status: 'in_progress' })).toStrictEqual(expect.any(String));
});
});
3 changes: 1 addition & 2 deletions packages/node/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Scope } from '@sentry/core';
import { addTracingExtensions, BaseClient, SDK_VERSION, SessionFlusher } from '@sentry/core';
import { addTracingExtensions, BaseClient, createCheckInEnvelope, SDK_VERSION, SessionFlusher } from '@sentry/core';
import type {
CheckIn,
Event,
Expand All @@ -13,7 +13,6 @@ import { logger, resolvedSyncPromise, uuid4 } from '@sentry/utils';
import * as os from 'os';
import { TextEncoder } from 'util';

import { createCheckInEnvelope } from './checkin';
import { eventFromMessage, eventFromUnknownInput } from './eventbuilder';
import type { NodeClientOptions } from './types';

Expand Down
12 changes: 2 additions & 10 deletions packages/node/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,22 +50,14 @@ export {
spanStatusfromHttpCode,
trace,
withScope,
captureCheckIn,
} from '@sentry/core';
export type { SpanStatusType } from '@sentry/core';
export { autoDiscoverNodePerformanceMonitoringIntegrations } from './tracing';

export { NodeClient } from './client';
export { makeNodeTransport } from './transports';
export {
defaultIntegrations,
init,
defaultStackParser,
lastEventId,
flush,
close,
getSentryRelease,
captureCheckIn,
} from './sdk';
export { defaultIntegrations, init, defaultStackParser, lastEventId, flush, close, getSentryRelease } from './sdk';
export { addRequestDataToEvent, DEFAULT_USER_INCLUDES, extractRequestData } from './requestdata';
export { deepReadDirSync } from './utils';

Expand Down
27 changes: 1 addition & 26 deletions packages/node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,13 @@ import {
initAndBind,
Integrations as CoreIntegrations,
} from '@sentry/core';
import type { CheckIn, MonitorConfig, SessionStatus, StackParser } from '@sentry/types';
import type { SessionStatus, StackParser } from '@sentry/types';
import {
createStackParser,
GLOBAL_OBJ,
logger,
nodeStackLineParser,
stackParserFromStackParserOptions,
uuid4,
} from '@sentry/utils';

import { setNodeAsyncContextStrategy } from './async';
Expand Down Expand Up @@ -263,30 +262,6 @@ export function getSentryRelease(fallback?: string): string | undefined {
);
}

/**
* Create a cron monitor check in and send it to Sentry.
*
* @param checkIn An object that describes a check in.
* @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 captureCheckIn(
checkIn: CheckIn,
upsertMonitorConfig?: MonitorConfig,
): ReturnType<NodeClient['captureCheckIn']> {
const capturedCheckIn =
checkIn.status !== 'in_progress' && checkIn.checkInId ? checkIn : { ...checkIn, checkInId: uuid4() };

const client = getCurrentHub().getClient<NodeClient>();
if (client) {
client.captureCheckIn(capturedCheckIn, upsertMonitorConfig);
} else {
__DEBUG_BUILD__ && logger.warn('Cannot capture check in. No client defined.');
}

return capturedCheckIn.checkInId;
}

/** Node.js stack parser */
export const defaultStackParser: StackParser = createStackParser(nodeStackLineParser(getModule));

Expand Down
20 changes: 0 additions & 20 deletions packages/node/test/sdk.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { getCurrentHub } from '@sentry/core';
import type { Integration } from '@sentry/types';

import type { NodeClient } from '../build/types';
import { init } from '../src/sdk';
import * as sdk from '../src/sdk';

Expand Down Expand Up @@ -92,21 +90,3 @@ describe('init()', () => {
expect(newIntegration.setupOnce as jest.Mock).toHaveBeenCalledTimes(1);
});
});

describe('captureCheckIn', () => {
it('always returns an id', () => {
const hub = getCurrentHub();
const client = hub.getClient<NodeClient>();
expect(client).toBeDefined();

const captureCheckInSpy = jest.spyOn(client!, 'captureCheckIn');

// test if captureCheckIn returns an id even if client is not defined
hub.bindClient(undefined);

expect(captureCheckInSpy).toHaveBeenCalledTimes(0);
expect(sdk.captureCheckIn({ monitorSlug: 'gogogo', status: 'in_progress' })).toBeTruthy();

hub.bindClient(client);
});
});
11 changes: 11 additions & 0 deletions packages/types/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Breadcrumb, BreadcrumbHint } from './breadcrumb';
import type { CheckIn, MonitorConfig } from './checkin';
import type { EventDropReason } from './clientreport';
import type { DataCategory } from './datacategory';
import type { DsnComponents } from './dsn';
Expand Down Expand Up @@ -67,6 +68,16 @@ export interface Client<O extends ClientOptions = ClientOptions> {
*/
captureSession?(session: Session): void;

/**
* Create a cron monitor check in and send it to Sentry. This method is not available on all clients.
*
* @param checkIn An object that describes a check in.
* @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.
* @returns A string representing the id of the check in.
*/
captureCheckIn?(checkIn: CheckIn, monitorConfig?: MonitorConfig): string;

/** Returns the current Dsn. */
getDsn(): DsnComponents | undefined;

Expand Down

0 comments on commit 6462e0d

Please sign in to comment.