Backup #796
| ID | 796 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Infrastructure/Logging/AuditLogger.php |
| Version | 3 |
| Typ |
modified |
| Größe | 5.2 KB |
| Hash | f4f7702cff58f04ccaf967dd21399d6d949997e4a60e309b62cedee85c500ac6 |
| Datum | 2025-12-23 08:06:44 |
| Geändert von | claude-code-hook |
| Grund | Claude Code Pre-Hook Backup vor Edit-Operation |
| Datei existiert |
Ja
|
Dateiinhalt
<?php
namespace Infrastructure\Logging;
use Infrastructure\Config\DatabaseFactory;
use PDO;
/**
* Audit Logger for tracking all important application events.
*
* Features:
* - Correlation ID for request tracing
* - Structured event logging with context
* - Entity-action pattern for CRUD operations
* - Automatic user and IP tracking
*/
final class AuditLogger
{
private string $correlationId;
private PDO $db;
private const LOG_LEVELS = ['debug', 'info', 'warning', 'error'];
public function __construct(?string $correlationId = null)
{
$this->correlationId = $correlationId
?? $_SERVER['HTTP_X_CORRELATION_ID']
?? $_SERVER['CORRELATION_ID']
?? $this->generateCorrelationId();
$this->db = DatabaseFactory::dev();
}
/**
* Generate a unique correlation ID.
*/
private function generateCorrelationId(): string
{
return bin2hex(random_bytes(8));
}
/**
* Get the current correlation ID.
*/
public function getCorrelationId(): string
{
return $this->correlationId;
}
/**
* Log a generic event.
*
* @param string $event Event name (e.g., "user.login", "chat.message.sent")
* @param array<string, mixed> $context Additional context data
* @param string $level Log level: debug, info, warning, error
*/
public function log(string $event, array $context = [], string $level = 'info'): void
{
if (!in_array($level, self::LOG_LEVELS, true)) {
$level = 'info';
}
$stmt = $this->db->prepare('
INSERT INTO audit_log
(correlation_id, event, context, level, user_id, ip_address, created_at)
VALUES (?, ?, ?, ?, ?, ?, NOW())
');
$stmt->execute([
$this->correlationId,
$event,
json_encode($context, JSON_UNESCAPED_UNICODE),
$level,
$this->getUserId(),
$this->getIpAddress(),
]);
}
/**
* Log an entity action (CRUD operation).
*
* @param string $action Action performed: create, read, update, delete, etc.
* @param string $entity Entity type: user, task, content, etc.
* @param int|null $entityId Entity ID (null for create before ID is known)
* @param array<string, mixed> $data Additional data about the action
*/
public function logAction(
string $action,
string $entity,
?int $entityId = null,
array $data = []
): void {
$event = "{$entity}.{$action}";
$stmt = $this->db->prepare('
INSERT INTO audit_log
(correlation_id, event, entity_type, entity_id, context, level, user_id, ip_address, created_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())
');
$stmt->execute([
$this->correlationId,
$event,
$entity,
$entityId,
json_encode($data, JSON_UNESCAPED_UNICODE),
'info',
$this->getUserId(),
$this->getIpAddress(),
]);
}
/**
* Log an error event.
*/
public function logError(string $event, string $message, array $context = []): void
{
$context['error_message'] = $message;
$this->log($event, $context, 'error');
}
/**
* Log a warning event.
*/
public function logWarning(string $event, string $message, array $context = []): void
{
$context['warning_message'] = $message;
$this->log($event, $context, 'warning');
}
/**
* Log debug information (only in development).
*/
public function debug(string $event, array $context = []): void
{
// Only log debug in development
$appEnv = $_ENV['APP_ENV'] ?? 'production';
if ($appEnv === 'development') {
$this->log($event, $context, 'debug');
}
}
/**
* Get the current user ID from session.
*/
private function getUserId(): ?int
{
return isset($_SESSION['user_id']) ? (int) $_SESSION['user_id'] : null;
}
/**
* Get the client IP address.
*/
private function getIpAddress(): ?string
{
return $_SERVER['HTTP_X_FORWARDED_FOR']
?? $_SERVER['HTTP_X_REAL_IP']
?? $_SERVER['REMOTE_ADDR']
?? null;
}
/**
* Query logs by correlation ID.
*
* @return array<int, array<string, mixed>>
*/
public function getByCorrelationId(string $correlationId): array
{
$stmt = $this->db->prepare('
SELECT * FROM audit_log
WHERE correlation_id = ?
ORDER BY created_at ASC
');
$stmt->execute([$correlationId]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Query recent logs for an entity.
*
* @return array<int, array<string, mixed>>
*/
public function getByEntity(string $entityType, int $entityId, int $limit = 50): array
{
$stmt = $this->db->prepare('
SELECT * FROM audit_log
WHERE entity_type = ? AND entity_id = ?
ORDER BY created_at DESC
LIMIT ?
');
$stmt->execute([$entityType, $entityId, $limit]);
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
}
Vollständig herunterladen
Aktionen
Andere Versionen dieser Datei
| ID |
Version |
Typ |
Größe |
Datum |
| 1210 |
4 |
modified |
5.1 KB |
2025-12-25 10:39 |
| 796 |
3 |
modified |
5.2 KB |
2025-12-23 08:06 |
| 527 |
2 |
modified |
5.2 KB |
2025-12-22 16:48 |
| 524 |
1 |
modified |
5.2 KB |
2025-12-22 16:46 |
← Zurück zur Übersicht