From a7a94f93d87fb7f6fc24c118989c7996b2ed9958 Mon Sep 17 00:00:00 2001 From: Sebastian Krupinski Date: Wed, 6 May 2026 12:24:53 -0400 Subject: [PATCH] fix: plain logging Signed-off-by: Sebastian Krupinski --- config/system.php | 6 +++--- core/lib/Logger/LoggerFactory.php | 2 +- core/lib/Logger/PlainFileLogger.php | 32 +++++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/config/system.php b/config/system.php index f78c16c..f4d4afd 100644 --- a/config/system.php +++ b/config/system.php @@ -57,15 +57,15 @@ return [ 'per_tenant' => false, // ── file driver options ──────────────────────────────────────────────── - // Absolute path to the log directory. null = /var/log + // Absolute path to the log directory. null = /var/logs 'path' => null, // Log channel — used as the filename without extension. - // 'app' → var/log/app.jsonl (or var/log/tenant/{id}/app.jsonl when per_tenant = true) + // 'app' → var/logs/app.jsonl (or var/logs/tenant/{id}/app.jsonl when per_tenant = true) 'channel' => 'app', // ── syslog driver options ────────────────────────────────────────────── - // Identity tag passed to openlog(); visible in /var/log/syslog and journalctl -t ktrix + // Identity tag passed to openlog(); visible in /var/logs/syslog and journalctl -t ktrix 'ident' => 'ktrix', // openlog() facility constant. Common values: LOG_USER, LOG_LOCAL0 … LOG_LOCAL7 diff --git a/core/lib/Logger/LoggerFactory.php b/core/lib/Logger/LoggerFactory.php index 9362f42..dee7d4f 100644 --- a/core/lib/Logger/LoggerFactory.php +++ b/core/lib/Logger/LoggerFactory.php @@ -79,7 +79,7 @@ class LoggerFactory $path = $logConfig['path'] ?? null; if ($path === null || $path === '') { - $path = $projectDir . '/var/log'; + $path = $projectDir . '/var/logs'; } return new FileLogger($path, $channel); diff --git a/core/lib/Logger/PlainFileLogger.php b/core/lib/Logger/PlainFileLogger.php index 89b5bce..7e32fdd 100644 --- a/core/lib/Logger/PlainFileLogger.php +++ b/core/lib/Logger/PlainFileLogger.php @@ -20,10 +20,8 @@ class PlainFileLogger implements LoggerInterface */ public function __construct(string $logDir, string $channel = 'app') { - if (!is_dir($logDir)) { - @mkdir($logDir, 0775, true); - } $this->logFile = rtrim($logDir, '/') . '/' . $channel . '.log'; + $this->ensureWritablePath(); } public function emergency($message, array $context = []): void { $this->log('emergency', $message, $context); } @@ -37,12 +35,38 @@ class PlainFileLogger implements LoggerInterface public function log($level, $message, array $context = []): void { + $this->ensureWritablePath(); + $dt = \DateTimeImmutable::createFromFormat('U.u', sprintf('%.6F', microtime(true))); $timestamp = $dt?->format('Y-m-d H:i:s.u') ?? date('Y-m-d H:i:s'); $line = $timestamp . ' ' . $this->interpolate((string) $message, $context) . PHP_EOL; - @file_put_contents($this->logFile, $line, FILE_APPEND | LOCK_EX); + if (@file_put_contents($this->logFile, $line, FILE_APPEND | LOCK_EX) === false) { + error_log(sprintf('Failed to write to log file: %s', $this->logFile)); + } + } + + private function ensureWritablePath(): void + { + $logDir = dirname($this->logFile); + + if (!is_dir($logDir)) { + @mkdir($logDir, 0777, true); + } + + if (is_dir($logDir)) { + @chmod($logDir, 0777); + } + + if (!file_exists($this->logFile)) { + @touch($this->logFile); + } + + clearstatcache(true, $this->logFile); + if (file_exists($this->logFile)) { + @chmod($this->logFile, 0666); + } } private function interpolate(string $message, array $context): string