<?php
declare(strict_types=1);
/**
* Class to add entries to the event log. Technically this class belongs to the
* eventlog module, but since it is used in so many places, this helper resides
* in the general inc directory instead of the eventlog's inc directory, since
* that would require to add "if (Module::isAvailable('eventlog')) { ... }"
* all over the place. Instead, the availability check was moved here.
*/
class EventLog
{
private static function log(string $type, string $message, string $details, bool $markWarning): void
{
if (!Module::isAvailable('eventlog')) {
// Eventlog module does not exist; the eventlog table might not exist, so bail out
error_log($message);
return;
}
if (mb_strlen($message) > 255) {
$message = mb_substr($message, 0, 255);
}
if (mb_strlen($details) > 65535) {
$details = mb_substr($details, 0, 65535);
}
$data = [
'type' => $type,
'message' => $message,
'details' => $details,
];
if (Database::exec("INSERT INTO eventlog (dateline, logtypeid, description, extra)"
. " VALUES (UNIX_TIMESTAMP(), :type, :message, :details)", $data, true) === false) {
error_log($message);
} else {
// Insert ok, see if we should update the "latest warning" id
$id = Database::lastInsertId();
if ($id !== 0 && $markWarning) {
Property::setLastWarningId($id);
}
}
self::applyFilterRules('#serverlog', $data);
}
public static function failure(string $message, string $details = ''): void
{
self::log('failure', $message, $details, true);
}
public static function warning(string $message, string $details = ''): void
{
self::log('warning', $message, $details, true);
}
public static function info(string $message, string $details = ''): void
{
self::log('info', $message, $details, false);
}
/**
* DELETE ENTIRE EVENT LOG!
*/
public static function clear(): void
{
if (!Module::isAvailable('eventlog'))
return;
Database::exec("TRUNCATE eventlog");
}
/**
* @param string $type the event. Will either be client state like ~poweron, ~runstate etc. or a client log type
* @param array $data A structured array containing event specific data that can be matched.
*/
public static function applyFilterRules(string $type, array $data): void
{
if (!Module::isAvailable('eventlog'))
return;
FilterRuleProcessor::applyFilterRules($type, $data);
}
}