Introduces Log Throtter to prevent log flooding

main
Yasen Pramatarov 2025-11-21 20:58:19 +02:00
parent c38e5ef4a6
commit 65a4dc7f18
2 changed files with 56 additions and 2 deletions

View File

@ -0,0 +1,50 @@
<?php
namespace App\Core;
require_once __DIR__ . '/Settings.php';
class LogThrottler
{
/**
* Log a message no more than once per interval.
*
* @param object $logger Logger implementing log($level, $message, array $context)
* @param mixed $db PDO or DatabaseConnector for Settings
* @param string $key Unique key for throttling (e.g. migrations_pending)
* @param int $intervalSeconds Minimum seconds between logs
* @param string $level Log level
* @param string $message Log message
* @param array $context Log context
*/
public static function logThrottled($logger, $db, string $key, int $intervalSeconds, string $level, string $message, array $context = []): void
{
if (!is_object($logger) || !method_exists($logger, 'log')) {
return;
}
$settings = null;
$shouldLog = true;
$settingsKey = 'log_throttle_' . $key;
try {
$settings = new Settings($db);
$lastLogged = $settings->get($settingsKey);
if ($lastLogged) {
$lastTimestamp = strtotime($lastLogged);
if ($lastTimestamp !== false && (time() - $lastTimestamp) < $intervalSeconds) {
$shouldLog = false;
}
}
} catch (\Throwable $e) {
$settings = null;
}
if ($shouldLog) {
$logger->log($level, $message, $context);
if ($settings) {
$settings->set($settingsKey, date('Y-m-d H:i:s'));
}
}
}
}

View File

@ -168,6 +168,10 @@ require_once __DIR__ . '/../app/core/DatabaseConnector.php';
use App\Core\DatabaseConnector;
$db = DatabaseConnector::connect($config);
// Initialize Log throttler
require_once __DIR__ . '/../app/core/LogThrottler.php';
use App\Core\LogThrottler;
// Logging: default to NullLogger, plugin can override
require_once __DIR__ . '/../app/core/NullLogger.php';
use App\Core\NullLogger;
@ -207,9 +211,9 @@ try {
}
}
}
// Log and show as a system message only if not already added
// Log (throttled) and show as a system message only if not already added
if (!$hasMigrationMessage) {
$logObject->log('warning', $msg, ['scope' => 'system']);
LogThrottler::logThrottled($logObject, $db, 'migrations_pending', 86400, 'warning', $msg, ['scope' => 'system']);
Feedback::flash('SYSTEM', 'MIGRATIONS_PENDING', $msg, false, true, false);
}
}