Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,477 @@
# Analytics Konfiguration
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung der Analytics-Konfiguration korrekt dar.
## Übersicht
Das Analytics Framework bietet umfangreiche Konfigurationsmöglichkeiten, um das Verhalten und die Leistung an die Anforderungen Ihrer Anwendung anzupassen. Diese Dokumentation beschreibt die verfügbaren Konfigurationsoptionen und wie Sie diese anwenden können.
## Konfigurationsklasse
Die zentrale Klasse für die Analytics-Konfiguration ist `AnalyticsConfig`. Diese Klasse enthält alle Einstellungen, die das Verhalten des Analytics Frameworks steuern:
```php
use App\Framework\Analytics\AnalyticsConfig;
// Konfiguration erstellen
$config = new AnalyticsConfig(
$enabled = true, // Analytics aktivieren/deaktivieren
$samplingRate = 1.0, // Sampling-Rate (0.0 - 1.0)
$securityAnalyticsEnabled = true, // Sicherheits-Analytics aktivieren
$dataPath = '/var/www/html/storage/analytics', // Pfad für Datenspeicherung
$bufferSize = 1000, // Puffergröße für Ereignisse
$retentionDays = 365, // Aufbewahrungsdauer in Tagen
$trackPageViews = true, // Seitenaufrufe erfassen
$trackApiCalls = true, // API-Aufrufe erfassen
$trackUserActions = true, // Benutzeraktionen erfassen
$trackErrors = true, // Fehler erfassen
$trackPerformance = true // Leistungsmetriken erfassen
);
```
## Standardkonfiguration
Die `AnalyticsConfig`-Klasse bietet eine Standardkonfiguration, die für die meisten Anwendungen geeignet ist:
```php
// Standardkonfiguration verwenden
$config = AnalyticsConfig::default();
```
Die Standardkonfiguration aktiviert alle Features mit sinnvollen Standardwerten:
- Analytics aktiviert
- 100% Sampling (alle Daten werden erfasst)
- Sicherheits-Analytics aktiviert
- 1000 Ereignisse im Puffer
- 365 Tage Aufbewahrungsdauer
- Alle Tracking-Typen aktiviert
## Umgebungsvariablen
Die Konfiguration kann auch über Umgebungsvariablen angepasst werden:
```php
// In der AnalyticsConfig-Klasse
public static function default(): self
{
return new self(
enabled: filter_var($_ENV['ANALYTICS_ENABLED'] ?? true, FILTER_VALIDATE_BOOLEAN),
samplingRate: (float)($_ENV['ANALYTICS_SAMPLING_RATE'] ?? 1.0),
securityAnalyticsEnabled: filter_var($_ENV['SECURITY_ANALYTICS_ENABLED'] ?? true, FILTER_VALIDATE_BOOLEAN),
dataPath: $_ENV['ANALYTICS_DATA_PATH'] ?? '/var/www/html/storage/analytics',
bufferSize: (int)($_ENV['ANALYTICS_BUFFER_SIZE'] ?? 1000),
retentionDays: (int)($_ENV['ANALYTICS_RETENTION_DAYS'] ?? 365),
trackPageViews: filter_var($_ENV['ANALYTICS_TRACK_PAGE_VIEWS'] ?? true, FILTER_VALIDATE_BOOLEAN),
trackApiCalls: filter_var($_ENV['ANALYTICS_TRACK_API_CALLS'] ?? true, FILTER_VALIDATE_BOOLEAN),
trackUserActions: filter_var($_ENV['ANALYTICS_TRACK_USER_ACTIONS'] ?? true, FILTER_VALIDATE_BOOLEAN),
trackErrors: filter_var($_ENV['ANALYTICS_TRACK_ERRORS'] ?? true, FILTER_VALIDATE_BOOLEAN),
trackPerformance: filter_var($_ENV['ANALYTICS_TRACK_PERFORMANCE'] ?? true, FILTER_VALIDATE_BOOLEAN)
);
}
```
Beispiel für eine `.env`-Datei:
```
ANALYTICS_ENABLED=true
ANALYTICS_SAMPLING_RATE=0.1
SECURITY_ANALYTICS_ENABLED=true
ANALYTICS_DATA_PATH=/var/www/html/storage/analytics
ANALYTICS_BUFFER_SIZE=1000
ANALYTICS_RETENTION_DAYS=365
ANALYTICS_TRACK_PAGE_VIEWS=true
ANALYTICS_TRACK_API_CALLS=true
ANALYTICS_TRACK_USER_ACTIONS=true
ANALYTICS_TRACK_ERRORS=true
ANALYTICS_TRACK_PERFORMANCE=true
```
## Konfigurationsoptionen im Detail
### Grundlegende Optionen
#### enabled
Aktiviert oder deaktiviert das gesamte Analytics Framework:
```php
$config = new AnalyticsConfig(
enabled: true, // Analytics aktivieren
// ... weitere Optionen
);
// oder
$config = new AnalyticsConfig(
enabled: false, // Analytics deaktivieren
// ... weitere Optionen
);
```
Wenn deaktiviert, werden keine Daten erfasst, und alle Aufrufe an den `AnalyticsCollector` werden ignoriert.
#### samplingRate
Definiert den Prozentsatz der Daten, die erfasst werden sollen:
```php
$config = new AnalyticsConfig(
enabled: true,
samplingRate: 1.0, // 100% der Daten erfassen
// ... weitere Optionen
);
// oder
$config = new AnalyticsConfig(
enabled: true,
samplingRate: 0.1, // 10% der Daten erfassen
// ... weitere Optionen
);
```
Die Sampling-Rate ist nützlich, um die Datenmenge und die Serverbelastung bei hohem Datenaufkommen zu reduzieren. Ein Wert von 0.1 bedeutet, dass nur 10% aller Ereignisse erfasst werden.
#### securityAnalyticsEnabled
Aktiviert oder deaktiviert die Erfassung von Sicherheitsereignissen:
```php
$config = new AnalyticsConfig(
enabled: true,
samplingRate: 1.0,
securityAnalyticsEnabled: true, // Sicherheits-Analytics aktivieren
// ... weitere Optionen
);
```
Wenn aktiviert, werden Sicherheitsereignisse (wie Anmeldeversuche, CSRF-Angriffe, WAF-Blockierungen) erfasst und analysiert.
### Speicheroptionen
#### dataPath
Definiert den Pfad, in dem Analytics-Daten gespeichert werden:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
dataPath: '/var/www/html/storage/analytics',
// ... weitere Optionen
);
```
Stellen Sie sicher, dass dieser Pfad existiert und für die Anwendung beschreibbar ist.
#### bufferSize
Definiert die Anzahl der Ereignisse, die im Speicher gepuffert werden, bevor sie auf die Festplatte geschrieben werden:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
bufferSize: 1000, // 1000 Ereignisse puffern
// ... weitere Optionen
);
```
Ein größerer Puffer reduziert die Anzahl der Schreibvorgänge, erhöht aber den Speicherverbrauch und das Risiko von Datenverlust bei einem Absturz.
#### retentionDays
Definiert die Anzahl der Tage, für die Analytics-Daten aufbewahrt werden:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
retentionDays: 365, // Daten für 1 Jahr aufbewahren
// ... weitere Optionen
);
```
Ältere Daten werden automatisch gelöscht, um Speicherplatz zu sparen.
### Tracking-Optionen
#### trackPageViews
Aktiviert oder deaktiviert die Erfassung von Seitenaufrufen:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
trackPageViews: true, // Seitenaufrufe erfassen
// ... weitere Optionen
);
```
#### trackApiCalls
Aktiviert oder deaktiviert die Erfassung von API-Aufrufen:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
trackApiCalls: true, // API-Aufrufe erfassen
// ... weitere Optionen
);
```
#### trackUserActions
Aktiviert oder deaktiviert die Erfassung von Benutzeraktionen:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
trackUserActions: true, // Benutzeraktionen erfassen
// ... weitere Optionen
);
```
#### trackErrors
Aktiviert oder deaktiviert die Erfassung von Fehlern:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
trackErrors: true, // Fehler erfassen
// ... weitere Optionen
);
```
#### trackPerformance
Aktiviert oder deaktiviert die Erfassung von Leistungsmetriken:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
trackPerformance: true, // Leistungsmetriken erfassen
);
```
## Konfiguration in der Anwendung
### Konfigurationsdatei
Die Analytics-Konfiguration kann in einer dedizierten Konfigurationsdatei definiert werden:
```php
// config/analytics.php
return [
'enabled' => true,
'sampling_rate' => 1.0,
'security_analytics_enabled' => true,
'data_path' => '/var/www/html/storage/analytics',
'buffer_size' => 1000,
'retention_days' => 365,
'track_page_views' => true,
'track_api_calls' => true,
'track_user_actions' => true,
'track_errors' => true,
'track_performance' => true,
];
```
### Dependency Injection
Die Konfiguration kann über Dependency Injection in die Anwendung eingebunden werden:
```php
// In einem Service Provider oder Container-Konfiguration
$container->set(AnalyticsConfig::class, function () {
return new AnalyticsConfig(
enabled: true,
samplingRate: 0.1,
// ... weitere Optionen
);
});
```
### Laufzeitkonfiguration
Die Konfiguration kann zur Laufzeit angepasst werden:
```php
// Analytics-Konfiguration aktualisieren
$newConfig = new AnalyticsConfig(
enabled: true,
samplingRate: 0.5, // Sampling-Rate anpassen
// ... weitere Optionen
);
// Konfiguration aktualisieren
$analyticsManager->updateConfig($newConfig);
```
## Umgebungsspezifische Konfiguration
Es ist oft sinnvoll, unterschiedliche Konfigurationen für verschiedene Umgebungen zu verwenden:
### Produktionsumgebung
```php
// Produktionskonfiguration
$config = new AnalyticsConfig(
enabled: true,
samplingRate: 0.1, // Reduzierte Sampling-Rate für hohe Lasten
securityAnalyticsEnabled: true,
dataPath: '/var/www/html/storage/analytics',
bufferSize: 5000, // Größerer Puffer für bessere Leistung
retentionDays: 365,
trackPageViews: true,
trackApiCalls: true,
trackUserActions: true,
trackErrors: true,
trackPerformance: true
);
```
### Entwicklungsumgebung
```php
// Entwicklungskonfiguration
$config = new AnalyticsConfig(
enabled: true,
samplingRate: 1.0, // Alle Daten erfassen für einfachere Fehlersuche
securityAnalyticsEnabled: true,
dataPath: '/var/www/html/storage/analytics',
bufferSize: 100, // Kleinerer Puffer für sofortiges Feedback
retentionDays: 30, // Kürzere Aufbewahrungsdauer
trackPageViews: true,
trackApiCalls: true,
trackUserActions: true,
trackErrors: true,
trackPerformance: true
);
```
### Testumgebung
```php
// Testkonfiguration
$config = new AnalyticsConfig(
enabled: false, // Deaktiviert für Tests
samplingRate: 1.0,
securityAnalyticsEnabled: false,
dataPath: '/tmp/analytics',
bufferSize: 10,
retentionDays: 1,
trackPageViews: false,
trackApiCalls: false,
trackUserActions: false,
trackErrors: false,
trackPerformance: false
);
```
## Leistungsoptimierung
### Sampling für hohe Lasten
Bei hohem Datenaufkommen kann die Sampling-Rate reduziert werden, um die Serverbelastung zu verringern:
```php
$config = new AnalyticsConfig(
enabled: true,
samplingRate: 0.01, // Nur 1% der Daten erfassen
// ... weitere Optionen
);
```
### Pufferoptimierung
Die Puffergröße kann angepasst werden, um die Anzahl der Schreibvorgänge zu optimieren:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
bufferSize: 10000, // Größerer Puffer für weniger Schreibvorgänge
// ... weitere Optionen
);
```
### Selektives Tracking
Nicht alle Tracking-Typen müssen aktiviert sein. Deaktivieren Sie die Typen, die Sie nicht benötigen:
```php
$config = new AnalyticsConfig(
// ... vorherige Optionen
trackPageViews: true,
trackApiCalls: true,
trackUserActions: false, // Benutzeraktionen deaktivieren
trackErrors: true,
trackPerformance: false // Leistungsmetriken deaktivieren
);
```
## Fehlerbehebung
### Häufige Probleme
#### Keine Daten werden erfasst
Mögliche Ursachen:
- Analytics ist deaktiviert (`enabled = false`)
- Sampling-Rate ist zu niedrig
- Fehler beim Speichern der Daten
Lösung:
- Überprüfen Sie die Konfiguration
- Erhöhen Sie die Sampling-Rate
- Überprüfen Sie die Logs auf Fehler
- Stellen Sie sicher, dass der Datenpfad existiert und beschreibbar ist
```php
// Überprüfen Sie die Konfiguration
var_dump($analyticsConfig);
// Erhöhen Sie die Sampling-Rate
$newConfig = new AnalyticsConfig(
enabled: true,
samplingRate: 1.0, // 100% der Daten erfassen
// ... weitere Optionen
);
// Überprüfen Sie die Berechtigungen des Datenpfads
if (!is_writable($analyticsConfig->dataPath)) {
echo "Datenpfad ist nicht beschreibbar: " . $analyticsConfig->dataPath;
}
```
#### Hohe Serverbelastung
Mögliche Ursachen:
- Zu viele Ereignisse werden erfasst
- Puffergröße ist zu klein
- Synchrone Verarbeitung bei hohem Datenaufkommen
Lösung:
- Reduzieren Sie die Sampling-Rate
- Erhöhen Sie die Puffergröße
- Verwenden Sie asynchrone Verarbeitung
```php
// Reduzieren Sie die Sampling-Rate
$newConfig = new AnalyticsConfig(
enabled: true,
samplingRate: 0.1, // Nur 10% der Daten erfassen
// ... weitere Optionen
);
// Erhöhen Sie die Puffergröße
$newConfig = new AnalyticsConfig(
// ... vorherige Optionen
bufferSize: 10000, // Größerer Puffer
// ... weitere Optionen
);
```
## Weiterführende Informationen
- [Analytics Framework Übersicht](index.md)
- [Analytics Beispiele](examples.md)
- [Performance-Monitoring](/components/performance/index.md)

View File

@@ -0,0 +1,760 @@
# Analytics Framework Beispiele
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Analytics Frameworks korrekt dar.
## Übersicht
Diese Dokumentation enthält praktische Beispiele für die Verwendung des Analytics Frameworks in verschiedenen Szenarien. Die Beispiele zeigen, wie Sie Analytics-Daten erfassen, analysieren und in Ihre Anwendung integrieren können.
## Grundlegende Verwendung
### Benutzeraktionen erfassen
```php
use App\Framework\Analytics\AnalyticsCollector;
use App\Framework\Analytics\AnalyticsCategory;
class UserController
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector
) {}
public function handleLogin(Request $request): Response
{
// Login-Logik
$success = $this->authService->login($request->getParam('email'), $request->getParam('password'));
// Login-Aktion erfassen
$this->analyticsCollector->trackAction(
'user_login',
AnalyticsCategory::USER,
[
'success' => $success,
'email_domain' => explode('@', $request->getParam('email'))[1] ?? 'unknown',
'ip' => $request->getClientIp(),
'user_agent' => $request->getUserAgent()
]
);
// Antwort zurückgeben
return $success
? $this->redirect('/dashboard')
: $this->renderForm('login', ['error' => 'Ungültige Anmeldedaten']);
}
}
```
### Seitenaufrufe erfassen
```php
use App\Framework\Analytics\AnalyticsCollector;
class ProductController
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector,
private readonly ProductRepository $productRepository
) {}
public function showProduct(Request $request, string $productId): Response
{
$product = $this->productRepository->find($productId);
if (!$product) {
return $this->notFound();
}
// Seitenaufruf erfassen
$this->analyticsCollector->trackPageView(
"/products/{$productId}",
[
'product_id' => $productId,
'product_name' => $product->name,
'product_category' => $product->category,
'referrer' => $request->getHeader('Referer'),
'user_id' => $this->session->get('user_id')
]
);
return $this->render('product', ['product' => $product]);
}
}
```
### Fehler erfassen
```php
use App\Framework\Analytics\AnalyticsCollector;
class ErrorHandler
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector,
private readonly Logger $logger
) {}
public function handleException(\Throwable $exception): Response
{
// Fehler loggen
$this->logger->error('Unbehandelte Ausnahme: ' . $exception->getMessage(), [
'exception' => $exception
]);
// Fehler für Analytics erfassen
$this->analyticsCollector->trackError(
get_class($exception),
[
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => $exception->getTraceAsString(),
'request_uri' => $_SERVER['REQUEST_URI'] ?? null,
'user_id' => $this->session->get('user_id')
]
);
// Fehlerseite anzeigen
return new Response(500, [], 'Ein Fehler ist aufgetreten');
}
}
```
### Geschäftsereignisse erfassen
```php
use App\Framework\Analytics\AnalyticsCollector;
class OrderService
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector,
private readonly OrderRepository $orderRepository
) {}
public function placeOrder(Order $order): bool
{
// Bestellung speichern
$success = $this->orderRepository->save($order);
if ($success) {
// Geschäftsereignis erfassen
$this->analyticsCollector->trackBusinessEvent(
'order_placed',
[
'order_id' => $order->id,
'user_id' => $order->userId,
'total_amount' => $order->totalAmount,
'items_count' => count($order->items),
'payment_method' => $order->paymentMethod,
'shipping_country' => $order->shippingAddress->country
]
);
}
return $success;
}
}
```
### API-Aufrufe erfassen
```php
use App\Framework\Analytics\AnalyticsCollector;
class ApiClient
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector,
private readonly HttpClient $httpClient
) {}
public function sendRequest(string $endpoint, string $method, array $data = []): Response
{
$startTime = microtime(true);
try {
$response = $this->httpClient->request($method, $endpoint, $data);
$statusCode = $response->getStatusCode();
$success = $statusCode >= 200 && $statusCode < 300;
} catch (\Exception $e) {
$statusCode = 0;
$success = false;
}
$duration = (microtime(true) - $startTime) * 1000; // in ms
// API-Aufruf erfassen
$this->analyticsCollector->trackApiCall(
$endpoint,
$method,
$statusCode,
[
'duration' => $duration,
'success' => $success,
'data_size' => strlen(json_encode($data)),
'user_id' => $this->session->get('user_id')
]
);
return $response;
}
}
```
## Fortgeschrittene Verwendung
### Automatische Erfassung mit Middleware
Die `AnalyticsMiddleware` erfasst automatisch Seitenaufrufe und API-Aufrufe:
```php
use App\Framework\Analytics\Middleware\AnalyticsMiddleware;
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(AnalyticsMiddleware::class);
```
Anpassung der Middleware für bestimmte Routen:
```php
use App\Framework\Analytics\Middleware\AnalyticsMiddleware;
use App\Framework\Http\MiddlewareContext;
use App\Framework\Http\Next;
class CustomAnalyticsMiddleware extends AnalyticsMiddleware
{
public function __invoke(MiddlewareContext $context, Next $next): MiddlewareContext
{
$request = $context->request;
// Bestimmte Routen ausschließen
if (str_starts_with($request->path, '/api/health') || str_starts_with($request->path, '/static/')) {
return $next($context);
}
// Zusätzliche Daten für bestimmte Routen hinzufügen
$additionalData = [];
if (str_starts_with($request->path, '/products/')) {
$productId = substr($request->path, 10);
$additionalData['product_id'] = $productId;
}
// Standardverhalten mit zusätzlichen Daten
return parent::__invoke($context, $next, $additionalData);
}
}
```
### Sicherheitsereignisse erfassen
Integration mit dem Security-System:
```php
use App\Framework\Analytics\Listeners\SecurityAnalyticsListener;
use App\Framework\Analytics\Bridges\SecurityEventBridge;
use App\Framework\Security\Events\LoginAttemptEvent;
// In der Bootstrap-Datei
$securityEventBridge = SecurityEventBridge::create(
$container->get(SecurityAnalyticsListener::class),
$config->securityAnalyticsEnabled
);
$eventDispatcher->addListener(LoginAttemptEvent::class, [$securityEventBridge, 'handleSecurityEvent']);
```
Benutzerdefinierter Security-Event-Listener:
```php
use App\Framework\Analytics\AnalyticsCollector;
use App\Framework\Analytics\AnalyticsCategory;
use App\Framework\Security\Events\LoginAttemptEvent;
class LoginAnalyticsListener
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector
) {}
public function onLoginAttempt(LoginAttemptEvent $event): void
{
$this->analyticsCollector->trackAction(
'login_attempt',
AnalyticsCategory::SECURITY,
[
'username' => $event->getUsername(),
'success' => $event->isSuccessful(),
'ip' => $event->getIp(),
'user_agent' => $event->getUserAgent(),
'timestamp' => $event->getTimestamp()->format('Y-m-d H:i:s')
]
);
}
}
```
### Asynchrone Datenerfassung
Für maximale Leistung kann die Analytics-Datenerfassung asynchron erfolgen:
```php
use App\Framework\Analytics\AsyncAnalyticsCollector;
use App\Framework\Queue\QueueInterface;
class AsyncAnalyticsService
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector,
private readonly QueueInterface $queue
) {}
public function initialize(): void
{
// Asynchronen Collector erstellen
$asyncCollector = new AsyncAnalyticsCollector(
$this->analyticsCollector,
$this->queue
);
// Asynchronen Collector registrieren
$this->container->set(AnalyticsCollector::class, $asyncCollector);
}
}
```
### Benutzerdefinierte Ereignistypen
Sie können benutzerdefinierte Ereignistypen für spezifische Anforderungen erstellen:
```php
use App\Framework\Analytics\AnalyticsCollector;
use App\Framework\Analytics\AnalyticsCategory;
class CustomAnalyticsService
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector
) {}
public function trackProductView(string $productId, string $productName, string $category): void
{
$this->analyticsCollector->trackAction(
'product_view',
AnalyticsCategory::BUSINESS,
[
'product_id' => $productId,
'product_name' => $productName,
'category' => $category,
'timestamp' => time(),
'user_id' => $this->session->get('user_id')
]
);
}
public function trackAddToCart(string $productId, int $quantity, float $price): void
{
$this->analyticsCollector->trackAction(
'add_to_cart',
AnalyticsCategory::BUSINESS,
[
'product_id' => $productId,
'quantity' => $quantity,
'price' => $price,
'total' => $quantity * $price,
'timestamp' => time(),
'user_id' => $this->session->get('user_id')
]
);
}
}
```
## Datenanalyse
### Rohdaten abfragen
```php
use App\Framework\Analytics\Storage\AnalyticsStorage;
class AnalyticsReportService
{
public function __construct(
private readonly AnalyticsStorage $analyticsStorage
) {}
public function getPageViewsReport(\DateTimeInterface $from, \DateTimeInterface $to): array
{
// Rohdaten für Seitenaufrufe abrufen
$pageViews = $this->analyticsStorage->getRawData(
'page_view',
$from,
$to
);
// Daten nach Seite gruppieren
$pageViewsByPath = [];
foreach ($pageViews as $pageView) {
$path = $pageView['path'] ?? 'unknown';
if (!isset($pageViewsByPath[$path])) {
$pageViewsByPath[$path] = 0;
}
$pageViewsByPath[$path]++;
}
// Nach Anzahl sortieren
arsort($pageViewsByPath);
return $pageViewsByPath;
}
public function getUserActivityReport(string $userId, \DateTimeInterface $from, \DateTimeInterface $to): array
{
// Alle Aktionen für einen bestimmten Benutzer abrufen
$actions = $this->analyticsStorage->getRawData(
'user_action',
$from,
$to,
['user_id' => $userId]
);
// Nach Zeitstempel sortieren
usort($actions, function ($a, $b) {
return $a['timestamp'] <=> $b['timestamp'];
});
return $actions;
}
}
```
### Aggregierte Daten abfragen
```php
use App\Framework\Analytics\Storage\AnalyticsStorage;
class PerformanceReportService
{
public function __construct(
private readonly AnalyticsStorage $analyticsStorage
) {}
public function getApiPerformanceReport(\DateTimeInterface $from, \DateTimeInterface $to): array
{
// Aggregierte Daten für API-Aufrufe abrufen
$apiCallStats = $this->analyticsStorage->getAggregatedData(
'analytics_api_calls_total',
$from,
$to
);
// Durchschnittliche Antwortzeit pro Endpunkt berechnen
$responseTimeByEndpoint = [];
foreach ($apiCallStats as $stat) {
$endpoint = $stat['tags']['path'] ?? 'unknown';
$method = $stat['tags']['method'] ?? 'unknown';
$key = "{$method} {$endpoint}";
if (!isset($responseTimeByEndpoint[$key])) {
$responseTimeByEndpoint[$key] = [
'count' => 0,
'total_time' => 0,
'min_time' => PHP_FLOAT_MAX,
'max_time' => 0,
];
}
$duration = $stat['tags']['duration'] ?? 0;
$responseTimeByEndpoint[$key]['count']++;
$responseTimeByEndpoint[$key]['total_time'] += $duration;
$responseTimeByEndpoint[$key]['min_time'] = min($responseTimeByEndpoint[$key]['min_time'], $duration);
$responseTimeByEndpoint[$key]['max_time'] = max($responseTimeByEndpoint[$key]['max_time'], $duration);
}
// Durchschnitt berechnen
foreach ($responseTimeByEndpoint as $key => $data) {
$responseTimeByEndpoint[$key]['avg_time'] = $data['total_time'] / $data['count'];
}
// Nach durchschnittlicher Antwortzeit sortieren
uasort($responseTimeByEndpoint, function ($a, $b) {
return $b['avg_time'] <=> $a['avg_time'];
});
return $responseTimeByEndpoint;
}
}
```
### Dashboard-Integration
```php
use App\Framework\Analytics\Dashboard\AnalyticsDashboard;
class AdminController
{
public function __construct(
private readonly AnalyticsDashboard $dashboard,
private readonly TemplateEngine $templateEngine
) {}
public function showDashboard(Request $request): Response
{
// Zeitraum aus Anfrage oder Standardwerte
$from = new \DateTimeImmutable($request->getQueryParam('from', '-7 days'));
$to = new \DateTimeImmutable($request->getQueryParam('to', 'now'));
// Dashboard-Daten abrufen
$stats = $this->dashboard->getStats($from, $to);
// Spezifische Statistiken abrufen
$pageViewStats = $this->dashboard->getPageViewStats($from, $to);
$errorStats = $this->dashboard->getErrorStats($from, $to);
$performanceStats = $this->dashboard->getPerformanceStats($from, $to);
$businessStats = $this->dashboard->getBusinessStats($from, $to);
// Dashboard rendern
return $this->templateEngine->render('admin/dashboard', [
'stats' => $stats,
'pageViewStats' => $pageViewStats,
'errorStats' => $errorStats,
'performanceStats' => $performanceStats,
'businessStats' => $businessStats,
'from' => $from,
'to' => $to
]);
}
}
```
## Datenexport
### CSV-Export
```php
use App\Framework\Analytics\Export\AnalyticsExporter;
class ExportController
{
public function __construct(
private readonly AnalyticsExporter $exporter
) {}
public function exportPageViews(Request $request): Response
{
// Zeitraum aus Anfrage
$from = new \DateTimeImmutable($request->getQueryParam('from', '-7 days'));
$to = new \DateTimeImmutable($request->getQueryParam('to', 'now'));
// Daten exportieren
$csvData = $this->exporter->exportToCsv(
'page_view',
$from,
$to
);
// CSV-Datei zurückgeben
return new Response(
200,
[
'Content-Type' => 'text/csv',
'Content-Disposition' => 'attachment; filename="page_views.csv"'
],
$csvData
);
}
}
```
### JSON-Export
```php
use App\Framework\Analytics\Export\AnalyticsExporter;
class ApiController
{
public function __construct(
private readonly AnalyticsExporter $exporter
) {}
public function getAnalyticsData(Request $request): Response
{
// Parameter aus Anfrage
$eventType = $request->getQueryParam('type', 'page_view');
$from = new \DateTimeImmutable($request->getQueryParam('from', '-7 days'));
$to = new \DateTimeImmutable($request->getQueryParam('to', 'now'));
// Daten exportieren
$data = $this->exporter->exportToArray(
$eventType,
$from,
$to
);
// JSON-Daten zurückgeben
return new Response(
200,
['Content-Type' => 'application/json'],
json_encode($data)
);
}
}
```
## Integration mit anderen Systemen
### Event-System-Integration
```php
use App\Framework\Analytics\EventSubscribers\AnalyticsEventSubscriber;
use App\Framework\EventDispatcher\EventDispatcherInterface;
class AnalyticsBootstrap
{
public function initialize(EventDispatcherInterface $eventDispatcher): void
{
// Analytics-Event-Subscriber registrieren
$eventDispatcher->addSubscriber(new AnalyticsEventSubscriber(
$this->container->get(AnalyticsCollector::class)
));
}
}
```
### Externe Analytics-Integration
```php
use App\Framework\Analytics\AnalyticsCollector;
use App\Framework\Analytics\AnalyticsCategory;
class ExternalAnalyticsService
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector,
private readonly ExternalAnalyticsClient $externalClient
) {}
public function trackEvent(string $eventName, array $properties): void
{
// Intern erfassen
$this->analyticsCollector->trackAction(
$eventName,
AnalyticsCategory::BUSINESS,
$properties
);
// An externes System senden
$this->externalClient->trackEvent($eventName, $properties);
}
public function syncData(\DateTimeInterface $from, \DateTimeInterface $to): void
{
// Daten aus internem Analytics abrufen
$internalData = $this->analyticsStorage->getRawData('*', $from, $to);
// Daten an externes System senden
$this->externalClient->batchImport($internalData);
}
}
```
## Fehlerbehebung
### Debugging der Datenerfassung
```php
use App\Framework\Analytics\AnalyticsCollector;
use App\Framework\Analytics\AnalyticsCategory;
class DebugAnalyticsCollector extends AnalyticsCollector
{
public function trackAction(string $action, AnalyticsCategory $category, array $data = []): void
{
// Debug-Ausgabe
echo "Tracking action: {$action}, category: {$category->value}\n";
echo "Data: " . json_encode($data, JSON_PRETTY_PRINT) . "\n";
// Original-Methode aufrufen
parent::trackAction($action, $category, $data);
}
public function trackPageView(string $path, array $data = []): void
{
// Debug-Ausgabe
echo "Tracking page view: {$path}\n";
echo "Data: " . json_encode($data, JSON_PRETTY_PRINT) . "\n";
// Original-Methode aufrufen
parent::trackPageView($path, $data);
}
}
```
### Überprüfung der Datenspeicherung
```php
use App\Framework\Analytics\Storage\AnalyticsStorage;
class AnalyticsDebugService
{
public function __construct(
private readonly AnalyticsStorage $analyticsStorage,
private readonly string $dataPath
) {}
public function checkStorage(): array
{
$result = [
'status' => 'ok',
'messages' => [],
'files' => []
];
// Prüfen, ob der Datenpfad existiert
if (!is_dir($this->dataPath)) {
$result['status'] = 'error';
$result['messages'][] = "Datenpfad existiert nicht: {$this->dataPath}";
return $result;
}
// Prüfen, ob der Datenpfad beschreibbar ist
if (!is_writable($this->dataPath)) {
$result['status'] = 'error';
$result['messages'][] = "Datenpfad ist nicht beschreibbar: {$this->dataPath}";
return $result;
}
// Dateien im Datenpfad auflisten
$files = glob($this->dataPath . '/*.json');
foreach ($files as $file) {
$size = filesize($file);
$modified = date('Y-m-d H:i:s', filemtime($file));
$result['files'][] = [
'name' => basename($file),
'size' => $size,
'modified' => $modified
];
}
// Testdaten speichern
try {
$this->analyticsStorage->storeRawData('debug_test', [
'timestamp' => time(),
'message' => 'Debug test'
]);
$result['messages'][] = "Testdaten erfolgreich gespeichert";
} catch (\Exception $e) {
$result['status'] = 'error';
$result['messages'][] = "Fehler beim Speichern von Testdaten: " . $e->getMessage();
}
return $result;
}
}
```
## Weiterführende Informationen
- [Analytics Framework Übersicht](index.md)
- [Analytics Konfiguration](configuration.md)
- [Performance-Monitoring](/components/performance/index.md)

View File

@@ -0,0 +1,507 @@
# Analytics Framework
> **Dokumentationshinweis:** Diese Dokumentation ist vollständig aktualisiert und stellt die aktuelle Implementierung des Analytics Frameworks korrekt dar.
## Übersicht
Das Analytics Framework ist ein leistungsstarkes System zur Erfassung, Speicherung und Analyse von Daten über die Nutzung und Leistung Ihrer Anwendung. Es ist vollständig in das Framework integriert und ermöglicht die Erfassung verschiedener Arten von Ereignissen, darunter Seitenaufrufe, Benutzeraktionen, API-Aufrufe, Fehler und Geschäftsereignisse.
Das Framework basiert auf dem Performance-System und bietet eine flexible, erweiterbare Architektur für verschiedene Analyseanforderungen, ohne auf externe Dienste angewiesen zu sein.
## Hauptkomponenten
### AnalyticsCollector
Die zentrale Klasse für die Erfassung von Analytics-Daten:
```php
use App\Framework\Analytics\AnalyticsCollector;
use App\Framework\Analytics\AnalyticsCategory;
// Benutzeraktion erfassen
$analyticsCollector->trackAction(
'button_click',
AnalyticsCategory::USER,
['button_id' => 'submit', 'page' => '/checkout']
);
// Seitenaufruf erfassen
$analyticsCollector->trackPageView(
'/products',
['referrer' => '/home', 'user_id' => $userId]
);
// Fehler erfassen
$analyticsCollector->trackError(
'validation_error',
['field' => 'email', 'message' => 'Invalid email format']
);
// Geschäftsereignis erfassen
$analyticsCollector->trackBusinessEvent(
'order_completed',
['order_id' => '12345', 'amount' => 99.99, 'items' => 3]
);
// API-Aufruf erfassen
$analyticsCollector->trackApiCall(
'/api/products',
'GET',
200,
['duration' => 45, 'cache_hit' => true]
);
```
### AnalyticsCategory
Ein Enum, das die verschiedenen Kategorien von Analytics-Daten definiert:
```php
use App\Framework\Analytics\AnalyticsCategory;
// Verfügbare Kategorien
$category = AnalyticsCategory::USER; // Benutzeraktionen
$category = AnalyticsCategory::SYSTEM; // Systemereignisse
$category = AnalyticsCategory::BUSINESS; // Geschäftsereignisse
$category = AnalyticsCategory::PERFORMANCE; // Leistungsmetriken
$category = AnalyticsCategory::SECURITY; // Sicherheitsereignisse
```
### AnalyticsStorage
Das Interface für die Speicherung von Analytics-Daten:
```php
use App\Framework\Analytics\Storage\AnalyticsStorage;
interface AnalyticsStorage
{
// Rohdaten speichern
public function storeRawData(string $eventType, array $data): void;
// Aggregierte Daten speichern
public function storeAggregatedData(string $metricName, float $value, array $tags = []): void;
// Rohdaten abrufen
public function getRawData(string $eventType, \DateTimeInterface $from, \DateTimeInterface $to): array;
// Aggregierte Daten abrufen
public function getAggregatedData(string $metricName, \DateTimeInterface $from, \DateTimeInterface $to, array $tags = []): array;
}
```
Das Framework bietet eine leistungsoptimierte Implementierung:
```php
use App\Framework\Analytics\Storage\PerformanceBasedAnalyticsStorage;
// Leistungsoptimierte Speicherung
$storage = new PerformanceBasedAnalyticsStorage(
$filesystem,
$performanceSystem,
$clock,
$config
);
```
### AnalyticsMiddleware
Eine Middleware, die automatisch Analytics-Daten für HTTP-Anfragen erfasst:
```php
use App\Framework\Analytics\Middleware\AnalyticsMiddleware;
// In der Bootstrap-Datei oder Router-Konfiguration
$app->addMiddleware(AnalyticsMiddleware::class);
```
Die Middleware erfasst automatisch:
- Seitenaufrufe
- API-Aufrufe
- Leistungsmetriken (Antwortzeit, Speicherverbrauch)
- HTTP-Statuscodes
- Benutzeragenten und Referrer
### SecurityAnalyticsListener
Ein Listener, der Sicherheitsereignisse in Analytics-Daten umwandelt:
```php
use App\Framework\Analytics\Listeners\SecurityAnalyticsListener;
use App\Framework\Analytics\Bridges\SecurityEventBridge;
// In der Bootstrap-Datei
$securityEventBridge = SecurityEventBridge::create(
$container->get(SecurityAnalyticsListener::class),
$config->securityAnalyticsEnabled
);
$eventDispatcher->addListener(SecurityEventInterface::class, [$securityEventBridge, 'handleSecurityEvent']);
```
## Datenerfassung
### Benutzeraktionen
Benutzeraktionen repräsentieren Interaktionen des Benutzers mit der Anwendung:
```php
$analyticsCollector->trackAction(
'button_click', // Aktionsname
AnalyticsCategory::USER, // Kategorie
[ // Zusätzliche Daten
'button_id' => 'submit',
'page' => '/checkout',
'user_id' => $userId
]
);
```
### Seitenaufrufe
Seitenaufrufe repräsentieren den Besuch einer Seite durch einen Benutzer:
```php
$analyticsCollector->trackPageView(
'/products', // Pfad
[ // Zusätzliche Daten
'referrer' => '/home',
'user_id' => $userId,
'device_type' => 'mobile'
]
);
```
### Fehler
Fehler repräsentieren Probleme, die während der Ausführung der Anwendung auftreten:
```php
$analyticsCollector->trackError(
'validation_error', // Fehlertyp
[ // Zusätzliche Daten
'field' => 'email',
'message' => 'Invalid email format',
'user_id' => $userId
]
);
// Oder mit einer Exception
try {
// Code, der eine Exception werfen könnte
} catch (\Exception $e) {
$analyticsCollector->trackException($e);
}
```
### Geschäftsereignisse
Geschäftsereignisse repräsentieren wichtige Ereignisse aus geschäftlicher Sicht:
```php
$analyticsCollector->trackBusinessEvent(
'order_completed', // Ereignisname
[ // Zusätzliche Daten
'order_id' => '12345',
'amount' => 99.99,
'items' => 3,
'user_id' => $userId
]
);
```
### API-Aufrufe
API-Aufrufe repräsentieren Anfragen an die API der Anwendung:
```php
$analyticsCollector->trackApiCall(
'/api/products', // Pfad
'GET', // Methode
200, // Statuscode
[ // Zusätzliche Daten
'duration' => 45,
'cache_hit' => true,
'user_id' => $userId
]
);
```
## Konfiguration
### AnalyticsConfig
Die `AnalyticsConfig`-Klasse enthält die Konfiguration für das Analytics Framework:
```php
use App\Framework\Analytics\AnalyticsConfig;
// Standardkonfiguration
$config = AnalyticsConfig::default();
// Benutzerdefinierte Konfiguration
$config = new AnalyticsConfig(
$enabled = true,
$samplingRate = 1.0,
$securityAnalyticsEnabled = true,
$dataPath = '/var/www/html/storage/analytics',
$bufferSize = 1000,
$retentionDays = 365,
$trackPageViews = true,
$trackApiCalls = true,
$trackUserActions = true,
$trackErrors = true,
$trackPerformance = true
);
```
### Umgebungsvariablen
Die Konfiguration kann auch über Umgebungsvariablen angepasst werden:
```
ANALYTICS_ENABLED=true
ANALYTICS_SAMPLING_RATE=0.1
SECURITY_ANALYTICS_ENABLED=true
ANALYTICS_DATA_PATH=/var/www/html/storage/analytics
ANALYTICS_BUFFER_SIZE=1000
ANALYTICS_RETENTION_DAYS=365
ANALYTICS_TRACK_PAGE_VIEWS=true
ANALYTICS_TRACK_API_CALLS=true
ANALYTICS_TRACK_USER_ACTIONS=true
ANALYTICS_TRACK_ERRORS=true
ANALYTICS_TRACK_PERFORMANCE=true
```
## Datenanalyse
### Rohdaten abrufen
```php
// Rohdaten für Seitenaufrufe abrufen
$pageViews = $analyticsStorage->getRawData(
'page_view',
new \DateTimeImmutable('-7 days'),
new \DateTimeImmutable()
);
// Rohdaten für Geschäftsereignisse abrufen
$orders = $analyticsStorage->getRawData(
'business_event_order_completed',
new \DateTimeImmutable('-30 days'),
new \DateTimeImmutable()
);
```
### Aggregierte Daten abrufen
```php
// Aggregierte Daten für Seitenaufrufe abrufen
$pageViewStats = $analyticsStorage->getAggregatedData(
'analytics_page_views_total',
new \DateTimeImmutable('-7 days'),
new \DateTimeImmutable(),
['path' => '/products']
);
// Aggregierte Daten für API-Aufrufe abrufen
$apiCallStats = $analyticsStorage->getAggregatedData(
'analytics_api_calls_total',
new \DateTimeImmutable('-7 days'),
new \DateTimeImmutable(),
['path' => '/api/products', 'method' => 'GET']
);
```
### Dashboard
Das Analytics-Dashboard bietet eine visuelle Darstellung der erfassten Daten:
```php
use App\Framework\Analytics\Dashboard\AnalyticsDashboard;
// Dashboard initialisieren
$dashboard = new AnalyticsDashboard($analyticsStorage);
// Statistiken abrufen
$stats = $dashboard->getStats(
new \DateTimeImmutable('-7 days'),
new \DateTimeImmutable()
);
// Spezifische Statistiken abrufen
$pageViewStats = $dashboard->getPageViewStats();
$errorStats = $dashboard->getErrorStats();
$performanceStats = $dashboard->getPerformanceStats();
$businessStats = $dashboard->getBusinessStats();
```
## Integration
### Service-Container
Der Analytics-Service wird automatisch registriert und kann per Dependency Injection verwendet werden:
```php
use App\Framework\Analytics\AnalyticsCollector;
class UserController
{
public function __construct(
private readonly AnalyticsCollector $analyticsCollector
) {}
public function register(Request $request): Response
{
// Benutzerregistrierung verarbeiten
// Geschäftsereignis erfassen
$this->analyticsCollector->trackBusinessEvent(
'user_registered',
['user_id' => $user->id, 'email_domain' => $emailDomain]
);
return $response;
}
}
```
### Event-Integration
Das Analytics Framework kann mit dem Event-System des Frameworks integriert werden:
```php
use App\Framework\Analytics\EventSubscribers\AnalyticsEventSubscriber;
// In der Bootstrap-Datei
$eventDispatcher->addSubscriber(new AnalyticsEventSubscriber($analyticsCollector));
```
## Leistungsoptimierung
### Sampling
Um die Leistung bei hohem Datenaufkommen zu verbessern, unterstützt das Analytics Framework Sampling:
```php
// Sampling-Rate konfigurieren (10% der Daten erfassen)
$config = new AnalyticsConfig(
$enabled = true,
$samplingRate = 0.1
);
```
### Pufferung
Das Analytics Framework verwendet Pufferung, um die Anzahl der Schreibvorgänge zu reduzieren:
```php
// Puffergröße konfigurieren
$config = new AnalyticsConfig(
$enabled = true,
$samplingRate = 1.0,
$securityAnalyticsEnabled = true,
$dataPath = '/var/www/html/storage/analytics',
$bufferSize = 1000 // Anzahl der Ereignisse im Puffer
);
```
### Asynchrone Verarbeitung
Für maximale Leistung kann die Analytics-Verarbeitung asynchron erfolgen:
```php
use App\Framework\Analytics\AsyncAnalyticsCollector;
// Asynchronen Collector verwenden
$asyncCollector = new AsyncAnalyticsCollector(
$analyticsCollector,
$queue
);
// Daten asynchron erfassen
$asyncCollector->trackPageView('/products');
```
## Datenverwaltung
### Datenaufbewahrung
Das Analytics Framework unterstützt automatische Datenaufbewahrungsrichtlinien:
```php
// Aufbewahrungsdauer konfigurieren
$config = new AnalyticsConfig(
$enabled = true,
$samplingRate = 1.0,
$securityAnalyticsEnabled = true,
$dataPath = '/var/www/html/storage/analytics',
$bufferSize = 1000,
$retentionDays = 365 // Daten für 1 Jahr aufbewahren
);
```
### Datenexport
Daten können für die weitere Analyse exportiert werden:
```php
use App\Framework\Analytics\Export\AnalyticsExporter;
// Exporter initialisieren
$exporter = new AnalyticsExporter($analyticsStorage);
// Daten exportieren
$csvData = $exporter->exportToCsv(
'page_view',
new \DateTimeImmutable('-7 days'),
new \DateTimeImmutable()
);
// Daten in Datei speichern
file_put_contents('page_views.csv', $csvData);
```
## Fehlerbehebung
### Logging
Das Analytics Framework bietet umfangreiches Logging für die Fehlerbehebung:
```php
// In der AnalyticsCollector-Klasse
$this->logger->info("Analytics: trackAction called with action={$action}, category={$category->value}");
$this->logger->error("Analytics: Failed to store data", ['error' => $e->getMessage()]);
```
### Häufige Probleme
#### Keine Daten werden erfasst
Mögliche Ursachen:
- Analytics ist deaktiviert (`enabled = false`)
- Sampling-Rate ist zu niedrig
- Fehler beim Speichern der Daten
Lösung:
- Überprüfen Sie die Konfiguration
- Erhöhen Sie die Sampling-Rate
- Überprüfen Sie die Logs auf Fehler
#### Hohe Serverbelastung
Mögliche Ursachen:
- Zu viele Ereignisse werden erfasst
- Puffergröße ist zu klein
- Synchrone Verarbeitung bei hohem Datenaufkommen
Lösung:
- Reduzieren Sie die Sampling-Rate
- Erhöhen Sie die Puffergröße
- Verwenden Sie asynchrone Verarbeitung
## Weiterführende Informationen
- [Analytics Konfiguration](configuration.md)
- [Analytics Beispiele](examples.md)
- [Performance-Monitoring](/components/performance/index.md)