Skip to content

feat(node): Use new integration APIs #9821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions packages/node/src/integrations/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import type {
CultureContext,
DeviceContext,
Event,
EventProcessor,
Integration,
OsContext,
} from '@sentry/types';
Expand Down Expand Up @@ -63,12 +62,14 @@ export class Context implements Integration {
/**
* @inheritDoc
*/
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void): void {
addGlobalEventProcessor(event => this.addContext(event));
public setupOnce(): void {
//
}

/** Processes an event and adds context */
public async addContext(event: Event): Promise<Event> {
/**
* @inheritDoc
*/
public async processEvent(event: Event): Promise<Event | null> {
if (this._cachedContext === undefined) {
this._cachedContext = this._getContexts();
}
Expand Down
17 changes: 8 additions & 9 deletions packages/node/src/integrations/contextlines.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { readFile } from 'fs';
import type { Event, EventProcessor, Hub, Integration, StackFrame } from '@sentry/types';
import type { Event, Integration, StackFrame } from '@sentry/types';
import { LRUMap, addContextToFrame } from '@sentry/utils';

const FILE_CONTENT_CACHE = new LRUMap<string, string[] | null>(100);
Expand Down Expand Up @@ -55,14 +55,13 @@ export class ContextLines implements Integration {
/**
* @inheritDoc
*/
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
addGlobalEventProcessor(event => {
const self = getCurrentHub().getIntegration(ContextLines);
if (!self) {
return event;
}
return this.addSourceContext(event);
});
public setupOnce(): void {
//
}

/** @inheritdoc */
public processEvent(event: Event): Event | PromiseLike<Event | null> | null {
return this.addSourceContext(event);
}

/** Processes an event and adds context lines */
Expand Down
25 changes: 9 additions & 16 deletions packages/node/src/integrations/http.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
import type * as http from 'http';
import type * as https from 'https';
import type { Hub } from '@sentry/core';
import { getCurrentHub, getDynamicSamplingContextFromClient, isSentryRequestUrl } from '@sentry/core';
import type {
DynamicSamplingContext,
EventProcessor,
Integration,
SanitizedRequestData,
TracePropagationTargets,
} from '@sentry/types';
import type { DynamicSamplingContext, Integration, SanitizedRequestData, TracePropagationTargets } from '@sentry/types';
import {
LRUMap,
dynamicSamplingContextToSentryBaggageHeader,
Expand Down Expand Up @@ -91,19 +84,19 @@ export class Http implements Integration {
this._tracing = !options.tracing ? undefined : options.tracing === true ? {} : options.tracing;
}

/**
* @inheritDoc
*/
public setupOnce(
_addGlobalEventProcessor: (callback: EventProcessor) => void,
setupOnceGetCurrentHub: () => Hub,
): void {
/** @inheritdoc */
public setupOnce(): void {
//
}

/** @inheritdoc */
public setup(client: NodeClient): void {
// No need to instrument if we don't want to track anything
if (!this._breadcrumbs && !this._tracing) {
return;
}

const clientOptions = setupOnceGetCurrentHub().getClient<NodeClient>()?.getOptions();
const clientOptions = client.getOptions();

// Do not auto-instrument for other instrumenter
if (clientOptions && clientOptions.instrumenter !== 'sentry') {
Expand Down
87 changes: 45 additions & 42 deletions packages/node/src/integrations/localvariables.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/* eslint-disable max-lines */
import type { Event, EventProcessor, Exception, Hub, Integration, StackFrame, StackParser } from '@sentry/types';
import type { Event, Exception, Integration, StackFrame, StackParser } from '@sentry/types';
import { LRUMap, logger } from '@sentry/utils';
import type { Debugger, InspectorNotification, Runtime, Session } from 'inspector';
import type { NodeClient } from '../client';

import { NODE_VERSION } from '../nodeVersion';
import type { NodeClientOptions } from '../types';

type Variables = Record<string, unknown>;
type OnPauseEvent = InspectorNotification<Debugger.PausedEventDataType>;
Expand Down Expand Up @@ -341,55 +341,58 @@ export class LocalVariables implements Integration {
/**
* @inheritDoc
*/
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
this._setup(addGlobalEventProcessor, getCurrentHub().getClient()?.getOptions());
public setupOnce(): void {
//
}

/** Setup in a way that's easier to call from tests */
private _setup(
addGlobalEventProcessor: (callback: EventProcessor) => void,
clientOptions: NodeClientOptions | undefined,
): void {
if (this._session && clientOptions?.includeLocalVariables) {
// Only setup this integration if the Node version is >= v18
// https://github.com/getsentry/sentry-javascript/issues/7697
const unsupportedNodeVersion = (NODE_VERSION.major || 0) < 18;

if (unsupportedNodeVersion) {
logger.log('The `LocalVariables` integration is only supported on Node >= v18.');
return;
}
/** @inheritdoc */
public setup(client: NodeClient): void {
const clientOptions = client.getOptions();
if (!this._session || !clientOptions?.includeLocalVariables) {
return;
}

const captureAll = this._options.captureAllExceptions !== false;
// Only setup this integration if the Node version is >= v18
// https://github.com/getsentry/sentry-javascript/issues/7697
const unsupportedNodeVersion = (NODE_VERSION.major || 0) < 18;

this._session.configureAndConnect(
(ev, complete) =>
this._handlePaused(clientOptions.stackParser, ev as InspectorNotification<PausedExceptionEvent>, complete),
captureAll,
);
if (unsupportedNodeVersion) {
logger.log('The `LocalVariables` integration is only supported on Node >= v18.');
return;
}

if (captureAll) {
const max = this._options.maxExceptionsPerSecond || 50;

this._rateLimiter = createRateLimiter(
max,
() => {
logger.log('Local variables rate-limit lifted.');
this._session?.setPauseOnExceptions(true);
},
seconds => {
logger.log(
`Local variables rate-limit exceeded. Disabling capturing of caught exceptions for ${seconds} seconds.`,
);
this._session?.setPauseOnExceptions(false);
},
);
}
const captureAll = this._options.captureAllExceptions !== false;

this._session.configureAndConnect(
(ev, complete) =>
this._handlePaused(clientOptions.stackParser, ev as InspectorNotification<PausedExceptionEvent>, complete),
captureAll,
);

addGlobalEventProcessor(async event => this._addLocalVariables(event));
if (captureAll) {
const max = this._options.maxExceptionsPerSecond || 50;

this._rateLimiter = createRateLimiter(
max,
() => {
logger.log('Local variables rate-limit lifted.');
this._session?.setPauseOnExceptions(true);
},
seconds => {
logger.log(
`Local variables rate-limit exceeded. Disabling capturing of caught exceptions for ${seconds} seconds.`,
);
this._session?.setPauseOnExceptions(false);
},
);
}
}

/** @inheritdoc */
public processEvent(event: Event): Event | null {
return this._addLocalVariables(event);
}

/**
* Handle the pause event
*/
Expand Down
28 changes: 14 additions & 14 deletions packages/node/src/integrations/modules.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { existsSync, readFileSync } from 'fs';
import { dirname, join } from 'path';
import type { EventProcessor, Hub, Integration } from '@sentry/types';
import type { Event, Integration } from '@sentry/types';

let moduleCache: { [key: string]: string };

Expand Down Expand Up @@ -80,19 +80,19 @@ export class Modules implements Integration {
/**
* @inheritDoc
*/
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void, getCurrentHub: () => Hub): void {
addGlobalEventProcessor(event => {
if (!getCurrentHub().getIntegration(Modules)) {
return event;
}
return {
...event,
modules: {
...event.modules,
...this._getModules(),
},
};
});
public setupOnce(): void {
//
}

/** @inheritdoc */
public processEvent(event: Event): Event | PromiseLike<Event | null> | null {
return {
...event,
modules: {
...event.modules,
...this._getModules(),
},
};
}

/** Fetches the list of modules and the versions loaded by the entry file for your node.js app. */
Expand Down