mirror of
https://github.com/ToolJet/ToolJet
synced 2026-05-24 09:28:31 +00:00
Implement OpenTelemetry middleware initialization and auto-start logic
This commit is contained in:
parent
8ae3924968
commit
4f5d186455
3 changed files with 94 additions and 11 deletions
|
|
@ -84,30 +84,41 @@ export async function handleLicensingInit(app: NestExpressApplication, logger: a
|
|||
}
|
||||
|
||||
/**
|
||||
* Handles OTEL initialization for Enterprise Edition
|
||||
* Applies OTEL middleware to Express app
|
||||
* Note: The OTEL SDK is started at import time in src/otel/tracing.ts
|
||||
* This function only applies the middleware after the app is created
|
||||
*/
|
||||
export async function initializeOtel(app: NestExpressApplication, logger: any) {
|
||||
// Check if OTEL is enabled
|
||||
if (process.env.ENABLE_OTEL !== 'true') {
|
||||
logger.log('OTEL disabled (ENABLE_OTEL not set to true)');
|
||||
logger.log('⏭️ OTEL disabled (ENABLE_OTEL not set to true)');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
logger.log('Initializing OpenTelemetry...');
|
||||
|
||||
const tooljetEdition = getTooljetEdition() as TOOLJET_EDITIONS;
|
||||
const importPath = await getImportPath(false, tooljetEdition);
|
||||
|
||||
// Dynamically import the edition-specific listener
|
||||
const { otelListener } = await import(`${importPath}/otel/listener`);
|
||||
if (tooljetEdition !== TOOLJET_EDITIONS.EE) {
|
||||
logger.log('⏭️ OTEL skipped - not Enterprise Edition');
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize the listener (CE will no-op, EE will set up OTEL)
|
||||
await otelListener.initialize(app);
|
||||
logger.log('🔭 Applying OpenTelemetry middleware...');
|
||||
|
||||
logger.log('✅ OpenTelemetry initialization completed');
|
||||
// Import otelMiddleware from tracing.ts (use relative path for runtime compatibility)
|
||||
const { otelMiddleware } = await import('../otel/tracing');
|
||||
|
||||
// Apply OTEL middleware to Express app
|
||||
const expressApp = app.getHttpAdapter().getInstance();
|
||||
expressApp.use(otelMiddleware);
|
||||
|
||||
logger.log('✅ OpenTelemetry middleware applied successfully');
|
||||
logger.log(' - SDK: Already started at import time');
|
||||
logger.log(' - Tracing: Enabled');
|
||||
logger.log(' - Metrics: Enabled');
|
||||
logger.log(' - Auto-instrumentation: Active');
|
||||
} catch (error) {
|
||||
logger.error('❌ Failed to initialize OpenTelemetry:', error);
|
||||
logger.error('❌ Failed to apply OpenTelemetry middleware:', error);
|
||||
// Don't throw - observability should never break the app
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import './otel/tracing'; // CRITICAL: This MUST be the first import to ensure OTEL patches modules before they load
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { NestExpressApplication } from '@nestjs/platform-express';
|
||||
import { WsAdapter } from '@nestjs/platform-ws';
|
||||
|
|
|
|||
|
|
@ -581,3 +581,74 @@ export const decrementActiveSessions = (attributes: {
|
|||
activeSessionsCounter.add(-1, metricAttributes);
|
||||
}
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// AUTO-START: Initialize OTEL SDK immediately when this module is imported
|
||||
// This MUST run before any other modules (http, pg, express, etc.) are loaded
|
||||
// ============================================================================
|
||||
|
||||
// Load .env file before checking ENABLE_OTEL
|
||||
// ConfigModule hasn't loaded yet, so we need to manually load .env
|
||||
// Use the same pattern as the rest of the codebase (from database-config-utils.ts)
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const dotenv = require('dotenv');
|
||||
|
||||
function loadEnvVars() {
|
||||
const envFilePath = process.env.NODE_ENV === 'test'
|
||||
? path.resolve(process.cwd(), '../.env.test')
|
||||
: path.resolve(process.cwd(), '../.env');
|
||||
|
||||
if (fs.existsSync(envFilePath)) {
|
||||
const envConfig = dotenv.parse(fs.readFileSync(envFilePath));
|
||||
// Merge with existing process.env (existing env vars take precedence)
|
||||
Object.assign(process.env, envConfig, process.env);
|
||||
}
|
||||
}
|
||||
|
||||
// Load environment variables
|
||||
loadEnvVars();
|
||||
|
||||
console.log('[OTEL] Auto-start code reached');
|
||||
console.log('[OTEL] ENABLE_OTEL:', process.env.ENABLE_OTEL);
|
||||
|
||||
let isInitialized = false;
|
||||
|
||||
if (process.env.ENABLE_OTEL === 'true' && !isInitialized) {
|
||||
console.log('[OTEL] Condition met, checking edition...');
|
||||
|
||||
try {
|
||||
// Check edition - only EE supports OTEL
|
||||
// Use relative paths instead of TypeScript aliases for runtime compatibility
|
||||
const { getTooljetEdition } = require('../helpers/utils.helper');
|
||||
const { TOOLJET_EDITIONS } = require('../modules/app/constants');
|
||||
|
||||
const tooljetEdition = getTooljetEdition();
|
||||
console.log('[OTEL] Edition:', tooljetEdition);
|
||||
|
||||
if (tooljetEdition === TOOLJET_EDITIONS.EE) {
|
||||
console.log('[OTEL] Starting SDK at import time (before any modules load)...');
|
||||
|
||||
// Start OTEL SDK - this registers instrumentations immediately
|
||||
// The patches are applied synchronously when instrumentations are registered
|
||||
startOpenTelemetry()
|
||||
.then(() => {
|
||||
isInitialized = true;
|
||||
console.log('[OTEL] ✅ SDK started successfully');
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('[OTEL] ❌ Failed to start SDK:', err);
|
||||
// Log the error but don't throw - observability should never break the app
|
||||
});
|
||||
|
||||
// Mark as initializing to prevent double initialization
|
||||
isInitialized = true;
|
||||
} else {
|
||||
console.log('[OTEL] ⏭️ Skipping OTEL - not Enterprise Edition');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[OTEL] Error during auto-start:', error);
|
||||
}
|
||||
} else {
|
||||
console.log('[OTEL] Condition NOT met. ENABLE_OTEL:', process.env.ENABLE_OTEL, 'isInitialized:', isInitialized);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue