@sentry/nextjs
Version:
Official Sentry SDK for Next.js
155 lines (152 loc) • 8.96 kB
JavaScript
import { registerSpanErrorInstrumentation, GLOBAL_OBJ, getGlobalScope, debug, applySdkMetadata, getIsolationScope, spanToJSON, getRootSpan, hasSpanStreamingEnabled, HTTP_SPAN_NAME_FALLBACK } from '@sentry/core';
import { getDefaultIntegrations, init as init$1 } from '@sentry/vercel-edge';
export * from '@sentry/vercel-edge';
import { DEBUG_BUILD } from '../common/debug-build.js';
import { ATTR_NEXT_SPAN_TYPE, ATTR_NEXT_SPAN_NAME } from '../common/nextSpanAttributes.js';
import { TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION, ATTR_NEXT_PAGES_API_ROUTE_TYPE } from '../common/span-attributes-with-logic-attached.js';
import { addHeadersAsAttributes } from '../common/utils/addHeadersAsAttributes.js';
import { backfillHttpResponseStatusCode } from '../common/utils/backfillHttpResponseStatusCode.js';
import { backfillHttpServerStatus } from '../common/utils/backfillHttpServerStatus.js';
import { createLiveRootSpanAdapter } from '../common/utils/liveRootSpanAdapter.js';
import { getTunnelRouteIgnoreSpans, dropMiddlewareTunnelRequests } from '../common/utils/dropMiddlewareTunnelRequests.js';
import { maybeForkIsolationScopeForRootSpan } from '../common/utils/forkIsolationScopeForRootSpan.js';
import { getNormalizedRequestFromAttributes } from '../common/utils/getNormalizedRequestFromAttributes.js';
import { isBuild } from '../common/utils/isBuild.js';
import { isCloudflareWaitUntilAvailable, isAsyncContextOwnedByCloudflare, setCloudflareWorkerRelease, waitUntil, flushSafelyWithTimeout } from '../common/utils/responseEnd.js';
import { setUrlProcessingMetadata } from '../common/utils/setUrlProcessingMetadata.js';
import { distDirRewriteFramesIntegration } from './distDirRewriteFramesIntegration.js';
import { enhanceMiddlewareRootSpan } from '../common/enhanceMiddlewareRootSpan.js';
import { enhanceRunHandlerRootSpan } from './enhanceRunHandlerRootSpan.js';
import { HTTP_REQUEST_METHOD, HTTP_METHOD, SENTRY_ORIGIN, SENTRY_KIND, SENTRY_OP, SENTRY_SEGMENT_NAME_SOURCE } from '@sentry/conventions/attributes';
import { MIDDLEWARE, HTTP_SERVER } from '@sentry/conventions/op';
export { wrapGetStaticPropsWithSentry } from '../common/pages-router-instrumentation/wrapGetStaticPropsWithSentry.js';
export { wrapGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapGetInitialPropsWithSentry.js';
export { wrapAppGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapAppGetInitialPropsWithSentry.js';
export { wrapDocumentGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapDocumentGetInitialPropsWithSentry.js';
export { wrapErrorGetInitialPropsWithSentry } from '../common/pages-router-instrumentation/wrapErrorGetInitialPropsWithSentry.js';
export { wrapGetServerSidePropsWithSentry } from '../common/pages-router-instrumentation/wrapGetServerSidePropsWithSentry.js';
export { wrapServerComponentWithSentry } from '../common/wrapServerComponentWithSentry.js';
export { wrapRouteHandlerWithSentry } from '../common/wrapRouteHandlerWithSentry.js';
export { wrapApiHandlerWithSentryVercelCrons } from '../common/pages-router-instrumentation/wrapApiHandlerWithSentryVercelCrons.js';
export { wrapMiddlewareWithSentry } from '../common/wrapMiddlewareWithSentry.js';
export { wrapPageComponentWithSentry } from '../common/pages-router-instrumentation/wrapPageComponentWithSentry.js';
export { wrapGenerationFunctionWithSentry } from '../common/wrapGenerationFunctionWithSentry.js';
export { withServerActionInstrumentation } from '../common/withServerActionInstrumentation.js';
export { captureRequestError } from '../common/captureRequestError.js';
export { captureUnderscoreErrorException } from '../common/pages-router-instrumentation/_error.js';
export { pinoIntegration } from '../common/pinoIntegrationShim.js';
export { vercelAIIntegration } from '../common/vercelAIIntegrationShim.js';
export { startInactiveSpan, startSpan, startSpanManual } from '../common/utils/nextSpan.js';
export { wrapApiHandlerWithSentry } from './wrapApiHandlerWithSentry.js';
const globalWithInjectedValues = GLOBAL_OBJ;
function init(options = {}) {
registerSpanErrorInstrumentation();
if (isBuild()) {
return;
}
if (!DEBUG_BUILD && options.debug) {
console.warn(
"[@sentry/nextjs] You have enabled `debug: true`, but Sentry debug logging was removed from your bundle (likely via `bundleSizeOptimizations.excludeDebugStatements: true` or `webpack.treeshake.removeDebugLogging: true`). Set that option to `false` to see Sentry debug output."
);
}
const customDefaultIntegrations = getDefaultIntegrations();
const distDirName = process.env._sentryRewriteFramesDistDir || globalWithInjectedValues._sentryRewriteFramesDistDir;
if (distDirName) {
customDefaultIntegrations.push(distDirRewriteFramesIntegration({ distDirName }));
}
const isRunningOnCloudflare = isCloudflareWaitUntilAvailable();
const opts = {
defaultIntegrations: customDefaultIntegrations,
environment: options.environment || process.env.SENTRY_ENVIRONMENT,
release: process.env._sentryRelease || globalWithInjectedValues._sentryRelease,
...options,
// Override runtime to 'cloudflare' when running on OpenNext/Cloudflare
...isRunningOnCloudflare && { runtime: { name: "cloudflare" } }
};
const nextjsIgnoreSpans = [
// (set in `dropMiddlewareTunnelRequests` during `spanStart`)
{ attributes: { [TRANSACTION_ATTR_SHOULD_DROP_TRANSACTION]: true } },
...getTunnelRouteIgnoreSpans()
];
opts.ignoreSpans = [...opts.ignoreSpans || [], ...nextjsIgnoreSpans];
try {
if (process.turbopack) {
getGlobalScope().setTag("turbopack", true);
getGlobalScope().setAttribute("turbopack", true);
}
} catch {
}
if (isAsyncContextOwnedByCloudflare()) {
setCloudflareWorkerRelease(opts.release);
DEBUG_BUILD && debug.log(
"The client of `withSentry` handles this Worker, so `init` creates no client and only applies `release`. Set the other options in `withSentry`."
);
return;
}
if (isRunningOnCloudflare) {
applySdkMetadata(opts, "nextjs", ["nextjs", "cloudflare"]);
} else {
applySdkMetadata(opts, "nextjs", ["nextjs", "vercel-edge"]);
}
const client = init$1(opts);
client.on("beforeSampling", ({ spanAttributes }) => {
const spanType = spanAttributes[ATTR_NEXT_SPAN_TYPE];
if (spanType !== "Middleware.execute" && spanType !== "BaseServer.handleRequest" && spanType !== "Next.request") {
return;
}
const isolationScope = getIsolationScope();
isolationScope.setSDKProcessingMetadata({ normalizedRequest: void 0 });
const normalizedRequest = getNormalizedRequestFromAttributes(spanAttributes);
if (normalizedRequest) {
isolationScope.setSDKProcessingMetadata({ normalizedRequest });
}
});
client.on("spanStart", (span) => {
const spanAttributes = spanToJSON(span).attributes;
const rootSpan = getRootSpan(span);
const isRootSpan = span === rootSpan;
dropMiddlewareTunnelRequests(span, spanAttributes);
if (isRootSpan && spanAttributes?.[ATTR_NEXT_SPAN_TYPE] === "BaseServer.handleRequest" && hasSpanStreamingEnabled(client)) {
const method = spanAttributes[HTTP_REQUEST_METHOD] ?? spanAttributes[HTTP_METHOD];
createLiveRootSpanAdapter(span).setName(
(typeof method === "string" ? method.toUpperCase() : "") || HTTP_SPAN_NAME_FALLBACK
);
}
if (spanAttributes?.[ATTR_NEXT_SPAN_TYPE] !== void 0) {
span.setAttribute(SENTRY_ORIGIN, "auto");
span.setAttribute(SENTRY_KIND, "server");
}
if (spanAttributes?.[ATTR_NEXT_SPAN_TYPE] === "Middleware.execute") {
span.setAttribute(SENTRY_OP, MIDDLEWARE);
span.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, "url");
}
if (spanAttributes?.[ATTR_NEXT_SPAN_TYPE] === "Node.runHandler" && String(spanAttributes?.[ATTR_NEXT_SPAN_NAME]).startsWith(ATTR_NEXT_PAGES_API_ROUTE_TYPE)) {
span.setAttribute(SENTRY_OP, HTTP_SERVER);
span.setAttribute(SENTRY_SEGMENT_NAME_SOURCE, "route");
}
if (spanAttributes?.[ATTR_NEXT_SPAN_TYPE] === "BaseServer.handleRequest") {
span.setAttribute(SENTRY_OP, HTTP_SERVER);
}
maybeForkIsolationScopeForRootSpan(span, spanAttributes);
if (isRootSpan) {
const headers = getIsolationScope().getScopeData().sdkProcessingMetadata?.normalizedRequest?.headers;
addHeadersAsAttributes(headers, rootSpan);
}
});
client.on("preprocessEvent", (event) => {
setUrlProcessingMetadata(event);
});
client.on("spanEnd", (span) => {
if (span !== getRootSpan(span)) {
return;
}
const mutableRootSpan = createLiveRootSpanAdapter(span);
enhanceMiddlewareRootSpan(mutableRootSpan);
enhanceRunHandlerRootSpan(mutableRootSpan);
backfillHttpResponseStatusCode(mutableRootSpan.attributes);
backfillHttpServerStatus(span);
waitUntil(flushSafelyWithTimeout());
});
}
export { init };
//# sourceMappingURL=index.js.map