- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
12 KiB
12 KiB
Error Reporting & Analytics
Das Error Reporting System bietet strukturierte Fehlerberichterstattung und erweiterte Analytics für das Framework. Es erfasst, analysiert und visualisiert Fehler mit umfassendem Kontext für bessere Debugging- und Monitoring-Möglichkeiten.
Überblick
Das System implementiert folgende Funktionen:
- Strukturierte Fehlerberichte - Umfassende Kontext-Erfassung
- Analytics Engine - Trend-Analyse und Anomalie-Erkennung
- Predictive Insights - Vorhersagen und Empfehlungen
- Context Processors - Automatische Anreicherung mit Request/User-Kontext
- Storage Interface - Flexible Speicher-Implementierungen
- Console Commands - Management und Monitoring Tools
Basic Usage
Error Reporter
use App\Framework\ErrorReporting\ErrorReporter;
$reporter = $container->get(ErrorReporter::class);
// Report an exception
$reportId = $reporter->reportThrowable($exception);
// Report manual error
$reportId = $reporter->reportError('error', 'Something went wrong', [
'user_action' => 'delete_file',
'file_id' => 123
]);
Mit Request Context
$contextualReporter = $reporter->withRequestContext(
method: 'POST',
route: '/api/users',
requestId: $requestId,
userAgent: $userAgent,
ipAddress: $clientIp
);
$reportId = $contextualReporter->reportThrowable($exception);
Mit User Context
$userReporter = $reporter->withUserContext(
userId: $user->getId(),
sessionId: $session->getId()
);
$reportId = $userReporter->reportError('warning', 'User action failed');
Error Report Structure
$report = ErrorReport::fromThrowable($exception)
->withUser($userId, $sessionId)
->withRequest($method, $route, $requestId, $userAgent, $ipAddress)
->withPerformance($executionTime, $memoryUsage)
->withTags(['api', 'payment'])
->withBreadcrumbs($breadcrumbs)
->withCustomData(['order_id' => 12345]);
Report Properties
- Basic Info: ID, timestamp, level, message, exception class
- Location: File, line, stack trace
- User Context: User ID, session ID
- Request Context: Route, method, IP, user agent, request data
- Performance: Execution time, memory usage
- Metadata: Tags, breadcrumbs, custom data, environment info
- Analytics: Fingerprint, severity level
Analytics Engine
Anomalie-Erkennung
use App\Framework\ErrorReporting\Analytics\ErrorAnalyticsEngine;
$analytics = $container->get(ErrorAnalyticsEngine::class);
$from = new DateTimeImmutable('-24 hours');
$to = new DateTimeImmutable();
// Detect anomalies and spikes
$anomalies = $analytics->detectAnomalies($from, $to);
foreach ($anomalies as $anomaly) {
echo "Anomaly detected: {$anomaly['type']} at {$anomaly['period']}\n";
echo "Count: {$anomaly['count']} (expected: {$anomaly['expected']})\n";
echo "Z-Score: {$anomaly['z_score']}\n";
}
Error Velocity
// Calculate rate of change
$velocity = $analytics->calculateErrorVelocity($from, $to);
$latest = end($velocity);
echo "Latest trend: {$latest['direction']} ({$latest['velocity_percent']}%)\n";
Pattern Analysis
$patterns = $analytics->identifyPatterns($from, $to);
// Route correlations
foreach ($patterns['route_correlations'] as $correlation) {
echo "Route {$correlation['route']}: {$correlation['total_errors']} errors\n";
echo "Clustered periods: {$correlation['clustered_periods']}\n";
}
// Time patterns
$timePatterns = $patterns['time_patterns'];
echo "Peak hour: {$timePatterns['peak_hour']}\n";
echo "Peak day: {$timePatterns['peak_day']}\n";
Predictive Insights
$predictions = $analytics->generatePredictiveInsights($from, $to);
$trend = $predictions['trend_prediction'];
echo "Trend: {$trend['trend']} (slope: {$trend['slope']})\n";
foreach ($trend['predictions'] as $prediction) {
echo "Period +{$prediction['period']}: ~{$prediction['predicted_count']} errors\n";
}
$risk = $predictions['risk_assessment'];
echo "Risk level: {$risk['level']} (factor: {$risk['risk_factor']})\n";
Health Report
$healthReport = $analytics->generateHealthReport($from, $to);
echo "Health Score: {$healthReport['health_score']}/100\n";
// Impact analysis
$impact = $healthReport['impact'];
echo "Affected users: {$impact['user_impact']['affected_users']}\n";
echo "Critical errors: {$impact['business_impact']['critical_errors']}\n";
// Recommendations
foreach ($healthReport['predictions']['recommendations'] as $rec) {
echo "[{$rec['priority']}] {$rec['message']}\n";
}
Search & Filtering
use App\Framework\ErrorReporting\ErrorReportCriteria;
// Recent critical errors
$criteria = ErrorReportCriteria::critical();
$reports = $reporter->findReports($criteria);
// Errors by user
$criteria = ErrorReportCriteria::byUser('user123');
$reports = $reporter->findReports($criteria);
// Complex search
$criteria = ErrorReportCriteria::recent(48) // Last 48 hours
->withLevels(['error', 'critical'])
->withEnvironment('production')
->withPagination(50, 0);
$reports = $reporter->findReports($criteria);
Search Criteria Options
$criteria = new ErrorReportCriteria(
from: $fromDate,
to: $toDate,
levels: ['error', 'critical'],
exceptions: ['DatabaseException', 'PaymentException'],
routes: ['/api/payment', '/api/orders'],
methods: ['POST', 'PUT'],
userId: 'user123',
environment: 'production',
tags: ['payment', 'critical'],
search: 'connection timeout',
fingerprint: 'abc123',
minSeverity: 2,
maxSeverity: 4,
limit: 100,
offset: 0,
orderBy: 'timestamp',
orderDir: 'DESC'
);
Context Processors
Request Context Processor
Automatische Anreicherung mit HTTP Request Informationen:
- Method, Route, User-Agent, IP-Adresse
- Request Data (GET, POST, JSON) - sanitized
- Execution Time, Memory Usage
- Tags (API, AJAX, Method)
User Context Processor
Automatische Anreicherung mit User Informationen:
- User ID aus Session
- Session ID
- User Breadcrumbs
- Tags (authenticated/anonymous)
use App\Framework\ErrorReporting\Processors\UserContextProcessor;
// Add breadcrumb from application code
UserContextProcessor::addBreadcrumb(
message: 'User clicked delete button',
category: 'user_action',
level: 'info',
data: ['file_id' => 123]
);
HTTP Middleware
Automatische Fehlerberichterstattung für HTTP Requests:
// Automatically registered via initializer
$app->addMiddleware(ErrorReportingMiddleware::class);
Das Middleware:
- Fängt alle ungefangenen Exceptions ab
- Fügt Request-Kontext automatisch hinzu
- Sanitized Request-Daten
- Bestimmt Client IP korrekt (X-Forwarded-For, etc.)
Console Commands
Statistiken anzeigen
# Last 24 hours (default)
php console.php errors:stats
# Last 48 hours
php console.php errors:stats 48
Zeigt:
- Total/Unique Errors
- Critical Error Count
- Error Rate & Health Score
- Errors by Level
- Top Exceptions & Routes
- Insights & Recommendations
Advanced Analytics
# Advanced analytics report
php console.php errors:analytics 24
Zeigt:
- Anomaly Detection
- Error Velocity
- Pattern Analysis
- Predictive Insights
Health Report
# Comprehensive health report
php console.php errors:health 24
Zeigt:
- Overall Health Score
- Key Metrics
- Impact Analysis
- Recommendations
Search Errors
# Search by term
php console.php errors:search "database connection"
Show Error Details
# Show detailed error report
php console.php errors:show <report-id>
Cleanup
# Delete errors older than 30 days (default)
php console.php errors:cleanup
# Delete errors older than 7 days
php console.php errors:cleanup 7
Environment Configuration
# Enable/disable error reporting
ERROR_REPORTING_ENABLED=true
# Enable async processing via queue
ERROR_REPORTING_ASYNC=true
# Filter levels (comma-separated)
ERROR_REPORTING_FILTER_LEVELS=error,critical,alert,emergency
Database Schema
Das System benötigt die error_reports Tabelle:
php console.php db:migrate
Die Migration erstellt eine optimierte Tabelle mit:
- Primary Key: String ID (32 chars)
- Indexes für häufige Queries
- JSON Felder für flexible Daten
- Analytics-Felder (fingerprint, severity_level)
Storage Interface
Custom Storage Implementierungen möglich:
use App\Framework\ErrorReporting\Storage\ErrorReportStorageInterface;
class RedisErrorReportStorage implements ErrorReportStorageInterface
{
public function store(ErrorReport $report): void
{
// Custom implementation
}
// ... other methods
}
// In initializer
$container->bind(ErrorReportStorageInterface::class, RedisErrorReportStorage::class);
Best Practices
1. Structured Error Messages
// Good - structured context
$reporter->reportError('error', 'Payment processing failed', [
'payment_id' => $paymentId,
'amount' => $amount,
'currency' => $currency,
'gateway_response' => $gatewayResponse
]);
// Avoid - unstructured message
$reporter->reportError('error', "Payment $paymentId failed for $amount $currency");
2. Appropriate Log Levels
// Critical system failures
$reporter->reportThrowable($exception, 'critical');
// Business logic errors
$reporter->reportThrowable($exception, 'error');
// Recoverable issues
$reporter->reportError('warning', 'Deprecated API used');
// Development info
$reporter->reportError('info', 'Cache miss occurred');
3. Sensitive Data Handling
// Data is automatically sanitized by processors
// But be explicit about sensitive data
$reporter->reportError('error', 'Authentication failed', [
'username' => $username,
'ip_address' => $ip,
// Don't include: password, tokens, etc.
]);
4. Custom Tags for Filtering
$report = ErrorReport::fromThrowable($exception)
->withTags(['payment', 'external_api', 'critical']);
5. Breadcrumbs for Context
// Add breadcrumbs throughout user journey
UserContextProcessor::addBreadcrumb('User logged in');
UserContextProcessor::addBreadcrumb('Started checkout process');
UserContextProcessor::addBreadcrumb('Selected payment method', 'action', 'info', [
'method' => 'credit_card'
]);
// Error report will include full journey
Performance Considerations
- Async Processing - Enable für Production (
ERROR_REPORTING_ASYNC=true) - Data Sanitization - Automatic für Request Data
- Storage Optimization - Indexes für häufige Queries
- Cleanup Strategy - Regular cleanup alter Reports
- Memory Usage - Limited Context Data Size
Security Considerations
- Data Sanitization - Sensitive Data wird automatisch entfernt
- Access Control - Console Commands benötigen entsprechende Rechte
- Storage Security - Database Access Controls
- IP Address Handling - Respects Privacy Regulations
- Session Security - Nur Session IDs, keine Session Daten
Integration Examples
Mit Custom Exception Handler
class CustomExceptionHandler
{
public function __construct(
private ErrorReporter $reporter
) {}
public function handle(Throwable $exception): void
{
// Report the error
$this->reporter->reportThrowable($exception);
// Continue with normal error handling
$this->originalHandler->handle($exception);
}
}
Mit Business Logic
class PaymentService
{
public function processPayment(Payment $payment): PaymentResult
{
try {
return $this->gateway->process($payment);
} catch (PaymentException $e) {
// Report with business context
$this->reporter->reportThrowable($e, 'error', [
'payment_id' => $payment->getId(),
'amount' => $payment->getAmount(),
'gateway' => $this->gateway->getName(),
]);
throw $e;
}
}
}
Mit Background Jobs
class EmailJob
{
public function handle(): void
{
try {
$this->sendEmails();
} catch (Throwable $e) {
$this->reporter->reportThrowable($e, 'error', [
'job' => 'email_sending',
'batch_size' => count($this->emails),
]);
throw $e;
}
}
}