Files
2026-07-04 15:16:50 +02:00

89 lines
3.1 KiB
PHP

<?php
declare(strict_types=1);
final class PluginLogger
{
private static string $path = '';
public static function init(string $path): void
{
self::$path = $path;
self::ensureLogFile();
@ini_set('log_errors', '1');
@ini_set('error_log', $path);
set_error_handler(static function (int $severity, string $message, string $file, int $line): bool {
if ((error_reporting() & $severity) === 0) {
return false;
}
self::log('PHP_ERROR', self::severityName($severity) . ': ' . $message . ' in ' . $file . ':' . $line);
return false;
});
register_shutdown_function(static function (): void {
$error = error_get_last();
if (!is_array($error)) {
return;
}
$fatal = [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR];
if (in_array((int)($error['type'] ?? 0), $fatal, true)) {
self::log('PHP_FATAL', self::severityName((int)$error['type']) . ': ' . (string)$error['message'] . ' in ' . (string)$error['file'] . ':' . (string)$error['line']);
}
});
}
public static function exception(Throwable $e, string $context = 'UNCAUGHT'): void
{
self::log($context, get_class($e) . ': ' . $e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() . "\n" . $e->getTraceAsString());
}
public static function log(string $level, string $message): void
{
$path = self::$path !== '' ? self::$path : (defined('PLUGIN_ROOT') ? PLUGIN_ROOT . '/plugin.log' : __DIR__ . '/../../plugin.log');
$line = '[' . gmdate('c') . '] ' . $level . ' ' . str_replace(["\r\n", "\r"], "\n", $message) . "\n";
$ok = @file_put_contents($path, $line, FILE_APPEND | LOCK_EX);
if ($ok !== false && is_file($path)) {
@chmod($path, 0600);
}
}
private static function severityName(int $severity): string
{
return match ($severity) {
E_ERROR => 'E_ERROR',
E_WARNING => 'E_WARNING',
E_PARSE => 'E_PARSE',
E_NOTICE => 'E_NOTICE',
E_CORE_ERROR => 'E_CORE_ERROR',
E_CORE_WARNING => 'E_CORE_WARNING',
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
E_USER_ERROR => 'E_USER_ERROR',
E_USER_WARNING => 'E_USER_WARNING',
E_USER_NOTICE => 'E_USER_NOTICE',
E_STRICT => 'E_STRICT',
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
E_DEPRECATED => 'E_DEPRECATED',
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
default => 'E_' . $severity,
};
}
private static function ensureLogFile(): void
{
if (self::$path === '') {
return;
}
$dir = dirname(self::$path);
if (!is_dir($dir) || !is_writable($dir)) {
return;
}
if (!is_file(self::$path)) {
@file_put_contents(self::$path, '');
}
if (is_file(self::$path)) {
@chmod(self::$path, 0600);
}
}
}