From 431a6aff08674f2c2b3fa52d55b0a1c1c0343c6e Mon Sep 17 00:00:00 2001 From: "Torsten Schulz (local)" Date: Tue, 23 Dec 2025 10:56:14 +0100 Subject: [PATCH] Implement heartbeat logging in EventsWorker: Add periodic logging to monitor the worker's activity and event triggering status. Introduce Mutex for thread-safe access to heartbeat timestamps, enhancing visibility into the worker's operational state. --- src/worker/events.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/worker/events.rs b/src/worker/events.rs index 21b4d6b..aeff0eb 100644 --- a/src/worker/events.rs +++ b/src/worker/events.rs @@ -5,6 +5,7 @@ use rand::seq::SliceRandom; use serde_json::json; use std::sync::atomic::Ordering; use std::sync::Arc; +use std::sync::Mutex; use std::time::{Duration, Instant}; use super::base::{BaseWorker, Worker, WorkerState}; @@ -393,6 +394,7 @@ impl EventsWorker { let mut last_event_check = None; let mut rng = rand::thread_rng(); let events = Self::initialize_events(); + eprintln!("[EventsWorker] Worker-Thread gestartet"); loop { if !state.running_worker.load(Ordering::Relaxed) { @@ -401,6 +403,20 @@ impl EventsWorker { let now = Instant::now(); + // Heartbeat im Run-Loop (unabhängig davon, ob Events triggern) + // Damit man sofort sieht, ob der Worker überhaupt läuft. + static LAST_RUNLOOP_HEARTBEAT: Mutex> = Mutex::new(None); + { + let mut last = LAST_RUNLOOP_HEARTBEAT.lock().unwrap(); + let should_log = last + .map(|t| t.elapsed().as_secs() >= 3600) + .unwrap_or(true); + if should_log { + eprintln!("[EventsWorker] RunLoop Heartbeat: alive"); + *last = Some(Instant::now()); + } + } + // Ereignisse einmal pro Minute prüfen if should_run_interval(last_event_check, now, Duration::from_secs(60)) { if let Err(err) = Self::check_and_trigger_events_inner( @@ -450,12 +466,37 @@ impl EventsWorker { events: &[RandomEvent], ) -> Result<(), DbError> { let rate_scale = Self::event_rate_scale(); + // Einmalige/gedrosselte Debug-Ausgaben, damit sichtbar ist, dass der Worker läuft + // und welche Skalierung aktiv ist. + static LAST_HEARTBEAT: Mutex> = Mutex::new(None); + // optional counter; keep it underscore-prefixed to avoid unused warnings + let mut _triggered = 0usize; + + { + let mut last = LAST_HEARTBEAT.lock().unwrap(); + let should_log = last + .map(|t| t.elapsed().as_secs() >= 3600) + .unwrap_or(true); + if should_log { + if (rate_scale - 1.0).abs() > f64::EPSILON { + eprintln!( + "[EventsWorker] Heartbeat: EVENT_RATE_SCALE={} (ENV `EVENT_RATE_SCALE` gesetzt?)", + rate_scale + ); + } else { + eprintln!("[EventsWorker] Heartbeat: EVENT_RATE_SCALE=1.0"); + } + *last = Some(Instant::now()); + } + } + // Prüfe jedes mögliche Ereignis for event in events { // Zufällige Prüfung basierend auf Wahrscheinlichkeit let roll = rng.gen_range(0.0..=1.0); let effective_prob = event.probability_per_minute * rate_scale; if roll < effective_prob { + _triggered += 1; eprintln!( "[EventsWorker] Ereignis '{}' wurde ausgelöst (Wahrscheinlichkeit: {:.4}% -> skaliert {:.4}%)", event.id, @@ -474,6 +515,9 @@ impl EventsWorker { } } + // Wenn über längere Zeit kein Ereignis triggert, sieht man sonst keinerlei Logs. + // Das Heartbeat-Log oben zeigt Liveness; hier loggen wir bewusst nicht pro Minute. + Ok(()) }