PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.8
Booking for Appointments and Events Calendar – Amelia v2.4.8
2.4.9 2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / src / Infrastructure / Services / Logger / JsonLineFormatter.php
ameliabooking / src / Infrastructure / Services / Logger Last commit date
JsonLineFormatter.php 1 week ago LogDirectoryManager.php 1 week ago LogRetentionCleanupService.php 1 week ago LogSanitizer.php 1 week ago MonologChannelLogger.php 1 week ago MonologLoggerFactory.php 1 week ago RequestIdProcessor.php 1 week ago
JsonLineFormatter.php
72 lines
1 <?php
2
3 namespace AmeliaBooking\Infrastructure\Services\Logger;
4
5 use AmeliaVendor\Monolog\Formatter\FormatterInterface;
6 use DateTimeInterface;
7
8 /**
9 * Class JsonLineFormatter
10 *
11 * Formats a Monolog record as a single JSON-line:
12 * {"timestamp":"...","level":"ERROR","message":"...","context":{"channel":"payment","request_id":"...","order_id":42}}
13 *
14 * @package AmeliaBooking\Infrastructure\Services\Logger
15 */
16 class JsonLineFormatter implements FormatterInterface
17 {
18 private const ENCODE_FLAGS = JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE;
19
20 /**
21 * @param mixed[] $record
22 *
23 * @return string
24 */
25 public function format(array $record)
26 {
27 $datetime = $record['datetime'] ?? null;
28 $timestamp = $datetime instanceof DateTimeInterface
29 ? $datetime->format(DATE_ATOM)
30 : gmdate(DATE_ATOM);
31
32 // Caller context first, then processor extras, then force the Monolog channel last
33 // so caller-supplied keys cannot overwrite trusted channel metadata.
34 $context = array_merge(
35 is_array($record['context'] ?? null) ? $record['context'] : [],
36 is_array($record['extra'] ?? null) ? $record['extra'] : [],
37 ['channel' => $record['channel'] ?? 'app']
38 );
39
40 $payload = [
41 'timestamp' => $timestamp,
42 'level' => strtoupper((string) ($record['level_name'] ?? 'INFO')),
43 'message' => (string) ($record['message'] ?? ''),
44 'context' => $context,
45 ];
46
47 $encoded = json_encode($payload, self::ENCODE_FLAGS);
48
49 if ($encoded === false) {
50 $encoded = '{"timestamp":"' . $timestamp . '","level":"ERROR","message":"log_encode_failed","context":{}}';
51 }
52
53 return $encoded . "\n";
54 }
55
56 /**
57 * @param mixed[] $records
58 *
59 * @return string
60 */
61 public function formatBatch(array $records)
62 {
63 $formatted = '';
64
65 foreach ($records as $record) {
66 $formatted .= $this->format($record);
67 }
68
69 return $formatted;
70 }
71 }
72