Files
UploadShied/core/Logger.php

79 lines
1.9 KiB
PHP

<?php
declare(strict_types=1);
namespace UploadLogger\Core;
/**
* Structured JSON logger with request context.
*/
final class Logger
{
private string $logFile;
/** @var array<string, mixed> */
private array $context;
/**
* @param array<string, mixed> $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<string, mixed> $context
*/
public function setContext(array $context): void
{
$this->context = $context;
}
/**
* @param array<string, mixed> $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);
}
}