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:
477
docs/components/analytics/configuration.md
Normal file
477
docs/components/analytics/configuration.md
Normal 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)
|
||||
760
docs/components/analytics/examples.md
Normal file
760
docs/components/analytics/examples.md
Normal 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)
|
||||
507
docs/components/analytics/index.md
Normal file
507
docs/components/analytics/index.md
Normal 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)
|
||||
Reference in New Issue
Block a user