chore: complete update

This commit is contained in:
2025-07-17 16:24:20 +02:00
parent 899227b0a4
commit 64a7051137
1300 changed files with 85570 additions and 2756 deletions

View File

@@ -0,0 +1,137 @@
<?php
declare(strict_types=1);
namespace App\Framework\Logging\Handlers;
use App\Framework\Logging\LogHandler;
use App\Framework\Logging\LogLevel;
use App\Framework\Logging\LogRecord;
/**
* Handler für die Ausgabe von Log-Einträgen als JSON in Dateien.
* Besonders nützlich für maschinelle Verarbeitung und Log-Aggregatoren.
*/
class JsonFileHandler implements LogHandler
{
/**
* @var LogLevel Minimales Level, ab dem dieser Handler aktiv wird
*/
private LogLevel $minLevel;
/**
* @var string Pfad zur Log-Datei
*/
private string $logFile;
/**
* @var array Liste der Felder, die in der JSON-Ausgabe enthalten sein sollen
*/
private array $includedFields;
/**
* Erstellt einen neuen JsonFileHandler
*
* @param string $logFile Pfad zur Log-Datei
* @param LogLevel|int $minLevel Minimales Level, ab dem dieser Handler aktiv wird
* @param array|null $includedFields Liste der Felder, die in der JSON-Ausgabe enthalten sein sollen (null = alle)
*/
public function __construct(
string $logFile,
LogLevel|int $minLevel = LogLevel::INFO,
?array $includedFields = null
) {
$this->logFile = $logFile;
$this->minLevel = $minLevel instanceof LogLevel ? $minLevel : LogLevel::fromValue($minLevel);
// Standardfelder, falls nicht anders angegeben
$this->includedFields = $includedFields ?? [
'timestamp',
'level_name',
'message',
'context',
'extra',
'channel',
];
// Stelle sicher, dass das Verzeichnis existiert
$this->ensureDirectoryExists(dirname($logFile));
}
/**
* Überprüft, ob dieser Handler den Log-Eintrag verarbeiten soll
*/
public function isHandling(LogRecord $record): bool
{
return $record->getLevel()->value >= $this->minLevel->value;
}
/**
* Verarbeitet einen Log-Eintrag
*/
public function handle(LogRecord $record): void
{
// Alle Daten des Records als Array holen
$data = $record->toArray();
// Nur die gewünschten Felder behalten
if (!empty($this->includedFields)) {
$data = array_intersect_key($data, array_flip($this->includedFields));
}
// Zeitstempel als ISO 8601 formatieren für bessere Interoperabilität
if (isset($data['datetime']) && $data['datetime'] instanceof \DateTimeInterface) {
$data['timestamp_iso'] = $data['datetime']->format(\DateTimeInterface::ATOM);
unset($data['datetime']); // DateTime-Objekt entfernen
}
// Als JSON formatieren und in die Datei schreiben
$json = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR) . PHP_EOL;
$this->write($json);
}
/**
* Schreibt einen String in die Log-Datei
*/
protected function write(string $output): void
{
file_put_contents($this->logFile, $output, FILE_APPEND);
}
/**
* Stellt sicher, dass ein Verzeichnis existiert
*/
private function ensureDirectoryExists(string $dir): void
{
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
}
/**
* Minimales Log-Level setzen
*/
public function setMinLevel(LogLevel|int $level): self
{
$this->minLevel = $level instanceof LogLevel ? $level : LogLevel::fromValue($level);
return $this;
}
/**
* Setzt die Liste der Felder, die in der JSON-Ausgabe enthalten sein sollen
*/
public function setIncludedFields(array $fields): self
{
$this->includedFields = $fields;
return $this;
}
/**
* Log-Datei setzen
*/
public function setLogFile(string $logFile): self
{
$this->logFile = $logFile;
$this->ensureDirectoryExists(dirname($logFile));
return $this;
}
}