perf(core): Make event loop block detection configurable (#25291)

This commit is contained in:
Iván Ovejero
2026-02-04 10:39:18 +00:00
committed by GitHub
parent ef22db2c62
commit 5446098653
4 changed files with 33 additions and 7 deletions
@@ -35,6 +35,16 @@ export class SentryConfig {
@Env('N8N_SENTRY_PROFILES_SAMPLE_RATE', sampleRateSchema)
profilesSampleRate: number = 0;
/**
* Threshold in milliseconds for event loop block detection.
* When the event loop is blocked for longer than this threshold,
* Sentry will report it.
*
* @default 500
*/
@Env('N8N_SENTRY_EVENT_LOOP_BLOCK_THRESHOLD', z.number({ coerce: true }).int().positive())
eventLoopBlockThreshold: number = 500;
/**
* Environment of the n8n instance.
*
+1
View File
@@ -285,6 +285,7 @@ describe('GlobalConfig', () => {
deploymentName: '',
profilesSampleRate: 0,
tracesSampleRate: 0,
eventLoopBlockThreshold: 500,
},
logging: {
level: 'info',
+9 -2
View File
@@ -84,8 +84,14 @@ export abstract class BaseCommand<F = never> {
this.dbConnection = Container.get(DbConnection);
this.errorReporter = Container.get(ErrorReporter);
const { backendDsn, environment, deploymentName, profilesSampleRate, tracesSampleRate } =
this.globalConfig.sentry;
const {
backendDsn,
environment,
deploymentName,
profilesSampleRate,
tracesSampleRate,
eventLoopBlockThreshold,
} = this.globalConfig.sentry;
await this.errorReporter.init({
serverType: this.instanceSettings.instanceType,
dsn: backendDsn,
@@ -94,6 +100,7 @@ export abstract class BaseCommand<F = never> {
serverName: deploymentName,
releaseDate: N8N_RELEASE_DATE,
withEventLoopBlockDetection: true,
eventLoopBlockThreshold,
tracesSampleRate,
profilesSampleRate,
eligibleIntegrations: {
+13 -5
View File
@@ -23,6 +23,9 @@ type ErrorReporterInitOptions = {
/** Whether to enable event loop block detection, if Sentry is enabled. */
withEventLoopBlockDetection: boolean;
/** Threshold in ms for event loop block detection. Only used if `withEventLoopBlockDetection` is true. */
eventLoopBlockThreshold?: number;
/** Sample rate for Sentry traces (0.0 to 1.0). 0 means disabled */
tracesSampleRate: number;
@@ -107,6 +110,7 @@ export class ErrorReporter {
serverName,
releaseDate,
withEventLoopBlockDetection,
eventLoopBlockThreshold,
profilesSampleRate,
tracesSampleRate,
eligibleIntegrations = {},
@@ -174,10 +178,13 @@ export class ErrorReporter {
const eventLoopBlockIntegration = withEventLoopBlockDetection
? // The EventLoopBlockIntegration doesn't automatically include the
// same tags, so we set them explicitly.
await this.getEventLoopBlockIntegration({
server_name: serverName,
server_type: serverType,
})
await this.getEventLoopBlockIntegration(
{
server_name: serverName,
server_type: serverType,
},
eventLoopBlockThreshold,
)
: [];
const profilingIntegration = isProfilingEnabled ? await this.getProfilingIntegration() : [];
@@ -312,11 +319,12 @@ export class ErrorReporter {
if (tags) event.tags = { ...event.tags, ...tags };
}
private async getEventLoopBlockIntegration(tags: Record<string, string>) {
private async getEventLoopBlockIntegration(tags: Record<string, string>, threshold?: number) {
try {
const { eventLoopBlockIntegration } = await import('@sentry/node-native');
return [
eventLoopBlockIntegration({
...(threshold ? { threshold } : {}),
staticTags: tags,
}),
];