79 lines
1.9 KiB
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);
|
|
}
|
|
}
|