fix(core): Fix Sentry error reporting on task runners (#12495)
Some checks failed
Test Master / install-and-build (push) Waiting to run
Test Master / Unit tests (18.x) (push) Blocked by required conditions
Test Master / Unit tests (20.x) (push) Blocked by required conditions
Test Master / Unit tests (22.4) (push) Blocked by required conditions
Test Master / Lint (push) Blocked by required conditions
Test Master / Notify Slack on failure (push) Blocked by required conditions
Benchmark Docker Image CI / build (push) Has been cancelled

This commit is contained in:
Iván Ovejero 2025-01-08 17:47:40 +01:00 committed by GitHub
parent dd36bb28bf
commit 88c0838dd7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 62 additions and 19 deletions

View file

@ -2,11 +2,35 @@ import { Config, Env } from '../decorators';
@Config
export class SentryConfig {
/** Sentry DSN for the backend. */
/** Sentry DSN (data source name) for the backend. */
@Env('N8N_SENTRY_DSN')
backendDsn: string = '';
/** Sentry DSN for the frontend . */
/** Sentry DSN (data source name) for the frontend. */
@Env('N8N_FRONTEND_SENTRY_DSN')
frontendDsn: string = '';
/**
* Version of the n8n instance
*
* @example '1.73.0'
*/
@Env('N8N_VERSION')
n8nVersion: string = '';
/**
* Environment of the n8n instance.
*
* @example 'production'
*/
@Env('ENVIRONMENT')
environment: string = '';
/**
* Name of the deployment, e.g. cloud account name.
*
* @example 'janober'
*/
@Env('DEPLOYMENT_NAME')
deploymentName: string = '';
}

View file

@ -236,6 +236,9 @@ describe('GlobalConfig', () => {
sentry: {
backendDsn: '',
frontendDsn: '',
n8nVersion: '',
environment: '',
deploymentName: '',
},
logging: {
level: 'info',

View file

@ -2,9 +2,9 @@ import { Config, Env } from '@n8n/config';
@Config
export class SentryConfig {
/** Sentry DSN */
/** Sentry DSN (data source name) */
@Env('N8N_SENTRY_DSN')
sentryDsn: string = '';
dsn: string = '';
//#region Metadata about the environment

View file

@ -50,7 +50,7 @@ describe('JsTaskRunner', () => {
...jsRunnerOpts,
},
sentryConfig: {
sentryDsn: '',
dsn: '',
deploymentName: '',
environment: '',
n8nVersion: '',

View file

@ -54,10 +54,19 @@ void (async function start() {
defaultTimezone: config.baseRunnerConfig.timezone,
});
if (config.sentryConfig.sentryDsn) {
const { dsn } = config.sentryConfig;
if (dsn) {
const { ErrorReporter } = await import('n8n-core');
errorReporter = Container.get(ErrorReporter);
await errorReporter.init('task_runner', config.sentryConfig.sentryDsn);
const { deploymentName, environment, n8nVersion } = config.sentryConfig;
await errorReporter.init({
serverType: 'task_runner',
dsn,
serverName: deploymentName,
environment,
release: n8nVersion,
});
}
runner = new JsTaskRunner(config);

View file

@ -61,10 +61,15 @@ export abstract class BaseCommand extends Command {
async init(): Promise<void> {
this.errorReporter = Container.get(ErrorReporter);
await this.errorReporter.init(
this.instanceSettings.instanceType,
this.globalConfig.sentry.backendDsn,
);
const { backendDsn, n8nVersion, environment, deploymentName } = this.globalConfig.sentry;
await this.errorReporter.init({
serverType: this.instanceSettings.instanceType,
dsn: backendDsn,
environment,
release: n8nVersion,
serverName: deploymentName,
});
initExpressionEvaluator();
process.once('SIGTERM', this.onTerminationSignal('SIGTERM'));

View file

@ -9,6 +9,14 @@ import { createHash } from 'node:crypto';
import type { InstanceType } from './InstanceSettings';
import { Logger } from './logging/logger';
type ErrorReporterInitOptions = {
serverType: InstanceType | 'task_runner';
dsn: string;
release: string;
environment: string;
serverName: string;
};
@Service()
export class ErrorReporter {
/** Hashes of error stack traces, to deduplicate error reports. */
@ -44,7 +52,7 @@ export class ErrorReporter {
await close(timeoutInMs);
}
async init(instanceType: InstanceType | 'task_runner', dsn: string) {
async init({ dsn, serverType, release, environment, serverName }: ErrorReporterInitOptions) {
process.on('uncaughtException', (error) => {
this.error(error);
});
@ -54,12 +62,6 @@ export class ErrorReporter {
// Collect longer stacktraces
Error.stackTraceLimit = 50;
const {
N8N_VERSION: release,
ENVIRONMENT: environment,
DEPLOYMENT_NAME: serverName,
} = process.env;
const { init, captureException, setTag } = await import('@sentry/node');
const { requestDataIntegration, rewriteFramesIntegration } = await import('@sentry/node');
@ -95,7 +97,7 @@ export class ErrorReporter {
],
});
setTag('server_type', instanceType);
setTag('server_type', serverType);
this.report = (error, options) => captureException(error, options);
}