230 lines
7.0 KiB
PHP
230 lines
7.0 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the TYPO3 CMS project.
|
|
*
|
|
* It is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License, either version 2
|
|
* of the License, or any later version.
|
|
*
|
|
* For the full copyright and license information, please read the
|
|
* LICENSE.txt file that was distributed with this source code.
|
|
*
|
|
* The TYPO3 project - inspiring people to share!
|
|
*/
|
|
|
|
namespace TYPO3\CMS\Core\Log;
|
|
|
|
use Psr\Log\LoggerInterface;
|
|
use Psr\Log\LoggerTrait;
|
|
use TYPO3\CMS\Core\Log\Processor\ProcessorInterface;
|
|
use TYPO3\CMS\Core\Log\Writer\WriterInterface;
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
|
|
|
/**
|
|
* Logger to log events and data for different components.
|
|
*/
|
|
final class Logger implements LoggerInterface
|
|
{
|
|
use LoggerTrait;
|
|
|
|
/**
|
|
* Logger name or component for which this logger is meant to be used for.
|
|
*
|
|
* This should be a dot-separated name and should normally be based on
|
|
* the class name or the name of a subsystem, such as
|
|
* core.t3lib.cache.manager, core.backend.workspaces or extension.news
|
|
*/
|
|
protected string $name = '';
|
|
|
|
/**
|
|
* Minimum log level, anything below this level will be ignored.
|
|
*/
|
|
protected int $minimumLogLevel;
|
|
|
|
/**
|
|
* Writers used by this logger
|
|
*/
|
|
protected array $writers = [];
|
|
|
|
/**
|
|
* Processors used by this logger
|
|
*/
|
|
protected array $processors = [];
|
|
|
|
/**
|
|
* Constructor.
|
|
*
|
|
* @param string $name A name for the logger.
|
|
*/
|
|
public function __construct(string $name)
|
|
{
|
|
$this->name = $name;
|
|
$this->minimumLogLevel = LogLevel::normalizeLevel(LogLevel::EMERGENCY);
|
|
}
|
|
|
|
/**
|
|
* Re-initialize instance with creating a new instance with up to date information
|
|
*/
|
|
public function __wakeup()
|
|
{
|
|
$newLogger = GeneralUtility::makeInstance(LogManager::class)->getLogger($this->name);
|
|
$this->minimumLogLevel = $newLogger->minimumLogLevel;
|
|
$this->writers = $newLogger->writers;
|
|
$this->processors = $newLogger->processors;
|
|
}
|
|
|
|
/**
|
|
* Remove everything except the name, to be able to restore it on wakeup
|
|
*/
|
|
public function __sleep(): array
|
|
{
|
|
return ['name'];
|
|
}
|
|
|
|
/**
|
|
* Sets the minimum log level for which log records are written.
|
|
*
|
|
* @param int $level Minimum log level
|
|
* @return \TYPO3\CMS\Core\Log\Logger $this
|
|
*/
|
|
protected function setMinimumLogLevel($level)
|
|
{
|
|
LogLevel::validateLevel($level);
|
|
$this->minimumLogLevel = $level;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Gets the minimum log level for which log records are written.
|
|
*
|
|
* @return int Minimum log level
|
|
*/
|
|
protected function getMinimumLogLevel()
|
|
{
|
|
return $this->minimumLogLevel;
|
|
}
|
|
|
|
/**
|
|
* Gets the logger's name.
|
|
*
|
|
* @return string Logger name.
|
|
*/
|
|
public function getName()
|
|
{
|
|
return $this->name;
|
|
}
|
|
|
|
/**
|
|
* Adds a writer to this logger
|
|
*
|
|
* @param \TYPO3\CMS\Core\Log\Writer\WriterInterface $writer Writer object
|
|
* @return \TYPO3\CMS\Core\Log\Logger $this
|
|
*/
|
|
public function addWriter(string $minimumLevel, WriterInterface $writer)
|
|
{
|
|
$minLevelAsNumber = LogLevel::normalizeLevel($minimumLevel);
|
|
// Cycle through all the log levels which are as severe as or higher
|
|
// than $minimumLevel and add $writer to each severity level
|
|
foreach (LogLevel::atLeast($minLevelAsNumber) as $levelName) {
|
|
$this->writers[$levelName] ??= [];
|
|
$this->writers[$levelName][] = $writer;
|
|
}
|
|
if ($minLevelAsNumber > $this->getMinimumLogLevel()) {
|
|
$this->setMinimumLogLevel($minLevelAsNumber);
|
|
}
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Returns all configured writers indexed by log level
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getWriters()
|
|
{
|
|
return $this->writers;
|
|
}
|
|
|
|
/**
|
|
* Adds a processor to the logger.
|
|
*
|
|
* @param \TYPO3\CMS\Core\Log\Processor\ProcessorInterface $processor The processor to add.
|
|
*/
|
|
public function addProcessor(string $minimumLevel, ProcessorInterface $processor)
|
|
{
|
|
$minLevelAsNumber = LogLevel::normalizeLevel($minimumLevel);
|
|
LogLevel::validateLevel($minLevelAsNumber);
|
|
// Cycle through all the log levels which are as severe as or higher
|
|
// than $minimumLevel and add $processor to each severity level
|
|
for ($logLevelWhichTriggersProcessor = LogLevel::normalizeLevel(\Psr\Log\LogLevel::EMERGENCY); $logLevelWhichTriggersProcessor <= $minLevelAsNumber; $logLevelWhichTriggersProcessor++) {
|
|
$logLevelName = LogLevel::getInternalName($logLevelWhichTriggersProcessor);
|
|
$this->processors[$logLevelName] ??= [];
|
|
$this->processors[$logLevelName][] = $processor;
|
|
}
|
|
if ($minLevelAsNumber > $this->getMinimumLogLevel()) {
|
|
$this->setMinimumLogLevel($minLevelAsNumber);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns all added processors indexed by log level
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getProcessors()
|
|
{
|
|
return $this->processors;
|
|
}
|
|
|
|
/**
|
|
* Adds a log record.
|
|
*
|
|
* @param int|string $level Log level. Value according to \TYPO3\CMS\Core\Log\LogLevel. Alternatively accepts a string.
|
|
* @param string|\Stringable $message Log message.
|
|
* @param array $data Additional data to log
|
|
*/
|
|
public function log($level, string|\Stringable $message, array $data = []): void
|
|
{
|
|
$level = LogLevel::normalizeLevel($level);
|
|
LogLevel::validateLevel($level);
|
|
if ($level > $this->minimumLogLevel) {
|
|
return;
|
|
}
|
|
$record = new LogRecord($this->name, LogLevel::getInternalName($level), $message, $data);
|
|
$record = $this->callProcessors($record);
|
|
$this->writeLog($record);
|
|
}
|
|
|
|
/**
|
|
* Calls all processors and returns log record
|
|
*
|
|
* @param \TYPO3\CMS\Core\Log\LogRecord $record Record to process
|
|
* @throws \RuntimeException
|
|
* @return \TYPO3\CMS\Core\Log\LogRecord Processed log record
|
|
*/
|
|
protected function callProcessors(LogRecord $record)
|
|
{
|
|
/** @var ProcessorInterface $processor */
|
|
foreach ($this->processors[$record->getLevel()] ?? [] as $processor) {
|
|
$processedRecord = $processor->processLogRecord($record);
|
|
if (!$processedRecord instanceof LogRecord) {
|
|
throw new \RuntimeException('Processor ' . get_class($processor) . ' returned invalid data. Instance of TYPO3\\CMS\\Core\\Log\\LogRecord expected', 1343593398);
|
|
}
|
|
$record = $processedRecord;
|
|
}
|
|
return $record;
|
|
}
|
|
|
|
/**
|
|
* Passes the \TYPO3\CMS\Core\Log\LogRecord to all registered writers.
|
|
*/
|
|
protected function writeLog(LogRecord $record)
|
|
{
|
|
/** @var WriterInterface $writer */
|
|
foreach ($this->writers[$record->getLevel()] ?? [] as $writer) {
|
|
$writer->writeLog($record);
|
|
}
|
|
}
|
|
}
|