mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
Integrate Monolog: replace four logging systems with single PSR-3 factory
- Add monolog/monolog dependency (^3.10)
- Create app/Logger.php central factory with channels: app, admin, error, audit
- Each channel gets RotatingFileHandler (30-day retention) with pass-through LineFormatter
preserving existing JSON format contracts
- Rewrite AppLogger as thin facade delegating to Logger::get('app')
- Rewrite ErrorHandler::log() to delegate to Logger::get('error')
- Rewrite AdminLogger file output to delegate to Logger::get('admin'), keep DB writes
- Add Monolog file shadow to Audit via Logger::get('audit') (Option A per monolog-plan)
- Log level controlled by LOG_LEVEL env var (defaults: DEBUG in cli-server, WARNING otherwise)
- Graceful NullHandler fallback when log directory is not writable
- Update SystemController LOG_FILES: remove php_error, add app/admin/error/audit
- JSON app logs parsed to readable one-liners in the log viewer
- Remove nginx config tab (parametres + fragment + template + css)
- Friendly empty-state message when app log files don't exist yet (notYet)
- PHP tail fallback when exec() unavailable
- All 228 PHPUnit tests pass, no call sites changed
This commit is contained in:
@@ -34,6 +34,7 @@ class Audit
|
||||
?array $oldData = null,
|
||||
?array $newData = null
|
||||
): void {
|
||||
// DB write is the primary path — best-effort, never crash.
|
||||
try {
|
||||
$stmt = $db->getConnection()->prepare(
|
||||
'INSERT INTO audit_log (actor, action, table_name, record_id, old_data, new_data)
|
||||
@@ -49,7 +50,33 @@ class Audit
|
||||
]);
|
||||
} catch (\Throwable $e) {
|
||||
// Audit logging is best-effort — never crash the app over it.
|
||||
error_log('[Audit] write failed: ' . $e->getMessage());
|
||||
error_log('[Audit] DB write failed: ' . $e->getMessage());
|
||||
}
|
||||
|
||||
// File shadow — structured JSON-line log for debuggability
|
||||
// (Option A from monolog-plan: keep Audit DB logic as-is, add file trace)
|
||||
try {
|
||||
$entry = [
|
||||
'timestamp' => date('c'),
|
||||
'ip' => $_SERVER['REMOTE_ADDR'] ?? 'cli',
|
||||
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
|
||||
'actor' => $actor,
|
||||
'action' => $action,
|
||||
'table' => $tableName,
|
||||
'record_id' => $recordId,
|
||||
];
|
||||
if ($oldData !== null) {
|
||||
$entry['old_data'] = $oldData;
|
||||
}
|
||||
if ($newData !== null) {
|
||||
$entry['new_data'] = $newData;
|
||||
}
|
||||
|
||||
$line = json_encode($entry, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
|
||||
Logger::get('audit')->info($line);
|
||||
} catch (\Throwable $e) {
|
||||
// File shadow is also best-effort
|
||||
error_log('[Audit] file shadow write failed: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user