Files
server-manager/src/Core/Logger.php
2026-06-06 17:58:34 -04:00

149 lines
3.9 KiB
PHP
Executable File

<?php
declare(strict_types=1);
namespace ServerManager\Core;
class Logger
{
private static ?Logger $instance = null;
private string $logPath;
private string $logLevel;
private array $levels = [
'debug' => 0,
'info' => 1,
'notice' => 2,
'warning' => 3,
'error' => 4,
'critical' => 5,
'alert' => 6,
'emergency' => 7,
];
private function __construct()
{
}
public static function getInstance(): self
{
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public static function init(string $path, string $level = 'warning'): void
{
$instance = self::getInstance();
$instance->logPath = rtrim($path, '/') . '/';
$instance->logLevel = $level;
if (!is_dir($instance->logPath)) {
mkdir($instance->logPath, 0750, true);
}
if (!is_writable($instance->logPath)) {
throw new \RuntimeException("Log path is not writable: {$instance->logPath}");
}
}
public function log(string $level, string $message, array $context = []): void
{
if (!$this->shouldLog($level)) {
return;
}
$timestamp = date('Y-m-d H:i:s');
$contextJson = !empty($context) ? ' ' . json_encode($context, JSON_UNESCAPED_SLASHES) : '';
$userInfo = $this->getUserInfo();
$logEntry = sprintf(
"[%s] %s.%s: %s%s %s\n",
$timestamp,
strtoupper($level),
$userInfo,
$message,
$contextJson,
$this->getRequestInfo()
);
$this->write($level, $logEntry);
}
public function debug(string $message, array $context = []): void
{
$this->log('debug', $message, $context);
}
public function info(string $message, array $context = []): void
{
$this->log('info', $message, $context);
}
public function notice(string $message, array $context = []): void
{
$this->log('notice', $message, $context);
}
public function warning(string $message, array $context = []): void
{
$this->log('warning', $message, $context);
}
public function error(string $message, array $context = []): void
{
$this->log('error', $message, $context);
}
public function critical(string $message, array $context = []): void
{
$this->log('critical', $message, $context);
}
public function alert(string $message, array $context = []): void
{
$this->log('alert', $message, $context);
}
public function emergency(string $message, array $context = []): void
{
$this->log('emergency', $message, $context);
}
private function shouldLog(string $level): bool
{
$currentLevel = $this->levels[$this->logLevel] ?? 3;
$messageLevel = $this->levels[$level] ?? 3;
return $messageLevel >= $currentLevel;
}
private function write(string $level, string $entry): void
{
$filename = $this->logPath . 'app-' . date('Y-m-d') . '.log';
file_put_contents($filename, $entry, FILE_APPEND | LOCK_EX);
if (in_array($level, ['error', 'critical', 'alert', 'emergency'], true)) {
$errorFile = $this->logPath . 'error-' . date('Y-m-d') . '.log';
file_put_contents($errorFile, $entry, FILE_APPEND | LOCK_EX);
}
}
private function getUserInfo(): string
{
$userId = Session::get('user_id');
$username = Session::get('username');
if ($userId) {
return "[User:{$userId}:{$username}]";
}
return '[Guest]';
}
private function getRequestInfo(): string
{
$ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
$method = $_SERVER['REQUEST_METHOD'] ?? 'CLI';
$uri = $_SERVER['REQUEST_URI'] ?? '';
return "[{$ip}] [{$method} {$uri}]";
}
}