1: <?php declare(strict_types=1);
2:
3: namespace Salient\Console;
4:
5: use Psr\Log\InvalidArgumentException;
6: use Psr\Log\LoggerInterface;
7: use Psr\Log\LogLevel;
8: use Salient\Contract\Console\ConsoleMessageType as MessageType;
9: use Salient\Contract\Console\ConsoleWriterInterface;
10: use Salient\Contract\Core\MessageLevel as Level;
11: use Salient\Utility\Format;
12: use Throwable;
13:
14: /**
15: * A PSR-3 logger backed by a console writer
16: */
17: final class ConsoleLogger implements LoggerInterface
18: {
19: private const LOG_LEVEL_MAP = [
20: LogLevel::EMERGENCY => Level::EMERGENCY,
21: LogLevel::ALERT => Level::ALERT,
22: LogLevel::CRITICAL => Level::CRITICAL,
23: LogLevel::ERROR => Level::ERROR,
24: LogLevel::WARNING => Level::WARNING,
25: LogLevel::NOTICE => Level::NOTICE,
26: LogLevel::INFO => Level::INFO,
27: LogLevel::DEBUG => Level::DEBUG,
28: ];
29:
30: private ConsoleWriterInterface $Writer;
31:
32: /**
33: * Creates a new ConsoleLogger object
34: */
35: public function __construct(ConsoleWriterInterface $writer)
36: {
37: $this->Writer = $writer;
38: }
39:
40: /**
41: * @inheritDoc
42: */
43: public function emergency($message, array $context = [])
44: {
45: $this->log(LogLevel::EMERGENCY, $message, $context);
46: }
47:
48: /**
49: * @inheritDoc
50: */
51: public function alert($message, array $context = [])
52: {
53: $this->log(LogLevel::ALERT, $message, $context);
54: }
55:
56: /**
57: * @inheritDoc
58: */
59: public function critical($message, array $context = [])
60: {
61: $this->log(LogLevel::CRITICAL, $message, $context);
62: }
63:
64: /**
65: * @inheritDoc
66: */
67: public function error($message, array $context = [])
68: {
69: $this->log(LogLevel::ERROR, $message, $context);
70: }
71:
72: /**
73: * @inheritDoc
74: */
75: public function warning($message, array $context = [])
76: {
77: $this->log(LogLevel::WARNING, $message, $context);
78: }
79:
80: /**
81: * @inheritDoc
82: */
83: public function notice($message, array $context = [])
84: {
85: $this->log(LogLevel::NOTICE, $message, $context);
86: }
87:
88: /**
89: * @inheritDoc
90: */
91: public function info($message, array $context = [])
92: {
93: $this->log(LogLevel::INFO, $message, $context);
94: }
95:
96: /**
97: * @inheritDoc
98: */
99: public function debug($message, array $context = [])
100: {
101: $this->log(LogLevel::DEBUG, $message, $context);
102: }
103:
104: /**
105: * @inheritDoc
106: */
107: public function log($level, $message, array $context = [])
108: {
109: if (!isset(self::LOG_LEVEL_MAP[$level])) {
110: throw new InvalidArgumentException('Invalid log level');
111: }
112:
113: if ($context) {
114: foreach ($context as $key => $value) {
115: $replace['{' . $key . '}'] = Format::value($value);
116: }
117: $message = strtr($message, $replace);
118:
119: if (
120: isset($context['exception'])
121: && $context['exception'] instanceof Throwable
122: ) {
123: $exception = $context['exception'];
124: }
125: }
126:
127: $this->Writer->message(
128: (string) $message,
129: null,
130: self::LOG_LEVEL_MAP[$level],
131: MessageType::STANDARD,
132: $exception ?? null,
133: );
134: }
135: }
136: