docs: consolidate documentation into organized structure

- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
This commit is contained in:
2025-10-05 11:05:04 +02:00
parent 887847dde6
commit 5050c7d73a
36686 changed files with 196456 additions and 12398919 deletions

View File

@@ -5,6 +5,9 @@ declare(strict_types=1);
namespace App\Framework\Logging;
use App\Framework\Attributes\Singleton;
use App\Framework\Logging\ValueObjects\LogContext;
use DateMalformedStringException;
use DateTimeImmutable;
use DateTimeZone;
/**
@@ -13,55 +16,73 @@ use DateTimeZone;
#[Singleton]
final readonly class DefaultLogger implements Logger
{
public ChannelLogger $security;
public ChannelLogger $cache;
public ChannelLogger $database;
public ChannelLogger $framework;
public ChannelLogger $error;
/**
* @param LogLevel $minLevel Minimales Level, das geloggt werden soll
* @param array<LogHandler> $handlers Array von Log-Handlern
* @param ProcessorManager $processorManager Optional: Processor Manager für die Verarbeitung
* @param ProcessorManager $processorManager Processor Manager für die Verarbeitung
* @param LogContextManager|null $contextManager Optional: Context Manager für automatische Kontext-Anreicherung
*/
public function __construct(
private LogLevel $minLevel = LogLevel::DEBUG,
private LogLevel $minLevel = LogLevel::DEBUG,
/** @var LogHandler[] */
private array $handlers = [],
private ProcessorManager $processorManager = new ProcessorManager(),
private array $handlers = [],
private ProcessorManager $processorManager = new ProcessorManager(),
private ?LogContextManager $contextManager = null,
) {
// Channel-Logger initialisieren
$this->security = new DefaultChannelLogger($this, LogChannel::SECURITY);
$this->cache = new DefaultChannelLogger($this, LogChannel::CACHE);
$this->database = new DefaultChannelLogger($this, LogChannel::DATABASE);
$this->framework = new DefaultChannelLogger($this, LogChannel::FRAMEWORK);
$this->error = new DefaultChannelLogger($this, LogChannel::ERROR);
}
public function debug(string $message, array $context = []): void
public function debug(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::DEBUG, $message, $context);
}
public function info(string $message, array $context = []): void
public function info(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::INFO, $message, $context);
}
public function notice(string $message, array $context = []): void
public function notice(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::NOTICE, $message, $context);
}
public function warning(string $message, array $context = []): void
public function warning(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::WARNING, $message, $context);
}
public function error(string $message, array $context = []): void
public function error(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::ERROR, $message, $context);
}
public function critical(string $message, array $context = []): void
public function critical(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::CRITICAL, $message, $context);
}
public function alert(string $message, array $context = []): void
public function alert(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::ALERT, $message, $context);
}
public function emergency(string $message, array $context = []): void
public function emergency(string $message, ?LogContext $context = null): void
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}
@@ -71,16 +92,30 @@ final readonly class DefaultLogger implements Logger
*
* @param LogLevel $level Log-Level
* @param string $message Log-Nachricht
* @param array $context Kontext-Daten für Platzhalter-Ersetzung
* @param LogContext|null $context Strukturierter LogContext
* @throws DateMalformedStringException
*/
public function log(LogLevel $level, string $message, array $context = []): void
public function log(LogLevel $level, string $message, ?LogContext $context = null): void
{
// Wenn kein Context übergeben, leeren Context erstellen
if ($context === null) {
$context = LogContext::empty();
}
// Prüfen ob Level hoch genug ist
if ($level->isLowerThan($this->minLevel)) {
return;
}
// LogContext automatisch mit aktuellem Context anreichern
$finalContext = $this->enrichWithCurrentContext($context);
// Log-Record erstellen
$record = new LogRecord(
message: $message,
context: $context,
context: $finalContext,
level: $level,
timestamp: new \DateTimeImmutable(timezone: new DateTimeZone('Europe/Berlin')),
timestamp: new DateTimeImmutable(timezone: new DateTimeZone('Europe/Berlin')),
);
// Record durch alle Processors verarbeiten
@@ -94,6 +129,132 @@ final readonly class DefaultLogger implements Logger
}
}
/**
* Loggt in einen spezifischen Channel
*
* @internal Wird von ChannelLogger verwendet
*/
public function logToChannel(LogChannel $channel, LogLevel $level, string $message, ?LogContext $context = null): void
{
// Wenn kein Context übergeben, leeren Context erstellen
if ($context === null) {
$context = LogContext::empty();
}
// Prüfen, ob Level hoch genug ist
if ($level->isLowerThan($this->minLevel)) {
return;
}
// LogContext automatisch mit aktuellem Context anreichern
$finalContext = $this->enrichWithCurrentContext($context);
// Log-Record erstellen mit Channel
$record = new LogRecord(
message: $message,
context: $finalContext,
level: $level,
timestamp: new DateTimeImmutable(timezone: new DateTimeZone('Europe/Berlin')),
channel: $channel->value
);
// Record durch alle Processors verarbeiten
$processedRecord = $this->processorManager->processRecord($record);
// Alle Handler durchlaufen
foreach ($this->handlers as $handler) {
if ($handler->isHandling($processedRecord)) {
$handler->handle($processedRecord);
}
}
}
/**
* Reichert den übergebenen Context mit dem aktuellen Context vom LogContextManager an
*/
private function enrichWithCurrentContext(LogContext $context): LogContext
{
// Wenn kein ContextManager verfügbar ist, Context unverändert zurückgeben
if ($this->contextManager === null) {
return $context;
}
$currentContext = $this->contextManager->getCurrentContext();
// Wenn der übergebene Context ein LogContext ist, mit aktuellem Context mergen
return $currentContext->merge($context);
}
/**
* Konvertiert LogContext zu Array für Legacy-Kompatibilität
* @deprecated
*/
private function convertLogContextToArray(LogContext $logContext): array
{
$context = $logContext->structured;
// Tags hinzufügen
if ($logContext->hasTags()) {
$context['_tags'] = $logContext->tags;
}
// Trace-Informationen hinzufügen
if ($logContext->trace !== null) {
$context['_trace_id'] = $logContext->trace->getTraceId();
if ($activeSpan = $logContext->trace->getActiveSpan()) {
$context['_span_id'] = $activeSpan->spanId;
}
}
// User-Kontext hinzufügen
if ($logContext->user !== null) {
$context['_user_id'] = $logContext->user->userId ?? null;
}
// Request-Kontext hinzufügen
if ($logContext->request !== null) {
$context['_request_id'] = $logContext->request->requestId ?? null;
}
return array_merge($context, $logContext->metadata);
}
/**
* Reichert LogRecord mit strukturierten Daten aus LogContext an
*/
private function enrichRecordWithLogContext(LogRecord $record, LogContext $logContext): LogRecord
{
// Tags als Extra hinzufügen
if ($logContext->hasTags()) {
$record->addExtra('structured_tags', $logContext->tags);
}
// Trace-Kontext als Extra hinzufügen
if ($logContext->trace !== null) {
$record->addExtra('trace_context', [
'trace_id' => $logContext->trace->getTraceId(),
'active_span' => $logContext->trace->getActiveSpan()?->toArray(),
]);
}
// User-Kontext als Extra hinzufügen
if ($logContext->user !== null) {
$record->addExtra('user_context', $logContext->user->toArray());
}
// Request-Kontext als Extra hinzufügen
if ($logContext->request !== null) {
$record->addExtra('request_context', $logContext->request->toArray());
}
// Metadaten als Extra hinzufügen
if (! empty($logContext->metadata)) {
$record->addExtras($logContext->metadata);
}
return $record;
}
/**
* Gibt die aktuelle Konfiguration des Loggers zurück
*/