275 lines
9.3 KiB
JavaScript
275 lines
9.3 KiB
JavaScript
|
import { _optionalChain } from '@sentry/utils';
|
||
|
import { inboundFiltersIntegration, functionToStringIntegration, linkedErrorsIntegration, requestDataIntegration, getMainCarrier, getIntegrationsToSetup, initAndBind, getClient, startSession, getIsolationScope, endSession, getCurrentScope } from '@sentry/core';
|
||
|
import { createStackParser, nodeStackLineParser, stackParserFromStackParserOptions, GLOBAL_OBJ, propagationContextFromHeaders } from '@sentry/utils';
|
||
|
import { setNodeAsyncContextStrategy } from './async/index.js';
|
||
|
import { NodeClient } from './client.js';
|
||
|
import { consoleIntegration } from './integrations/console.js';
|
||
|
import { nodeContextIntegration } from './integrations/context.js';
|
||
|
import { contextLinesIntegration } from './integrations/contextlines.js';
|
||
|
import { httpIntegration } from './integrations/http.js';
|
||
|
import { localVariablesIntegration } from './integrations/local-variables/index.js';
|
||
|
import { modulesIntegration } from './integrations/modules.js';
|
||
|
import { onUncaughtExceptionIntegration } from './integrations/onuncaughtexception.js';
|
||
|
import { onUnhandledRejectionIntegration } from './integrations/onunhandledrejection.js';
|
||
|
import { spotlightIntegration } from './integrations/spotlight.js';
|
||
|
import { nativeNodeFetchintegration } from './integrations/undici/index.js';
|
||
|
import { createGetModuleFromFilename } from './module.js';
|
||
|
import { makeNodeTransport } from './transports/http.js';
|
||
|
|
||
|
/* eslint-disable max-lines */
|
||
|
|
||
|
/** @deprecated Use `getDefaultIntegrations(options)` instead. */
|
||
|
const defaultIntegrations = [
|
||
|
// Common
|
||
|
inboundFiltersIntegration(),
|
||
|
functionToStringIntegration(),
|
||
|
linkedErrorsIntegration(),
|
||
|
requestDataIntegration(),
|
||
|
// Native Wrappers
|
||
|
consoleIntegration(),
|
||
|
httpIntegration(),
|
||
|
nativeNodeFetchintegration(),
|
||
|
// Global Handlers
|
||
|
onUncaughtExceptionIntegration(),
|
||
|
onUnhandledRejectionIntegration(),
|
||
|
// Event Info
|
||
|
contextLinesIntegration(),
|
||
|
localVariablesIntegration(),
|
||
|
nodeContextIntegration(),
|
||
|
modulesIntegration(),
|
||
|
];
|
||
|
|
||
|
/** Get the default integrations for the Node SDK. */
|
||
|
function getDefaultIntegrations(_options) {
|
||
|
const carrier = getMainCarrier();
|
||
|
|
||
|
const autoloadedIntegrations = _optionalChain([carrier, 'access', _ => _.__SENTRY__, 'optionalAccess', _2 => _2.integrations]) || [];
|
||
|
|
||
|
return [
|
||
|
// eslint-disable-next-line deprecation/deprecation
|
||
|
...defaultIntegrations,
|
||
|
...autoloadedIntegrations,
|
||
|
];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* The Sentry Node SDK Client.
|
||
|
*
|
||
|
* To use this SDK, call the {@link init} function as early as possible in the
|
||
|
* main entry module. To set context information or send manual events, use the
|
||
|
* provided methods.
|
||
|
*
|
||
|
* @example
|
||
|
* ```
|
||
|
*
|
||
|
* const { init } = require('@sentry/node');
|
||
|
*
|
||
|
* init({
|
||
|
* dsn: '__DSN__',
|
||
|
* // ...
|
||
|
* });
|
||
|
* ```
|
||
|
*
|
||
|
* @example
|
||
|
* ```
|
||
|
*
|
||
|
* const { configureScope } = require('@sentry/node');
|
||
|
* configureScope((scope: Scope) => {
|
||
|
* scope.setExtra({ battery: 0.7 });
|
||
|
* scope.setTag({ user_mode: 'admin' });
|
||
|
* scope.setUser({ id: '4711' });
|
||
|
* });
|
||
|
* ```
|
||
|
*
|
||
|
* @example
|
||
|
* ```
|
||
|
*
|
||
|
* const { addBreadcrumb } = require('@sentry/node');
|
||
|
* addBreadcrumb({
|
||
|
* message: 'My Breadcrumb',
|
||
|
* // ...
|
||
|
* });
|
||
|
* ```
|
||
|
*
|
||
|
* @example
|
||
|
* ```
|
||
|
*
|
||
|
* const Sentry = require('@sentry/node');
|
||
|
* Sentry.captureMessage('Hello, world!');
|
||
|
* Sentry.captureException(new Error('Good bye'));
|
||
|
* Sentry.captureEvent({
|
||
|
* message: 'Manual',
|
||
|
* stacktrace: [
|
||
|
* // ...
|
||
|
* ],
|
||
|
* });
|
||
|
* ```
|
||
|
*
|
||
|
* @see {@link NodeOptions} for documentation on configuration options.
|
||
|
*/
|
||
|
// eslint-disable-next-line complexity
|
||
|
function init(options = {}) {
|
||
|
setNodeAsyncContextStrategy();
|
||
|
|
||
|
if (options.defaultIntegrations === undefined) {
|
||
|
options.defaultIntegrations = getDefaultIntegrations();
|
||
|
}
|
||
|
|
||
|
if (options.dsn === undefined && process.env.SENTRY_DSN) {
|
||
|
options.dsn = process.env.SENTRY_DSN;
|
||
|
}
|
||
|
|
||
|
const sentryTracesSampleRate = process.env.SENTRY_TRACES_SAMPLE_RATE;
|
||
|
if (options.tracesSampleRate === undefined && sentryTracesSampleRate) {
|
||
|
const tracesSampleRate = parseFloat(sentryTracesSampleRate);
|
||
|
if (isFinite(tracesSampleRate)) {
|
||
|
options.tracesSampleRate = tracesSampleRate;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (options.release === undefined) {
|
||
|
const detectedRelease = getSentryRelease();
|
||
|
if (detectedRelease !== undefined) {
|
||
|
options.release = detectedRelease;
|
||
|
} else {
|
||
|
// If release is not provided, then we should disable autoSessionTracking
|
||
|
options.autoSessionTracking = false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (options.environment === undefined && process.env.SENTRY_ENVIRONMENT) {
|
||
|
options.environment = process.env.SENTRY_ENVIRONMENT;
|
||
|
}
|
||
|
|
||
|
if (options.autoSessionTracking === undefined && options.dsn !== undefined) {
|
||
|
options.autoSessionTracking = true;
|
||
|
}
|
||
|
|
||
|
if (options.instrumenter === undefined) {
|
||
|
options.instrumenter = 'sentry';
|
||
|
}
|
||
|
|
||
|
// TODO(v7): Refactor this to reduce the logic above
|
||
|
const clientOptions = {
|
||
|
...options,
|
||
|
stackParser: stackParserFromStackParserOptions(options.stackParser || defaultStackParser),
|
||
|
integrations: getIntegrationsToSetup(options),
|
||
|
transport: options.transport || makeNodeTransport,
|
||
|
};
|
||
|
|
||
|
initAndBind(options.clientClass || NodeClient, clientOptions);
|
||
|
|
||
|
if (options.autoSessionTracking) {
|
||
|
startSessionTracking();
|
||
|
}
|
||
|
|
||
|
updateScopeFromEnvVariables();
|
||
|
|
||
|
if (options.spotlight) {
|
||
|
const client = getClient();
|
||
|
if (client && client.addIntegration) {
|
||
|
// force integrations to be setup even if no DSN was set
|
||
|
// If they have already been added before, they will be ignored anyhow
|
||
|
const integrations = client.getOptions().integrations;
|
||
|
for (const integration of integrations) {
|
||
|
client.addIntegration(integration);
|
||
|
}
|
||
|
client.addIntegration(
|
||
|
spotlightIntegration({ sidecarUrl: typeof options.spotlight === 'string' ? options.spotlight : undefined }),
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Function that takes an instance of NodeClient and checks if autoSessionTracking option is enabled for that client
|
||
|
*/
|
||
|
function isAutoSessionTrackingEnabled(client) {
|
||
|
if (client === undefined) {
|
||
|
return false;
|
||
|
}
|
||
|
const clientOptions = client && client.getOptions();
|
||
|
if (clientOptions && clientOptions.autoSessionTracking !== undefined) {
|
||
|
return clientOptions.autoSessionTracking;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a release dynamically from environment variables.
|
||
|
*/
|
||
|
function getSentryRelease(fallback) {
|
||
|
// Always read first as Sentry takes this as precedence
|
||
|
if (process.env.SENTRY_RELEASE) {
|
||
|
return process.env.SENTRY_RELEASE;
|
||
|
}
|
||
|
|
||
|
// This supports the variable that sentry-webpack-plugin injects
|
||
|
if (GLOBAL_OBJ.SENTRY_RELEASE && GLOBAL_OBJ.SENTRY_RELEASE.id) {
|
||
|
return GLOBAL_OBJ.SENTRY_RELEASE.id;
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
// GitHub Actions - https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables
|
||
|
process.env.GITHUB_SHA ||
|
||
|
// Netlify - https://docs.netlify.com/configure-builds/environment-variables/#build-metadata
|
||
|
process.env.COMMIT_REF ||
|
||
|
// Vercel - https://vercel.com/docs/v2/build-step#system-environment-variables
|
||
|
process.env.VERCEL_GIT_COMMIT_SHA ||
|
||
|
process.env.VERCEL_GITHUB_COMMIT_SHA ||
|
||
|
process.env.VERCEL_GITLAB_COMMIT_SHA ||
|
||
|
process.env.VERCEL_BITBUCKET_COMMIT_SHA ||
|
||
|
// Zeit (now known as Vercel)
|
||
|
process.env.ZEIT_GITHUB_COMMIT_SHA ||
|
||
|
process.env.ZEIT_GITLAB_COMMIT_SHA ||
|
||
|
process.env.ZEIT_BITBUCKET_COMMIT_SHA ||
|
||
|
// Cloudflare Pages - https://developers.cloudflare.com/pages/platform/build-configuration/#environment-variables
|
||
|
process.env.CF_PAGES_COMMIT_SHA ||
|
||
|
fallback
|
||
|
);
|
||
|
}
|
||
|
|
||
|
/** Node.js stack parser */
|
||
|
const defaultStackParser = createStackParser(nodeStackLineParser(createGetModuleFromFilename()));
|
||
|
|
||
|
/**
|
||
|
* Enable automatic Session Tracking for the node process.
|
||
|
*/
|
||
|
function startSessionTracking() {
|
||
|
startSession();
|
||
|
// Emitted in the case of healthy sessions, error of `mechanism.handled: true` and unhandledrejections because
|
||
|
// The 'beforeExit' event is not emitted for conditions causing explicit termination,
|
||
|
// such as calling process.exit() or uncaught exceptions.
|
||
|
// Ref: https://nodejs.org/api/process.html#process_event_beforeexit
|
||
|
process.on('beforeExit', () => {
|
||
|
const session = getIsolationScope().getSession();
|
||
|
const terminalStates = ['exited', 'crashed'];
|
||
|
// Only call endSession, if the Session exists on Scope and SessionStatus is not a
|
||
|
// Terminal Status i.e. Exited or Crashed because
|
||
|
// "When a session is moved away from ok it must not be updated anymore."
|
||
|
// Ref: https://develop.sentry.dev/sdk/sessions/
|
||
|
if (session && !terminalStates.includes(session.status)) {
|
||
|
endSession();
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update scope and propagation context based on environmental variables.
|
||
|
*
|
||
|
* See https://github.com/getsentry/rfcs/blob/main/text/0071-continue-trace-over-process-boundaries.md
|
||
|
* for more details.
|
||
|
*/
|
||
|
function updateScopeFromEnvVariables() {
|
||
|
const sentryUseEnvironment = (process.env.SENTRY_USE_ENVIRONMENT || '').toLowerCase();
|
||
|
if (!['false', 'n', 'no', 'off', '0'].includes(sentryUseEnvironment)) {
|
||
|
const sentryTraceEnv = process.env.SENTRY_TRACE;
|
||
|
const baggageEnv = process.env.SENTRY_BAGGAGE;
|
||
|
const propagationContext = propagationContextFromHeaders(sentryTraceEnv, baggageEnv);
|
||
|
getCurrentScope().setPropagationContext(propagationContext);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
export { defaultIntegrations, defaultStackParser, getDefaultIntegrations, getSentryRelease, init, isAutoSessionTrackingEnabled };
|
||
|
//# sourceMappingURL=sdk.js.map
|