*/ private array $context; /** * @param array $context */ public function __construct(string $logFile, array $context = [], ?Config $config = null) { $this->logFile = $logFile; $this->context = $context; // Keep optional config parameter for backward compatibility (unused here) unset($config); } /** * @param array $context */ public function setContext(array $context): void { $this->context = $context; } /** * @param array $data */ public function logEvent(string $event, array $data = []): void { $payload = array_merge( ['ts' => gmdate('c'), 'event' => $event], $this->context, $data ); $payload = $this->normalizeValue($payload); $json = json_encode($payload, JSON_UNESCAPED_SLASHES); if ($json === false) { $json = json_encode([ 'ts' => gmdate('c'), 'event' => 'log_error', 'error' => json_last_error_msg(), ], JSON_UNESCAPED_SLASHES); } @file_put_contents($this->logFile, $json . "\n", FILE_APPEND | LOCK_EX); } private function normalizeValue(mixed $value): mixed { if (is_array($value)) { $out = []; foreach ($value as $k => $v) { $out[$k] = $this->normalizeValue($v); } return $out; } if (is_bool($value) || is_int($value) || is_float($value) || $value === null) { return $value; } $str = (string)$value; return preg_replace('/[\x00-\x1F\x7F]/', '_', $str); } }