03e85c8fdfd711e2dee09661538866055e1e9c7a
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Log / Logger.php
1 <?php
2 namespace TYPO3\CMS\Core\Log;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18
19 /**
20 * Logger to log events and data for different components.
21 */
22 class Logger implements \Psr\Log\LoggerInterface
23 {
24 /**
25 * Logger name or component for which this logger is meant to be used for.
26 * This should be a dot-separated name and should normally be based on
27 * the class name or the name of a subsystem, such as
28 * core.t3lib.cache.manager, core.backend.workspaces or extension.news
29 *
30 * @var string
31 */
32 protected $name = '';
33
34 /**
35 * Unique ID of the request
36 *
37 * @var string
38 */
39 protected $requestId = '';
40
41 /**
42 * Minimum log level, anything below this level will be ignored.
43 *
44 * @var int
45 */
46 protected $minimumLogLevel = LogLevel::EMERGENCY;
47
48 /**
49 * Writers used by this logger
50 *
51 * @var array
52 */
53 protected $writers = [];
54
55 /**
56 * Processors used by this logger
57 *
58 * @var array
59 */
60 protected $processors = [];
61
62 /**
63 * Constructor.
64 *
65 * @param string $name A name for the logger.
66 * @param string $requestId Unique ID of the request
67 */
68 public function __construct(string $name, string $requestId = '')
69 {
70 $this->name = $name;
71 $this->requestId = $requestId;
72 }
73
74 /**
75 * Re-initialize instance with creating a new instance with up to date information
76 */
77 public function __wakeup()
78 {
79 $newLogger = GeneralUtility::makeInstance(LogManager::class)->getLogger($this->name);
80 $this->requestId = $newLogger->requestId;
81 $this->minimumLogLevel = $newLogger->minimumLogLevel;
82 $this->writers = $newLogger->writers;
83 $this->processors = $newLogger->processors;
84 }
85
86 /**
87 * Remove everything except the name, to be able to restore it on wakeup
88 *
89 * @return array
90 */
91 public function __sleep(): array
92 {
93 return ['name'];
94 }
95
96 /**
97 * Sets the minimum log level for which log records are written.
98 *
99 * @param int $level Minimum log level
100 * @return \TYPO3\CMS\Core\Log\Logger $this
101 */
102 protected function setMinimumLogLevel($level)
103 {
104 LogLevel::validateLevel($level);
105 $this->minimumLogLevel = $level;
106 return $this;
107 }
108
109 /**
110 * Gets the minimum log level for which log records are written.
111 *
112 * @return int Minimum log level
113 */
114 protected function getMinimumLogLevel()
115 {
116 return $this->minimumLogLevel;
117 }
118
119 /**
120 * Gets the logger's name.
121 *
122 * @return string Logger name.
123 */
124 public function getName()
125 {
126 return $this->name;
127 }
128
129 /**
130 * Adds a writer to this logger
131 *
132 * @param int $minimumLevel
133 * @param \TYPO3\CMS\Core\Log\Writer\WriterInterface $writer Writer object
134 * @return \TYPO3\CMS\Core\Log\Logger $this
135 */
136 public function addWriter($minimumLevel, Writer\WriterInterface $writer)
137 {
138 LogLevel::validateLevel($minimumLevel);
139 // Cycle through all the log levels which are as severe as or higher
140 // than $minimumLevel and add $writer to each severity level
141 for ($logLevelWhichTriggersWriter = LogLevel::EMERGENCY; $logLevelWhichTriggersWriter <= $minimumLevel; $logLevelWhichTriggersWriter++) {
142 if (!isset($this->writers[$logLevelWhichTriggersWriter])) {
143 $this->writers[$logLevelWhichTriggersWriter] = [];
144 }
145 $this->writers[$logLevelWhichTriggersWriter][] = $writer;
146 }
147 if ($minimumLevel > $this->getMinimumLogLevel()) {
148 $this->setMinimumLogLevel($minimumLevel);
149 }
150 return $this;
151 }
152
153 /**
154 * Returns all configured writers indexed by log level
155 *
156 * @return array
157 */
158 public function getWriters()
159 {
160 return $this->writers;
161 }
162
163 /**
164 * Adds a processor to the logger.
165 *
166 * @param int $minimumLevel
167 * @param \TYPO3\CMS\Core\Log\Processor\ProcessorInterface $processor The processor to add.
168 */
169 public function addProcessor($minimumLevel, Processor\ProcessorInterface $processor)
170 {
171 LogLevel::validateLevel($minimumLevel);
172 // Cycle through all the log levels which are as severe as or higher
173 // than $minimumLevel and add $processor to each severity level
174 for ($logLevelWhichTriggersProcessor = LogLevel::EMERGENCY; $logLevelWhichTriggersProcessor <= $minimumLevel; $logLevelWhichTriggersProcessor++) {
175 if (!isset($this->processors[$logLevelWhichTriggersProcessor])) {
176 $this->processors[$logLevelWhichTriggersProcessor] = [];
177 }
178 $this->processors[$logLevelWhichTriggersProcessor][] = $processor;
179 }
180 if ($minimumLevel > $this->getMinimumLogLevel()) {
181 $this->setMinimumLogLevel($minimumLevel);
182 }
183 }
184
185 /**
186 * Returns all added processors indexed by log level
187 *
188 * @return array
189 */
190 public function getProcessors()
191 {
192 return $this->processors;
193 }
194
195 /**
196 * Adds a log record.
197 *
198 * @param int|string $level Log level. Value according to \TYPO3\CMS\Core\Log\LogLevel. Alternatively accepts a string.
199 * @param string $message Log message.
200 * @param array $data Additional data to log
201 * @return mixed
202 */
203 public function log($level, $message, array $data = [])
204 {
205 $level = LogLevel::normalizeLevel($level);
206 LogLevel::validateLevel($level);
207 if ($level > $this->minimumLogLevel) {
208 return $this;
209 }
210 /** @var \TYPO3\CMS\Core\Log\LogRecord $record */
211 $record = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(LogRecord::class, $this->name, $level, $message, $data, $this->requestId);
212 $record = $this->callProcessors($record);
213 $this->writeLog($record);
214 return $this;
215 }
216
217 /**
218 * Calls all processors and returns log record
219 *
220 * @param \TYPO3\CMS\Core\Log\LogRecord $record Record to process
221 * @throws \RuntimeException
222 * @return \TYPO3\CMS\Core\Log\LogRecord Processed log record
223 */
224 protected function callProcessors(LogRecord $record)
225 {
226 if (!empty($this->processors[$record->getLevel()])) {
227 foreach ($this->processors[$record->getLevel()] as $processor) {
228 $processedRecord = $processor->processLogRecord($record);
229 if (!$processedRecord instanceof LogRecord) {
230 throw new \RuntimeException('Processor ' . get_class($processor) . ' returned invalid data. Instance of TYPO3\\CMS\\Core\\Log\\LogRecord expected', 1343593398);
231 }
232 $record = $processedRecord;
233 }
234 }
235 return $record;
236 }
237
238 /**
239 * Passes the \TYPO3\CMS\Core\Log\LogRecord to all registered writers.
240 *
241 * @param \TYPO3\CMS\Core\Log\LogRecord $record
242 */
243 protected function writeLog(LogRecord $record)
244 {
245 if (!empty($this->writers[$record->getLevel()])) {
246 foreach ($this->writers[$record->getLevel()] as $writer) {
247 $writer->writeLog($record);
248 }
249 }
250 }
251
252 /**
253 * Shortcut to log an EMERGENCY record.
254 *
255 * @param string $message Log message.
256 * @param array $data Additional data to log
257 * @return \TYPO3\CMS\Core\Log\Logger $this
258 */
259 public function emergency($message, array $data = [])
260 {
261 return $this->log(LogLevel::EMERGENCY, $message, $data);
262 }
263
264 /**
265 * Shortcut to log an ALERT record.
266 *
267 * @param string $message Log message.
268 * @param array $data Additional data to log
269 * @return \TYPO3\CMS\Core\Log\Logger $this
270 */
271 public function alert($message, array $data = [])
272 {
273 return $this->log(LogLevel::ALERT, $message, $data);
274 }
275
276 /**
277 * Shortcut to log a CRITICAL record.
278 *
279 * @param string $message Log message.
280 * @param array $data Additional data to log
281 * @return \TYPO3\CMS\Core\Log\Logger $this
282 */
283 public function critical($message, array $data = [])
284 {
285 return $this->log(LogLevel::CRITICAL, $message, $data);
286 }
287
288 /**
289 * Shortcut to log an ERROR record.
290 *
291 * @param string $message Log message.
292 * @param array $data Additional data to log
293 * @return \TYPO3\CMS\Core\Log\Logger $this
294 */
295 public function error($message, array $data = [])
296 {
297 return $this->log(LogLevel::ERROR, $message, $data);
298 }
299
300 /**
301 * Shortcut to log a WARNING record.
302 *
303 * @param string $message Log message.
304 * @param array $data Additional data to log
305 * @return \TYPO3\CMS\Core\Log\Logger $this
306 */
307 public function warning($message, array $data = [])
308 {
309 return $this->log(LogLevel::WARNING, $message, $data);
310 }
311
312 /**
313 * Shortcut to log a NOTICE record.
314 *
315 * @param string $message Log message.
316 * @param array $data Additional data to log
317 * @return \TYPO3\CMS\Core\Log\Logger $this
318 */
319 public function notice($message, array $data = [])
320 {
321 return $this->log(LogLevel::NOTICE, $message, $data);
322 }
323
324 /**
325 * Shortcut to log an INFORMATION record.
326 *
327 * @param string $message Log message.
328 * @param array $data Additional data to log
329 * @return \TYPO3\CMS\Core\Log\Logger $this
330 */
331 public function info($message, array $data = [])
332 {
333 return $this->log(LogLevel::INFO, $message, $data);
334 }
335
336 /**
337 * Shortcut to log a DEBUG record.
338 *
339 * @param string $message Log message.
340 * @param array $data Additional data to log
341 * @return \TYPO3\CMS\Core\Log\Logger $this
342 */
343 public function debug($message, array $data = [])
344 {
345 return $this->log(LogLevel::DEBUG, $message, $data);
346 }
347 }