feat(monitoring): add snapshot collector to queue worker

Periodic metric collection running in the queue-worker PM2 process.
Collects system metrics every 60s (configurable), stores them in
MonitoringSnapshots, and evaluates alert rules against each snapshot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2026-02-15 00:34:28 +00:00
parent d252ed321a
commit 0615b22188
3 changed files with 74 additions and 0 deletions

View file

@ -39,6 +39,8 @@ module.exports = {
// Worker aktivieren/deaktivieren
QUEUE_ENABLE_EMAIL: 'true',
QUEUE_ENABLE_PDF: 'true',
QUEUE_ENABLE_MONITORING: 'true',
MONITORING_SNAPSHOT_INTERVAL: '60000',
// PDF-spezifische Optionen
PDF_OUTPUT_DIR: '/tmp/payload-pdfs',
// PDF_GENERATION_DISABLED: 'true', // Für Tests

View file

@ -43,6 +43,9 @@ async function main() {
const ENABLE_RETENTION_SCHEDULER = process.env.QUEUE_ENABLE_RETENTION_SCHEDULER !== 'false'
const ENABLE_YOUTUBE_UPLOAD_WORKER = process.env.QUEUE_ENABLE_YOUTUBE_UPLOAD !== 'false'
// Monitoring (optional)
const ENABLE_MONITORING = process.env.QUEUE_ENABLE_MONITORING !== 'false'
console.log('='.repeat(50))
console.log('[QueueRunner] Starting queue workers...')
console.log(`[QueueRunner] PID: ${process.pid}`)
@ -52,6 +55,7 @@ async function main() {
console.log(`[QueueRunner] Retention Worker: ${ENABLE_RETENTION_WORKER ? 'enabled' : 'disabled'}`)
console.log(`[QueueRunner] Retention Scheduler: ${ENABLE_RETENTION_SCHEDULER ? 'enabled' : 'disabled'}`)
console.log(`[QueueRunner] YouTube Upload Worker: ${ENABLE_YOUTUBE_UPLOAD_WORKER ? 'enabled' : 'disabled'}`)
console.log(`[QueueRunner] Monitoring Collector: ${ENABLE_MONITORING ? 'enabled' : 'disabled'}`)
console.log('='.repeat(50))
// Workers starten
@ -78,6 +82,15 @@ async function main() {
startYouTubeUploadWorker()
}
// Monitoring Snapshot Collector
if (ENABLE_MONITORING) {
const { startSnapshotCollector, stopSnapshotCollector } = await import('../src/lib/monitoring/snapshot-collector')
await startSnapshotCollector()
// Store stop function for shutdown
;(global as any).__stopSnapshotCollector = stopSnapshotCollector
}
// Graceful Shutdown
async function shutdown(signal: string) {
console.log(`\n[QueueRunner] Received ${signal}, shutting down gracefully...`)
@ -97,6 +110,9 @@ async function main() {
if (ENABLE_YOUTUBE_UPLOAD_WORKER) {
stopPromises.push(stopYouTubeUploadWorker())
}
if (ENABLE_MONITORING && (global as any).__stopSnapshotCollector) {
stopPromises.push((global as any).__stopSnapshotCollector())
}
await Promise.all(stopPromises)
console.log('[QueueRunner] All workers stopped')

View file

@ -0,0 +1,56 @@
/**
* Snapshot Collector
*
* Periodische Metrik-Erfassung, laeuft im Queue-Worker PM2-Prozess.
* Sammelt alle 60s (konfigurierbar) System-Metriken und speichert
* sie in MonitoringSnapshots. Evaluiert dabei Alert-Regeln.
*/
import { collectMetrics } from './monitoring-service.js'
import { AlertEvaluator } from './alert-evaluator.js'
let interval: ReturnType<typeof setInterval> | null = null
const alertEvaluator = new AlertEvaluator()
export async function startSnapshotCollector(): Promise<void> {
const INTERVAL = parseInt(process.env.MONITORING_SNAPSHOT_INTERVAL || '60000', 10)
console.log(`[SnapshotCollector] Starting (interval: ${INTERVAL}ms)`)
// Run immediately once, then on interval
await collectAndSave()
interval = setInterval(async () => {
await collectAndSave()
}, INTERVAL)
}
async function collectAndSave(): Promise<void> {
try {
const { getPayload } = await import('payload')
const config = (await import('@payload-config')).default
const payload = await getPayload({ config })
const metrics = await collectMetrics()
await payload.create({
collection: 'monitoring-snapshots',
data: {
timestamp: new Date().toISOString(),
...metrics,
},
})
// Evaluate alert rules against collected metrics
await alertEvaluator.evaluateRules(payload, metrics)
} catch (error) {
console.error('[SnapshotCollector] Error:', error)
}
}
export async function stopSnapshotCollector(): Promise<void> {
if (interval) {
clearInterval(interval)
interval = null
}
console.log('[SnapshotCollector] Stopped')
}