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.

This commit is contained in:
Torsten Schulz (local)
2025-12-23 10:56:14 +01:00
parent 08563c956c
commit 431a6aff08

View File

@@ -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<Option<Instant>> = 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<Option<Instant>> = 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(())
}