AuditLogger.php
- Pfad:
src/Infrastructure/Logging/AuditLogger.php - Namespace: Infrastructure\Logging
- Zeilen: 190 | Größe: 5,171 Bytes
- Geändert: 2025-12-25 10:39:59 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 96
- Dependencies: 100 (25%)
- LOC: 100 (20%)
- Methods: 80 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 100 (10%)
Keine Issues gefunden.
Dependencies 2
- constructor PDO
- use PDO
Klassen 1
-
AuditLoggerclass Zeile 11
Funktionen 12
-
__construct()public Zeile 18 -
generateCorrelationId()private Zeile 30 -
getCorrelationId()public Zeile 38 -
log()public Zeile 50 -
logAction()public Zeile 80 -
logError()Zeile 109 -
logWarning()Zeile 118 -
debug()Zeile 127 -
getUserId()Zeile 139 -
getIpAddress()Zeile 147 -
getByCorrelationId()Zeile 160 -
getByEntity()Zeile 177
Verwendet von 1
Versionen 4
-
v4
2025-12-25 10:39 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v3
2025-12-23 08:06 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v2
2025-12-22 16:48 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation -
v1
2025-12-22 16:46 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
Code
<?php
declare(strict_types=1);
namespace Infrastructure\Logging;
// @responsibility: Audit-Logging mit Correlation-ID und strukturiertem Kontext
use PDO;
final class AuditLogger
{
private string $correlationId;
private PDO $db;
private const LOG_LEVELS = ['debug', 'info', 'warning', 'error'];
public function __construct(PDO $pdo, ?string $correlationId = null)
{
$this->db = $pdo;
$this->correlationId = $correlationId
?? $_SERVER['HTTP_X_CORRELATION_ID']
?? $_SERVER['CORRELATION_ID']
?? $this->generateCorrelationId();
}
/**
* 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);
}
}