logs: standardise log filenames to xamxam-{service}-{date}.log

This commit is contained in:
Pontoporeia
2026-08-24 11:34:34 +02:00
parent 7b6d79c133
commit d2cef85966
25 changed files with 442 additions and 83 deletions
+2 -2
View File
@@ -3,8 +3,8 @@
/**
* Admin audit logger.
*
* Writes JSON-lines to /var/log/xamxam.log (production) or
* storage/logs/admin.log (dev / cli-server).
* Writes JSON-lines to /var/log/xamxam/xamxam-admin-YYYY-MM-DD.log (production)
* or storage/logs/xamxam-admin.log (dev / cli-server).
*
* Each entry: timestamp, actor (admin IP/UA), action, resource, status, context.
*
+70 -11
View File
@@ -26,25 +26,39 @@ class SystemController
'admin' => ['label' => 'Admin — actions', 'path' => null, 'json' => true],
'error' => ['label' => 'Erreurs — application', 'path' => null, 'json' => true],
'audit' => ['label' => 'Audit — données', 'path' => null, 'json' => true],
'nginx_access' => ['label' => 'nginx — accès', 'path' => '/var/log/nginx/xamxam_access.log', 'json' => false],
'nginx_error' => ['label' => 'nginx — erreurs','path' => '/var/log/nginx/xamxam_error.log', 'json' => false],
'nginx_access' => ['label' => 'nginx — accès', 'path' => '/var/log/nginx/xamxam-nginx-access.log', 'json' => false],
'nginx_error' => ['label' => 'nginx — erreurs','path' => '/var/log/nginx/xamxam-nginx-error.log', 'json' => false],
];
/**
* Resolve a log file path — app logs live under STORAGE_ROOT, system logs
* have hard-coded paths (only valid in production).
* Resolve a log file path — app logs live under /var/log/xamxam in
* production (and storage/logs in dev/cli-server); nginx logs have
* hard-coded paths (only valid in production).
*
* A $date (YYYY-MM-DD) selects a specific retained daily file for app
* channels; when null the most recent file is returned.
*/
private static function resolveLogPath(string $tab): string
private static function resolveLogPath(string $tab, ?string $date = null): string
{
$def = self::LOG_FILES[$tab];
if ($def['path'] !== null) {
return $def['path'];
}
// App logs: storage/logs/{channel}.log (Monolog RotatingFileHandler uses
// this as base name; the current log is always at {channel}-YYYY-MM-DD.log)
$dir = defined('STORAGE_ROOT') ? STORAGE_ROOT . '/logs' : APP_ROOT . '/storage/logs';
// App logs: /var/log/xamxam/xamxam-{channel}.log (production) or
// storage/logs/xamxam-{channel}.log (dev / cli-server). Monolog
// RotatingFileHandler uses this as base name; the current log is always
// at xamxam-{channel}-YYYY-MM-DD.log.
$dir = php_sapi_name() === 'cli-server'
? APP_ROOT . '/storage/logs'
: '/var/log/xamxam';
$base = $dir . '/xamxam-' . $tab;
// Explicit date selection (validated YYYY-MM-DD)
if ($date !== null && preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {
return $base . '-' . $date . '.log';
}
// Find the most recent dated log file for this channel
$base = $dir . '/' . $tab;
$dated = glob($base . '-20[0-9][0-9]-[0-9][0-9]-[0-9][0-9].log');
if (!empty($dated)) {
rsort($dated); // newest first
@@ -54,6 +68,49 @@ class SystemController
return $base . '.log';
}
/**
* List the retained daily log files (dates) for an app channel.
*
* Returns [['date' => 'YYYY-MM-DD', 'label' => '...'], …] newest-first.
* Empty array for system logs (nginx) which have fixed names.
*/
public static function listLogDates(string $tab): array
{
$def = self::LOG_FILES[$tab];
if (($def['json'] ?? false) !== true) {
return []; // nginx logs are fixed-name, not daily
}
$dir = php_sapi_name() === 'cli-server'
? APP_ROOT . '/storage/logs'
: '/var/log/xamxam';
$base = $dir . '/xamxam-' . $tab;
$dated = glob($base . '-20[0-9][0-9]-[0-9][0-9]-[0-9][0-9].log');
if (empty($dated)) {
return [];
}
$dates = [];
foreach ($dated as $path) {
if (preg_match('/(\d{4}-\d{2}-\d{2})\.log$/', $path, $m)) {
$dates[] = $m[1];
}
}
rsort($dates); // newest first
$out = [];
foreach ($dates as $d) {
$isToday = $d === date('Y-m-d');
$out[] = [
'date' => $d,
'label' => $isToday
? 'Aujourd\'hui (' . date('d/m/Y', strtotime($d)) . ')'
: date('d/m/Y', strtotime($d)),
];
}
return $out;
}
public const ALLOWED_LINES = [50, 100, 200, 500];
// ── TTLs ──────────────────────────────────────────────────────────────────
@@ -157,11 +214,13 @@ class SystemController
/**
* Read and return data for a log tab.
*
* @param string|null $date YYYY-MM-DD to select a specific daily file
* (app channels); null = most recent.
* @return array{lines: ?array, error: ?string, meta: ?array}
*/
public function getLogData(string $tab, int $n): array
public function getLogData(string $tab, int $n, ?string $date = null): array
{
$logPath = self::resolveLogPath($tab);
$logPath = self::resolveLogPath($tab, $date);
$isJson = self::LOG_FILES[$tab]['json'] ?? false;
$error = null;
$rawLines = null;
+10 -4
View File
@@ -55,7 +55,7 @@ class Logger
try {
$handler = new RotatingFileHandler(
$logDir . '/' . $channel . '.log',
$logDir . '/xamxam-' . $channel . '.log',
30, // keep 30 days of logs
self::level()
);
@@ -99,12 +99,18 @@ class Logger
/**
* Resolve the log directory.
*
* Production: /var/log/xamxam/ (standard system log root, provisioned by
* setup-server.sh; owned by www-data:xamxam). Dev (cli-server): the
* app's local storage/logs/ so no root provisioning is needed.
*/
private static function logDir(): string
{
if (defined('STORAGE_ROOT')) {
return STORAGE_ROOT . '/logs';
// cli-server (dev) → app-local storage/logs; everything else (php-fpm
// production) → the standard system log directory.
if (php_sapi_name() === 'cli-server') {
return __DIR__ . '/../storage/logs';
}
return __DIR__ . '/../storage/logs';
return '/var/log/xamxam';
}
}