/** * Multi-Main Observability E2E Tests * * These tests verify that the observability stack (VictoriaMetrics + VictoriaLogs) * works correctly with n8n's multi-main architecture in queue mode. * * Architecture under test: * ┌─────────────────────────────────────────────────────────────────────────┐ * │ Queue Mode Cluster (2 mains + 1 worker) │ * │ │ * │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ * │ │ Main 1 │ │ Main 2 │ │ Worker 1 │ │ * │ │ (leader) │ │ (follower) │ │ │ │ * │ │ :5678/metrics│ │ :5679/metrics│ │ :5680/metrics│ │ * │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ * │ │ │ │ │ * │ │ Syslog (TCP) │ │ │ * │ └───────────────────┼───────────────────┘ │ * │ │ │ * │ ▼ │ * │ ┌──────────────────────────────────────────────────────────────────┐ │ * │ │ VictoriaLogs (:9428) │ │ * │ │ - Receives syslog on port 514 │ │ * │ │ - LogsQL queries via HTTP API │ │ * │ └──────────────────────────────────────────────────────────────────┘ │ * │ │ * │ ┌──────────────────────────────────────────────────────────────────┐ │ * │ │ VictoriaMetrics (:8428) │ │ * │ │ - Scrapes /metrics from all n8n instances every 5s │ │ * │ │ - PromQL queries via HTTP API │ │ * │ └──────────────────────────────────────────────────────────────────┘ │ * └─────────────────────────────────────────────────────────────────────────┘ * * Test scenarios: * 1. Metrics scraping - Verify VictoriaMetrics discovers and scrapes all instances * 2. Log streaming - Verify logs from cluster reach VictoriaLogs via syslog * * Run with: * pnpm playwright test -- --grep "Multi-main Observability" */ import { test, expect } from '../../../fixtures/base'; // Configure test to run with multi-main queue mode and observability stack test.use({ capability: { services: ['victoriaLogs', 'victoriaMetrics', 'vector'], mains: 2, workers: 1, }, }); test.describe('Multi-main Observability @capability:observability @mode:multi-main', { annotation: [ { type: 'owner', description: 'Catalysts' }, ], }, () => { /** * Test: Metrics scraping from multi-main cluster * * Verifies that VictoriaMetrics can discover and scrape metrics from all * n8n instances in the queue mode cluster (2 mains + 1 worker). * * This tests the Prometheus-compatible /metrics endpoint exposure and * service discovery configuration in VictoriaMetrics. */ test('should scrape metrics from all n8n instances', async ({ services }) => { const obs = services.observability; // Expected targets: 2 mains + 1 worker = 3 instances const expectedTargets = 3; // ========== STEP 1: Wait for all targets to be healthy ========== // The 'up' metric indicates which targets are being scraped (1=up, 0=down) // Poll until all expected targets are healthy (containers may still be starting) const healthyTarget = await obs.metrics.waitForMetric('up', { timeoutMs: 90000, // Allow time for all containers to start and be scraped intervalMs: 2000, predicate: (results) => { const healthy = results.filter((r) => r.value === 1); console.log( `Waiting for healthy targets: ${healthy.length}/${expectedTargets}`, healthy.map((r) => r.labels.instance), ); return healthy.length >= expectedTargets; }, }); expect(healthyTarget, 'Expected all scrape targets to become healthy').toBeTruthy(); // ========== STEP 2: Verify final state ========== const allInstances = await obs.metrics.query('up'); const healthyTargets = allInstances.filter((m) => m.value === 1); console.log( `Final state: ${healthyTargets.length}/${allInstances.length} healthy targets:`, healthyTargets.map((m) => m.labels.instance), ); expect(healthyTargets.length).toBe(expectedTargets); }); /** * Test: Log streaming to VictoriaLogs in multi-main setup * * Verifies that log streaming can be configured via API and that events * are correctly delivered to VictoriaLogs via syslog protocol. * * This tests: * - Log streaming feature flag enablement * - Syslog destination configuration via REST API * - TCP syslog delivery from n8n to VictoriaLogs * - LogsQL query capability in VictoriaLogs */ test('should configure log streaming and receive events', async ({ api, services }) => { // ========== STEP 1: Enable log streaming feature ========== await api.enableFeature('logStreaming'); const obs = services.observability; // ========== STEP 2: Configure syslog destination ========== // Create a syslog destination pointing to VictoriaLogs const destination = await api.createSyslogDestination({ host: obs.syslog.host, port: obs.syslog.port, protocol: obs.syslog.protocol, label: 'Multi-main VictoriaLogs', }); console.log('Created syslog destination:', destination.id); console.log(` Target: ${obs.syslog.host}:${obs.syslog.port} (${obs.syslog.protocol})`); // ========== STEP 3: Send test message ========== // The test message triggers n8n to send a "n8n.destination.test" event const testResult = await api.testLogStreamingDestination(destination.id); expect(testResult, 'Test message should be sent successfully').toBe(true); console.log('Test message sent to log streaming destination'); // ========== STEP 4: Verify message arrives in VictoriaLogs ========== // Query VictoriaLogs for the test message using LogsQL const logEntry = await obs.logs.waitForLog('n8n.destination.test', { timeoutMs: 30000, }); expect(logEntry, 'Test message should appear in VictoriaLogs').toBeTruthy(); console.log('Test message received in VictoriaLogs:', logEntry?.message); // ========== CLEANUP ========== await api.deleteLogStreamingDestination(destination.id); console.log('Cleaned up syslog destination'); }); });