fix(login): seperate OpenTelemetry initialization for different runtimes (#11785)

This commit is contained in:
Max Peintner
2026-03-09 09:24:19 +05:30
committed by GitHub
parent 2793abf1e3
commit 5b12690757
3 changed files with 70 additions and 49 deletions
+6
View File
@@ -81,5 +81,11 @@ declare namespace NodeJS {
* which is safer for environments with enterprise email link scanners.
*/
NEXT_PUBLIC_AUTO_SUBMIT_CODE?: string;
/**
* Optional: Disable OpenTelemetry instrumentation.
* Set to "true" to bypass OTEL initialization.
* In local development (NODE_ENV=development), it is disabled by default unless explicitly set to "false".
*/
OTEL_SDK_DISABLED?: string;
}
}
+53
View File
@@ -0,0 +1,53 @@
import type { LoggerProvider } from "@opentelemetry/api-logs";
export async function registerNode(): Promise<LoggerProvider | null> {
const [
{ NodeSDK },
{ envDetector, processDetector, hostDetector, resourceFromAttributes },
{ containerDetector },
{ gcpDetector },
{ logs },
{ getNodeAutoInstrumentations },
] = await Promise.all([
import("@opentelemetry/sdk-node"),
import("@opentelemetry/resources"),
import("@opentelemetry/resource-detector-container"),
import("@opentelemetry/resource-detector-gcp"),
import("@opentelemetry/api-logs"),
import("@opentelemetry/auto-instrumentations-node"),
]);
const sdk = new NodeSDK({
resource: resourceFromAttributes({
"deployment.environment.name": process.env.NODE_ENV || "development",
}),
resourceDetectors: [
envDetector,
processDetector,
hostDetector,
containerDetector,
gcpDetector,
],
instrumentations: [
getNodeAutoInstrumentations({
"@opentelemetry/instrumentation-http": {
ignoreIncomingRequestHook: (req) =>
["/healthy", "/_next/", "/favicon.ico", "/__nextjs", "/metrics"].some((p) =>
req.url?.includes(p),
),
},
"@opentelemetry/instrumentation-fs": { enabled: false },
"@opentelemetry/instrumentation-winston": { disableLogSending: false },
}),
],
});
sdk.start();
// Use console during shutdown as the logger may be unavailable
const shutdown = () => sdk.shutdown().catch(console.error);
process.once("SIGTERM", shutdown);
process.once("SIGINT", shutdown);
return logs.getLoggerProvider();
}
+11 -49
View File
@@ -29,57 +29,19 @@ import type { LoggerProvider } from "@opentelemetry/api-logs";
let _loggerProvider: LoggerProvider | null = null;
export async function register(): Promise<void> {
if (process.env.NEXT_RUNTIME !== "nodejs") return;
// Only run OpenTelemetry in the Node.js environment
if (process.env.NEXT_RUNTIME === "nodejs") {
// Disable by default in local development to avoid unnecessary overhead
if (process.env.NODE_ENV === "development" && process.env.OTEL_SDK_DISABLED !== "false") {
return;
}
const [
{ NodeSDK },
{ envDetector, processDetector, hostDetector, resourceFromAttributes },
{ containerDetector },
{ gcpDetector },
{ logs },
{ getNodeAutoInstrumentations },
] = await Promise.all([
import("@opentelemetry/sdk-node"),
import("@opentelemetry/resources"),
import("@opentelemetry/resource-detector-container"),
import("@opentelemetry/resource-detector-gcp"),
import("@opentelemetry/api-logs"),
import("@opentelemetry/auto-instrumentations-node"),
]);
// Explicit check for disabled env variable
if (process.env.OTEL_SDK_DISABLED === "true") return;
const sdk = new NodeSDK({
resource: resourceFromAttributes({
"deployment.environment.name": process.env.NODE_ENV || "development",
}),
resourceDetectors: [
envDetector,
processDetector,
hostDetector,
containerDetector,
gcpDetector,
],
instrumentations: [
getNodeAutoInstrumentations({
"@opentelemetry/instrumentation-http": {
ignoreIncomingRequestHook: (req) =>
["/healthy", "/_next/", "/favicon.ico", "/__nextjs", "/metrics"].some((p) =>
req.url?.includes(p),
),
},
"@opentelemetry/instrumentation-fs": { enabled: false },
"@opentelemetry/instrumentation-winston": { disableLogSending: false },
}),
],
});
sdk.start();
_loggerProvider = logs.getLoggerProvider();
// Use console during shutdown as the logger may be unavailable
const shutdown = () => sdk.shutdown().catch(console.error);
process.once("SIGTERM", shutdown);
process.once("SIGINT", shutdown);
const { registerNode } = await import("./instrumentation.node");
_loggerProvider = await registerNode();
}
}
export function getLoggerProvider(): LoggerProvider | null {