fix(Discovery): Add comprehensive debug logging for router initialization
- Add initializer count logging in DiscoveryServiceBootstrapper - Add route structure analysis in RouterSetup - Add request parameter logging in HttpRouter - Update PHP production config for better OPcache handling - Fix various config and error handling improvements
This commit is contained in:
@@ -51,8 +51,13 @@ final readonly class ErrorHandler
|
||||
?SecurityEventHandler $securityHandler = null
|
||||
) {
|
||||
$this->isDebugMode = $isDebugMode ?? $this->getDebugModeFromEnvironment();
|
||||
$this->logger = new ErrorLogger($logger);
|
||||
$this->securityHandler = $securityHandler ?? SecurityEventHandler::createDefault($logger);
|
||||
|
||||
// Get Logger and AppConfig from container if not provided
|
||||
$logger = $logger ?? $container->get(Logger::class);
|
||||
$appConfig = $container->get(\App\Framework\Config\AppConfig::class);
|
||||
|
||||
$this->logger = new ErrorLogger($logger, $appConfig);
|
||||
$this->securityHandler = $securityHandler ?? SecurityEventHandler::createDefault($logger, $appConfig);
|
||||
}
|
||||
|
||||
public function register(): void
|
||||
@@ -456,9 +461,12 @@ final readonly class ErrorHandler
|
||||
}
|
||||
}
|
||||
|
||||
// Get AppConfig from container
|
||||
$appConfig = $this->container->get(\App\Framework\Config\AppConfig::class);
|
||||
|
||||
$htmlRenderer = $templateRenderer ?
|
||||
new ErrorTemplateRenderer($templateRenderer) :
|
||||
new ErrorTemplateRenderer(new DummyTemplateRenderer());
|
||||
new ErrorTemplateRenderer($templateRenderer, $appConfig) :
|
||||
new ErrorTemplateRenderer(new DummyTemplateRenderer(), $appConfig);
|
||||
|
||||
$apiRenderer = new ApiErrorRenderer();
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\ErrorHandling;
|
||||
|
||||
use App\Framework\Config\AppConfig;
|
||||
use App\Framework\Exception\Core\ErrorSeverity;
|
||||
use App\Framework\Exception\ErrorHandlerContext;
|
||||
use App\Framework\Logging\Logger;
|
||||
@@ -16,7 +17,8 @@ use App\Framework\Logging\ValueObjects\LogContext;
|
||||
final readonly class ErrorLogger
|
||||
{
|
||||
public function __construct(
|
||||
private ?Logger $logger = null
|
||||
private Logger $logger,
|
||||
private AppConfig $appConfig
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -42,13 +44,8 @@ final readonly class ErrorLogger
|
||||
'additionalData' => $context->additionalData,
|
||||
];
|
||||
|
||||
if ($this->logger !== null) {
|
||||
$logLevel = $this->mapErrorSeverityToLogLevel($context->level);
|
||||
$this->logger->log($logLevel, $message, $contextData);
|
||||
} else {
|
||||
// Fallback auf error_log
|
||||
$this->logToErrorLog($context);
|
||||
}
|
||||
$logLevel = $this->mapErrorSeverityToLogLevel($context->level);
|
||||
$this->logger->log($logLevel, $message, $contextData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -73,23 +70,18 @@ final readonly class ErrorLogger
|
||||
);
|
||||
|
||||
|
||||
if ($this->logger !== null) {
|
||||
$logLevel = $this->determineLogLevel($context);
|
||||
$logLevel = $this->determineLogLevel($context);
|
||||
|
||||
// Erstelle LogContext mit strukturierten Daten
|
||||
$logContext = LogContext::withData($logData)
|
||||
->addTags('error_handler', 'framework');
|
||||
// Erstelle LogContext mit strukturierten Daten
|
||||
$logContext = LogContext::withData($logData)
|
||||
->addTags('error_handler', 'framework');
|
||||
|
||||
// Füge Metadaten-Tags hinzu
|
||||
if ($context->exception->metadata['security_event'] ?? false) {
|
||||
$logContext = $logContext->addTags('security');
|
||||
}
|
||||
|
||||
$this->logger->log($logLevel, $message, $logContext);
|
||||
} else {
|
||||
// Fallback auf error_log
|
||||
$this->logHandlerContextToErrorLog($context);
|
||||
// Füge Metadaten-Tags hinzu
|
||||
if ($context->exception->metadata['security_event'] ?? false) {
|
||||
$logContext = $logContext->addTags('security');
|
||||
}
|
||||
|
||||
$this->logger->log($logLevel, $message, $logContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -97,18 +89,13 @@ final readonly class ErrorLogger
|
||||
*/
|
||||
private function logSecurityEvent(ErrorHandlerContext $context): void
|
||||
{
|
||||
$securityLog = $context->toSecurityEventFormat($_ENV['APP_NAME'] ?? 'app');
|
||||
$securityLog = $context->toSecurityEventFormat($this->appConfig->name);
|
||||
|
||||
if ($this->logger !== null) {
|
||||
// Verwende LogContext für strukturiertes Security Event Logging
|
||||
$logContext = LogContext::withData($securityLog)
|
||||
->addTags('security_event', 'owasp');
|
||||
// Verwende LogContext für strukturiertes Security Event Logging
|
||||
$logContext = LogContext::withData($securityLog)
|
||||
->addTags('security_event', 'owasp');
|
||||
|
||||
$this->logger->log(LogLevel::WARNING, 'Security Event Detected', $logContext);
|
||||
} else {
|
||||
// Fallback nur als letzte Option
|
||||
error_log('SECURITY_EVENT: ' . json_encode($securityLog, JSON_UNESCAPED_SLASHES));
|
||||
}
|
||||
$this->logger->log(LogLevel::WARNING, 'Security Event Detected', $logContext);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,51 +151,6 @@ final readonly class ErrorLogger
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback-Methode für ErrorHandlerContext ohne Framework Logger
|
||||
*/
|
||||
private function logHandlerContextToErrorLog(ErrorHandlerContext $context): void
|
||||
{
|
||||
$message = sprintf(
|
||||
'[%s] [%s] %s: %s',
|
||||
date('Y-m-d H:i:s'),
|
||||
$context->exception->metadata['error_level'] ?? 'ERROR',
|
||||
$context->exception->component ?? 'Application',
|
||||
$this->extractExceptionMessage($context)
|
||||
);
|
||||
|
||||
error_log($message);
|
||||
|
||||
// Security Events auch separat loggen
|
||||
if ($context->exception->metadata['security_event'] ?? false) {
|
||||
$securityLog = $context->toSecurityEventJson($_ENV['APP_NAME'] ?? 'app');
|
||||
error_log('SECURITY_EVENT: ' . $securityLog);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback-Methode für Logging ohne Framework Logger (Legacy)
|
||||
*/
|
||||
private function logToErrorLog(ErrorContext $context): void
|
||||
{
|
||||
$exception = $context->exception;
|
||||
$message = sprintf(
|
||||
'[%s] [%s] %s: %s in %s:%d',
|
||||
date('Y-m-d H:i:s'),
|
||||
$context->level->name,
|
||||
get_class($exception),
|
||||
$exception->getMessage(),
|
||||
$exception->getFile(),
|
||||
$exception->getLine()
|
||||
);
|
||||
|
||||
error_log($message);
|
||||
|
||||
// Bei kritischen Fehlern auch den Stacktrace loggen
|
||||
if ($context->level === ErrorSeverity::CRITICAL) {
|
||||
error_log("Stack trace: \n" . $exception->getTraceAsString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mappt ErrorSeverity auf Framework LogLevel
|
||||
|
||||
@@ -16,7 +16,7 @@ use Throwable;
|
||||
final readonly class SecurityEventHandler
|
||||
{
|
||||
public function __construct(
|
||||
private SecurityEventLogger $securityLogger,
|
||||
private ?SecurityEventLogger $securityLogger,
|
||||
private ?SecurityAlertManager $alertManager = null
|
||||
) {
|
||||
}
|
||||
@@ -28,6 +28,11 @@ final readonly class SecurityEventHandler
|
||||
SecurityException $exception,
|
||||
?MiddlewareContext $context = null
|
||||
): void {
|
||||
// Skip if no logger available
|
||||
if ($this->securityLogger === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Erstelle ErrorHandlerContext für OWASP-Format
|
||||
$errorHandlerContext = $this->createErrorHandlerContext($exception, $context);
|
||||
@@ -71,7 +76,7 @@ final readonly class SecurityEventHandler
|
||||
): void {
|
||||
if ($this->alertManager) {
|
||||
$this->alertManager->sendAlert($exception, $context);
|
||||
} else {
|
||||
} elseif ($this->securityLogger !== null) {
|
||||
// Fallback: Logge als kritisches Event
|
||||
$this->securityLogger->logCriticalAlert($exception, $context);
|
||||
}
|
||||
@@ -135,9 +140,16 @@ final readonly class SecurityEventHandler
|
||||
/**
|
||||
* Factory-Methode mit Standard-Konfiguration
|
||||
*/
|
||||
public static function createDefault(?Logger $logger = null): self
|
||||
public static function createDefault(?Logger $logger = null, ?\App\Framework\Config\AppConfig $appConfig = null): self
|
||||
{
|
||||
$securityLogger = new SecurityEventLogger($logger);
|
||||
// If AppConfig not provided, we can't create SecurityEventLogger properly
|
||||
// This is a temporary solution - ideally AppConfig should always be provided
|
||||
if ($logger === null || $appConfig === null) {
|
||||
// Return a minimal handler without SecurityEventLogger
|
||||
return new self(null, null);
|
||||
}
|
||||
|
||||
$securityLogger = new SecurityEventLogger($logger, $appConfig);
|
||||
$alertManager = null; // Kann später konfiguriert werden
|
||||
|
||||
return new self($securityLogger, $alertManager);
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\ErrorHandling;
|
||||
|
||||
use App\Framework\Config\AppConfig;
|
||||
use App\Framework\Exception\ErrorHandlerContext;
|
||||
use App\Framework\Exception\SecurityException;
|
||||
use App\Framework\Exception\SecurityLogLevel;
|
||||
@@ -16,8 +17,8 @@ use App\Framework\Logging\LogLevel;
|
||||
final readonly class SecurityEventLogger
|
||||
{
|
||||
public function __construct(
|
||||
private ?Logger $logger = null,
|
||||
private string $applicationId = 'app'
|
||||
private Logger $logger,
|
||||
private AppConfig $appConfig
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -33,26 +34,21 @@ final readonly class SecurityEventLogger
|
||||
// OWASP-konformes Log generieren
|
||||
$owaspLog = $this->createOWASPLog($exception, $context);
|
||||
|
||||
if ($this->logger) {
|
||||
// Strukturiertes Logging über Framework Logger
|
||||
$frameworkLogLevel = $this->mapSecurityLevelToFrameworkLevel($securityEvent->getLogLevel());
|
||||
// Strukturiertes Logging über Framework Logger
|
||||
$frameworkLogLevel = $this->mapSecurityLevelToFrameworkLevel($securityEvent->getLogLevel());
|
||||
|
||||
$this->logger->log(
|
||||
$frameworkLogLevel,
|
||||
$securityEvent->getDescription(),
|
||||
[
|
||||
'security_event' => $securityEvent->getEventIdentifier(),
|
||||
'security_category' => $securityEvent->getCategory(),
|
||||
'requires_alert' => $securityEvent->requiresAlert(),
|
||||
'owasp_format' => $owaspLog,
|
||||
'event_data' => $securityEvent->toArray(),
|
||||
'context_data' => $context->forLogging(),
|
||||
]
|
||||
);
|
||||
} else {
|
||||
// Fallback auf error_log
|
||||
$this->logToErrorLog($owaspLog);
|
||||
}
|
||||
$this->logger->log(
|
||||
$frameworkLogLevel,
|
||||
$securityEvent->getDescription(),
|
||||
[
|
||||
'security_event' => $securityEvent->getEventIdentifier(),
|
||||
'security_category' => $securityEvent->getCategory(),
|
||||
'requires_alert' => $securityEvent->requiresAlert(),
|
||||
'owasp_format' => $owaspLog,
|
||||
'event_data' => $securityEvent->toArray(),
|
||||
'context_data' => $context->forLogging(),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,15 +60,11 @@ final readonly class SecurityEventLogger
|
||||
): void {
|
||||
$alertData = $this->createAlertData($exception, $context);
|
||||
|
||||
if ($this->logger) {
|
||||
$this->logger->log(
|
||||
LogLevel::CRITICAL,
|
||||
'SECURITY_ALERT: ' . $exception->getSecurityEvent()->getEventIdentifier(),
|
||||
$alertData
|
||||
);
|
||||
} else {
|
||||
error_log('SECURITY_ALERT: ' . json_encode($alertData));
|
||||
}
|
||||
$this->logger->log(
|
||||
LogLevel::CRITICAL,
|
||||
'SECURITY_ALERT: ' . $exception->getSecurityEvent()->getEventIdentifier(),
|
||||
$alertData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,7 +78,7 @@ final readonly class SecurityEventLogger
|
||||
|
||||
return [
|
||||
'datetime' => date('c'),
|
||||
'appid' => $this->applicationId,
|
||||
'appid' => $this->appConfig->name,
|
||||
'event' => $securityEvent->getEventIdentifier(),
|
||||
'level' => $securityEvent->getLogLevel()->value,
|
||||
'description' => $securityEvent->getDescription(),
|
||||
@@ -98,8 +90,6 @@ final readonly class SecurityEventLogger
|
||||
'port' => $context->request->port,
|
||||
'request_uri' => $context->request->requestUri,
|
||||
'request_method' => $context->request->requestMethod,
|
||||
'region' => $_ENV['AWS_REGION'] ?? 'unknown',
|
||||
'geo' => $_ENV['GEO_LOCATION'] ?? 'unknown',
|
||||
'category' => $securityEvent->getCategory(),
|
||||
'requires_alert' => $securityEvent->requiresAlert(),
|
||||
];
|
||||
@@ -127,15 +117,6 @@ final readonly class SecurityEventLogger
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback-Logging über error_log
|
||||
*/
|
||||
private function logToErrorLog(array $owaspLog): void
|
||||
{
|
||||
$logMessage = 'SECURITY_EVENT: ' . json_encode($owaspLog, JSON_UNESCAPED_SLASHES);
|
||||
error_log($logMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mappt SecurityLogLevel auf Framework LogLevel
|
||||
*/
|
||||
@@ -150,15 +131,4 @@ final readonly class SecurityEventLogger
|
||||
SecurityLogLevel::FATAL => LogLevel::CRITICAL,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Factory-Methode für Standard-Konfiguration
|
||||
*/
|
||||
public static function create(?Logger $logger = null): self
|
||||
{
|
||||
return new self(
|
||||
$logger,
|
||||
$_ENV['APP_NAME'] ?? $_ENV['APP_ID'] ?? 'app'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\ErrorHandling\View;
|
||||
|
||||
use App\Framework\Config\AppConfig;
|
||||
use App\Framework\Core\ValueObjects\Byte;
|
||||
use App\Framework\Core\ValueObjects\Duration;
|
||||
use App\Framework\ErrorHandling\StackTrace;
|
||||
@@ -23,6 +24,7 @@ final readonly class ErrorTemplateRenderer implements ErrorViewRendererInterface
|
||||
{
|
||||
public function __construct(
|
||||
private TemplateRenderer $renderer,
|
||||
private AppConfig $appConfig,
|
||||
private string $debugTemplate = 'enhanced-debug',
|
||||
private string $productionTemplate = 'production'
|
||||
) {
|
||||
@@ -65,7 +67,7 @@ final readonly class ErrorTemplateRenderer implements ErrorViewRendererInterface
|
||||
'userAgent' => (string) ($context->request->userAgent ?? 'Unknown'),
|
||||
'traceCount' => 0, // Will be updated below if trace is available
|
||||
// Environment information
|
||||
'environment' => $_ENV['APP_ENV'] ?? 'development',
|
||||
'environment' => $this->appConfig->type->value,
|
||||
'debugMode' => $isDebug ? 'Enabled' : 'Disabled',
|
||||
'phpVersion' => PHP_VERSION,
|
||||
'frameworkVersion' => '1.0.0-dev',
|
||||
|
||||
Reference in New Issue
Block a user