diff --git a/Classes/Logger/Logger.php b/Classes/Logger/Logger.php index 6b69dcf3..5a6adf58 100644 --- a/Classes/Logger/Logger.php +++ b/Classes/Logger/Logger.php @@ -22,6 +22,7 @@ ***************************************************************/ use PunktDe\PtExtbase\Logger\Processor\ReplaceComponentProcessor; +use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Log\LogLevel; @@ -31,9 +32,9 @@ class Logger implements SingletonInterface { /** - * @var LoggerManager + * @var LogManager */ - protected $loggerManager; + protected $logManager; /** * @var \TYPO3\CMS\Core\Log\Logger @@ -75,11 +76,11 @@ public function __construct() } /** - * @param LoggerManager $loggerManager + * @param LogManager $logManager */ - public function injectLoggerManager(LoggerManager $loggerManager) + public function injectLogManager(LogManager $logManager) { - $this->loggerManager = $loggerManager; + $this->logManager = $logManager; } /** @@ -123,14 +124,6 @@ protected function configureLoggerProperties() $GLOBALS['TYPO3_CONF_VARS']['LOG']['processorConfiguration'][LogLevel::DEBUG] = [ ReplaceComponentProcessor::class => [] ]; - - $internalName = LogLevel::getInternalName($this->loggerConfiguration->getEmailLogLevelThreshold()); - - if ($this->loggerConfiguration->weHaveAnyEmailReceivers()) { - $GLOBALS['TYPO3_CONF_VARS']['LOG']['processorConfiguration'][$internalName]['Tx_PtExtbase_Logger_Processor_EmailProcessor'] = [ - 'receivers' => $this->loggerConfiguration->getEmailReceivers() - ]; - } } @@ -144,7 +137,7 @@ protected function getLogger($logComponent) if ($logComponent === null) { $logComponent = $this->defaultLogComponent; } - return $this->logger = $this->loggerManager->getLogger($logComponent); + return $this->logger = $this->logManager->getLogger($logComponent); } @@ -400,9 +393,9 @@ public function enrichLogDataByComponent(&$data, $component) $this->enrichLoggerSpecificDataByComponent($data, $component); if (empty($component)) { - $data['loggerComponent'] = $this->loggerManager->unifyComponentName($this->defaultLogComponent); + $data['loggerComponent'] = $this->unifyComponentName($this->defaultLogComponent); } else { - $data['loggerComponent'] = $this->loggerManager->unifyComponentName($component); + $data['loggerComponent'] = $this->unifyComponentName($component); } return $this; @@ -415,4 +408,15 @@ public function enrichLogDataByComponent(&$data, $component) public function enrichLoggerSpecificDataByComponent(&$data, $component) { } + /** + * Transform namespaces and underscore class names to the dot-name style + * + * @param $componentName + * @return string + */ + public function unifyComponentName($componentName) + { + $separators = ['_', '\\']; + return str_replace($separators, '.', $componentName); + } } diff --git a/Classes/Logger/LoggerConfiguration.php b/Classes/Logger/LoggerConfiguration.php index 9cf495a6..731e4ed7 100644 --- a/Classes/Logger/LoggerConfiguration.php +++ b/Classes/Logger/LoggerConfiguration.php @@ -53,27 +53,12 @@ class LoggerConfiguration implements SingletonInterface */ protected $logLevelThreshold = 6; - - /** - * @var integer - */ - protected $emailLogLevelThreshold = 2; - - - /** - * @var string - */ - protected $emailReceivers = ''; - - public function __construct() { $this->extensionConfiguration = Div::returnExtConfArray('pt_extbase'); $this->evaluateLogFilePath(); $this->evaluateExceptionDirectory(); $this->setLogLevelThresholdByExtensionConfigurationProperty('logLevelThreshold'); - $this->setLogLevelThresholdByExtensionConfigurationProperty('emailLogLevelThreshold'); - $this->evaluateEmailReceivers(); } @@ -123,32 +108,6 @@ protected function setLogLevelThresholdByExtensionConfigurationProperty($propert } } - - - /** - * @return void - * - * TODO: Add some logic to check if e-mail addresses are syntactically valid - */ - protected function evaluateEmailReceivers() - { - if (array_key_exists('emailReceivers', $this->extensionConfiguration)) { - $this->emailReceivers = $this->extensionConfiguration['emailReceivers']; - } - } - - - - /** - * @return int - */ - public function getEmailLogLevelThreshold() - { - return $this->emailLogLevelThreshold; - } - - - /** * @return string */ @@ -157,8 +116,6 @@ public function getExceptionDirectory() return $this->exceptionDirectory; } - - /** * @return string */ @@ -167,8 +124,6 @@ public function getLogFilePath() return $this->logFilePath; } - - /** * @return int */ @@ -176,27 +131,4 @@ public function getLogLevelThreshold() { return $this->logLevelThreshold; } - - - - /** - * @return string - */ - public function getEmailReceivers() - { - return $this->emailReceivers; - } - - - - /** - * @return boolean - */ - public function weHaveAnyEmailReceivers() - { - if ($this->emailReceivers === '') { - return false; - } - return true; - } } diff --git a/Classes/Logger/LoggerManager.php b/Classes/Logger/LoggerManager.php deleted file mode 100755 index ce51dbbf..00000000 --- a/Classes/Logger/LoggerManager.php +++ /dev/null @@ -1,125 +0,0 @@ - - * - * This script is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use \TYPO3\CMS\Core\Utility\GeneralUtility; -use \TYPO3\CMS\Core\Log\LogManager; - -/** - * Logger Manager - * - * @package pt_extbase - */ -class LoggerManager extends LogManager -{ - /** - * @const LOGGER_INDEX_PREFIX - */ - const LOGGER_INDEX_PREFIX = 'PTEXTBASE'; - - - /** - * @var array|NULL - */ - protected $loggerConfiguration; - - - /** - * @return LoggerManager - */ - public function __construct() - { - parent::__construct(); - $this->loggerConfiguration = &$GLOBALS['TYPO3_CONF_VARS']['LOG']; - } - - - - /** - * Gets a logger instance for the given name. - * - * This method overrides the TYPO3 core logger method to reduce the number - * of instantiated loggers. This is done by grouping loggers by their - * available configuration. - * - * @param string $name Logger name, empty to get the global "root" logger. - * @return \TYPO3\CMS\Core\Log\Logger Logger with name $name - */ - public function getLogger($name = '') - { - $logger = null; /** @var $logger \TYPO3\CMS\Core\Log\Logger */ - - $componentName = $this->unifyComponentName($name); - $indexName = $this->evaluateIndexNameByComponentName($componentName); - - if (isset($this->loggers[$indexName])) { - $logger = $this->loggers[$indexName]; - } else { - $logger = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\Logger::class, $indexName); - $this->loggers[$indexName] = $logger; - $this->setWritersForLogger($logger); - $this->setProcessorsForLogger($logger); - } - - return $logger; - } - - - - /** - * @param $componentName - * @return string - */ - protected function evaluateIndexNameByComponentName($componentName) - { - $indexNameParts = [self::LOGGER_INDEX_PREFIX]; - - $explodedName = explode('.', $componentName); - $configuration = $this->loggerConfiguration; - - foreach ($explodedName as $partOfClassName) { - if (!empty($configuration[$partOfClassName])) { - $indexNameParts[] = $partOfClassName; - $configuration = $configuration[$partOfClassName]; - } else { - break; - } - - } - - return implode('.', $indexNameParts); - } - - - - /** - * Transform namespaces and underscore class names to the dot-name style - * - * @param $componentName - * @return string - */ - public function unifyComponentName($componentName) - { - $separators = ['_', '\\']; - return str_replace($separators, '.', $componentName); - } -} diff --git a/Classes/Logger/Processor/EmailProcessor.php_ignore b/Classes/Logger/Processor/EmailProcessor.php_ignore deleted file mode 100644 index aa3247e8..00000000 --- a/Classes/Logger/Processor/EmailProcessor.php_ignore +++ /dev/null @@ -1,137 +0,0 @@ - - * - * This script is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ - -use \TYPO3\CMS\Fluid\View\StandaloneView; -use \TYPO3\CMS\Core\Utility\GeneralUtility; -use \TYPO3\CMS\Core\Log\LogRecord; - -/** - * Logger Email Processor - */ -class Tx_PtExtbase_Logger_Processor_EmailProcessor extends TYPO3\CMS\Core\Log\Processor\AbstractProcessor -{ - /** - * @var string - */ - protected $receivers; - - - /** - * @var LogRecord - */ - protected $logRecord; - - - /** - * @var Tx_PtExtbase_Utility_ServerInformation - */ - protected $serverInformation; - - - /** - * @var \PunktDe\PtExtbase\Utility\RequestInformation - */ - protected $requestInformation; - - - /** - * @var Tx_PtExtbase_Utility_UserAgent - */ - protected $userAgent; - - - /** - * @var \TYPO3\CMS\Extbase\Object\ObjectManagerInterface - */ - protected $objectManager; - - - /** - * @param array $options - */ - public function __construct(array $options = []) - { - parent::__construct($options); - $this->objectManager = GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager'); - $this->serverInformation = $this->objectManager->get('Tx_PtExtbase_Utility_ServerInformation'); - $this->requestInformation = $this->objectManager->get('PunktDe\PtExtbase\Utility\RequestInformation'); - $this->userAgent = $this->objectManager->get('Tx_PtExtbase_Utility_UserAgent'); - } - - - - /** - * @param LogRecord $logRecord - * @return LogRecord - */ - public function processLogRecord(LogRecord $logRecord) - { - $this->logRecord = $logRecord; - - try { - $mail = $this->objectManager->get('TYPO3\CMS\Core\Mail\MailMessage'); - /** @var \TYPO3\CMS\Core\Mail\MailMessage $mail */ - $mail->setFrom(["noreply@punkt.de" => "noreply@punkt.de"]); - $mail->setTo($this->receivers); - $mail->setSubject(sprintf('%s: Error on system %s', $this->getNamespaceOfLogComponent(), $this->serverInformation->getServerHostName())); - $mail->setBody($this->renderViewForMail()); - $mail->send(); - } catch (\Exception $exception) { - error_log('The error mail could not be sent!'); - } - return $logRecord; - } - - - - /** - * @return string - */ - protected function renderViewForMail() - { - $view = new StandaloneView(); - $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:pt_extbase/Resources/Private/Templates/Logger/ErrorEmail.html')); - $view->assign('logRecord', $this->logRecord); - $view->assign('serverInformation', $this->serverInformation); - $view->assign('userAgent', $this->userAgent); - $view->assign('requestId', $this->requestInformation->getCurrentRequestId()); - return $view->render(); - } - - - /** - * @param string $receivers - */ - public function setReceivers($receivers) - { - $this->receivers = $receivers; - } - - /** - * @return string - */ - protected function getNamespaceOfLogComponent() - { - $componentParts = explode('.', $this->logRecord->getComponent()); - - return $componentParts[1]; - } -} diff --git a/Classes/Logger/Processor/FormatProcessor.php_ignore b/Classes/Logger/Processor/FormatProcessor.php similarity index 89% rename from Classes/Logger/Processor/FormatProcessor.php_ignore rename to Classes/Logger/Processor/FormatProcessor.php index cd05d0c4..72614f7b 100644 --- a/Classes/Logger/Processor/FormatProcessor.php_ignore +++ b/Classes/Logger/Processor/FormatProcessor.php @@ -1,4 +1,10 @@ 'formatH1', @@ -36,10 +42,10 @@ class Tx_PtExtbase_Logger_FormatProcessor extends TYPO3\CMS\Core\Log\Processor\A /** * Formats the log * - * @param \TYPO3\CMS\Core\Log\LogRecord $logRecord - * @return \TYPO3\CMS\Core\Log\LogRecord + * @param LogRecord $logRecord + * @return LogRecord */ - public function processLogRecord(\TYPO3\CMS\Core\Log\LogRecord $logRecord) + public function processLogRecord(LogRecord $logRecord) { $message = $logRecord->getMessage(); diff --git a/Tests/Functional/Utility/Wget/WgetTest.php b/Tests/Functional/Utility/Wget/WgetTest.php index 5bb887bc..73c5ed94 100755 --- a/Tests/Functional/Utility/Wget/WgetTest.php +++ b/Tests/Functional/Utility/Wget/WgetTest.php @@ -23,13 +23,13 @@ use PunktDe\PtExtbase\Exception\InternalException; use PunktDe\PtExtbase\Logger\Logger; -use PunktDe\PtExtbase\Logger\LoggerManager; use PunktDe\PtExtbase\Testing\Unit\AbstractBaseTestcase; use PunktDe\PtExtbase\Utility\Files; use PunktDe\PtExtbase\Utility\Wget\WgetCommand; use PunktDe\PtExtbase\Utility\Wget\WgetLogEntry; use PunktDe\PtExtbase\Utility\Wget\WgetLogParser; use TYPO3\CMS\Core\Core\Environment; +use TYPO3\CMS\Core\Log\LogManager; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Object\Container\Container as ExtbaseContainer; use TYPO3\CMS\Extbase\Object\ObjectManager; @@ -74,7 +74,7 @@ public function setUp(): void $this->wgetCommand = GeneralUtility::makeInstance(WgetCommand::class); $logger = GeneralUtility::makeInstance(Logger::class); - $logger->injectLoggerManager(GeneralUtility::makeInstance(LoggerManager::class)); + $logger->injectLoggerManager(GeneralUtility::makeInstance(LogManager::class)); $this->wgetCommand->injectLogger($logger); $this->wgetLogParser = $this->objectManager->get(WgetLogParser::class); diff --git a/Tests/Unit/Logger/LoggerManagerTest.php b/Tests/Unit/Logger/LoggerManagerTest.php deleted file mode 100644 index 4ad569df..00000000 --- a/Tests/Unit/Logger/LoggerManagerTest.php +++ /dev/null @@ -1,257 +0,0 @@ - - * - * This script is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This script is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * This copyright notice MUST APPEAR in all copies of the script! - ***************************************************************/ -use PunktDe\PtExtbase\Logger\LoggerManager; - -/** - * Logger Manager Testcase - */ -class LoggerManagerTest extends \PunktDe\PtExtbase\Testing\Unit\AbstractBaseTestcase -{ - /** - * @var LoggerManager - */ - protected $proxy; - - /** - * @var string - */ - protected $proxyClass; - - - /** - * @return void - */ - public function setUp(): void - { - $this->proxyClass = $this->buildAccessibleProxy(LoggerManager::class); - $this->proxy = new $this->proxyClass(); - } - - - - /** - * @return array - */ - public function unifyComponentNameUnifiesComponentNameDataProvider() - { - return [ - 'deprecatedClassName' => [ - 'componentName' => 'Tx_Acme_Utility_ToonDrawer', - 'expected' => 'Tx.Acme.Utility.ToonDrawer' - ], - 'namespacedClassName' => [ - 'componentName' => 'Acme\\Utility\\ToonDrawer', - 'expected' => 'Acme.Utility.ToonDrawer' - ], - 'dotSeparatedComponentName' => [ - 'componentName' => 'acme.utility.toondrawer', - 'expected' => 'acme.utility.toondrawer' - ], - 'componentNameWithoutSeparator' => [ - 'componentName' => 'AcmeUtilityToonDrawer', - 'expected' => 'AcmeUtilityToonDrawer' - ], - ]; - } - - - - /** - * @test - * @dataProvider unifyComponentNameUnifiesComponentNameDataProvider - * - * @param string $componentName - * @param string $expected - */ - public function unifyComponentNameUnifiesComponentName($componentName, $expected) - { - $actual = $this->proxy->_call('unifyComponentName', $componentName); - $this->assertSame($expected, $actual); - } - - - - /** - * @return array - */ - public function evaluateIndexNameByComponentNameDataProvider() - { - return [ - 'noConfigurationAvailable' => [ - 'componentName' => 'Tx.Acme.Utility.ToonDrawer', - 'loggerConfigurationConfiguration' => [ - ], - 'expected' => 'PTEXTBASE' - ], - 'onlyWriterConfigurationAvailable' => [ - 'componentName' => 'Tx.Acme.Utility.ToonDrawer', - 'loggerConfigurationConfiguration' => [ - 'Tx' => [ - 'writerConfiguration' => [ - 'Duffy', 'Duck' - ] - ] - ], - 'expected' => 'PTEXTBASE.Tx' - ], - 'onlyProcessorConfigurationAvailable' => [ - 'componentName' => 'Tx.Acme.Utility.ToonDrawer', - 'loggerConfiguration' => [ - 'Tx' => [ - 'processorConfiguration' => [ - 'Duffy', 'Duck' - ] - ] - ], - 'expected' => 'PTEXTBASE.Tx' - ], - 'levelTwoConfigurationAvailable' => [ - 'componentName' => 'Tx.Acme.Utility.ToonDrawer', - 'loggerConfiguration' => [ - 'Tx' => [ - 'Acme' => [ - 'processorConfiguration' => [ - 'Duffy', 'Duck' - ] - ] - ] - ], - 'expected' => 'PTEXTBASE.Tx.Acme' - ], - 'maximumSpecificConfigurationAvailable' => [ - 'componentName' => 'Tx.Acme.Utility.ToonDrawer', - 'loggerConfiguration' => [ - 'Tx' => [ - 'Acme' => [ - 'Utility' => [ - 'ToonDrawer' => [ - 'processorConfiguration' => [ - 'Duffy', 'Duck' - ] - ] - ] - ] - ] - ], - 'expected' => 'PTEXTBASE.Tx.Acme.Utility.ToonDrawer' - ], - 'writerAndProcessorWithConfigurationOfUnequalSpecificityAvailable' => [ - 'componentName' => 'Tx.Acme.Utility.ToonDrawer', - 'loggerConfiguration' => [ - 'Tx' => [ - 'Acme' => [ - 'Utility' => [ - 'ToonDrawer' => [ - 'processorConfiguration' => [ - 'Duffy', 'Duck' - ] - ] - ] - ], - 'writerConfiguration' => [ - 'Bugs', 'Bunny' - ] - ] - ], - 'expected' => 'PTEXTBASE.Tx.Acme.Utility.ToonDrawer' - ] - ]; - } - - - - /** - * @test - * @dataProvider evaluateIndexNameByComponentNameDataProvider - * - * @param string $componentName - * @param array $loggerConfiguration - * @param string $expected - */ - public function evaluateIndexNameByComponentName($componentName, $loggerConfiguration, $expected) - { - $this->proxy->_set('loggerConfiguration', $loggerConfiguration); - $actual = $this->proxy->_call('evaluateIndexNameByComponentName', $componentName); - $this->assertSame($expected, $actual); - } - - - - /** - * @return array - */ - public function getLoggerCreatesValidIndexOfLoggersAndReturnsLoggerWithCorrectComponentNameDataProvider() - { - return [ - [ - 'loggerNames' => [ - 'Tx.Acme.Utility.ToonDrawer', - 'Tx.Acme.Utility', - 'Tx.Acme', - 'Tx.Roadrunner', - ], - 'loggerConfiguration' => [ - 'Tx' => [ - 'Acme' => [ - 'processorConfiguration' => [ - 'Duffy', 'Duck' - ] - ] - ] - ], - 'expectedLoggerIndexKeys' => [ - '', - 'PTEXTBASE.Tx.Acme', - 'PTEXTBASE.Tx', - ] - ], - ]; - } - - - - /** - * @test - * @dataProvider getLoggerCreatesValidIndexOfLoggersAndReturnsLoggerWithCorrectComponentNameDataProvider - * - * @param array $loggerNames - * @param array $loggerConfiguration - * @param array $expectedLoggerIndexKeys - */ - public function getLoggerCreatesValidIndexOfLoggersAndReturnsLoggerWithCorrectComponentName($loggerNames, $loggerConfiguration, $expectedLoggerIndexKeys) - { - $loggerManagerMock = $this->getMockBuilder($this->proxyClass) - ->setMethods(['setWritersForLogger','setProcessorsForLogger']) - ->getMock(); - - $loggerManagerMock->_set('loggerConfiguration', $loggerConfiguration); - - foreach ($loggerNames as $loggerName) { - $loggerManagerMock->getLogger($loggerName); - } - - $actualLoggerIndexKeys = $loggerManagerMock->getLoggerNames(); - $this->assertSame($expectedLoggerIndexKeys, $actualLoggerIndexKeys, 'Expected and actual logger index keys are not equal'); - } -} diff --git a/Tests/Unit/Logger/LoggerTest.php b/Tests/Unit/Logger/LoggerTest.php index e401694f..2300d096 100644 --- a/Tests/Unit/Logger/LoggerTest.php +++ b/Tests/Unit/Logger/LoggerTest.php @@ -24,9 +24,9 @@ ***************************************************************/ use PunktDe\PtExtbase\Logger\LoggerConfiguration; -use PunktDe\PtExtbase\Logger\LoggerManager; use PunktDe\PtExtbase\Logger\Processor\ReplaceComponentProcessor; use TYPO3\CMS\Core\Log\LogLevel; +use TYPO3\CMS\Core\Log\LogManager; /** * Logger Testcase @@ -109,8 +109,8 @@ public function enrichLogDataByComponentCallsLoggerSpecificMethod() ->method('enrichLoggerSpecificDataByComponent'); /** @var $loggerMock \PunktDe\PtExtbase\Logger\Logger */ - $loggerManager = new LoggerManager(); - $loggerMock->injectLoggerManager($loggerManager); + $loggerManager = new LogManager(); + $loggerMock->injectLogManager($loggerManager); $data = []; $loggerMock->enrichLogDataByComponent($data, 'Extbase'); @@ -169,8 +169,8 @@ public function enrichLogDataByComponentEnrichesDataArray($userId, $component, $ $GLOBALS['TSFE']->fe_user->user['uid'] = $userId; - $loggerManager = new LoggerManager(); - $this->proxy->injectLoggerManager($loggerManager); + $loggerManager = new LogManager(); + $this->proxy->injectLogManager($loggerManager); $this->proxy->enrichLogDataByComponent($actual, $component); diff --git a/ext_conf_template.txt b/ext_conf_template.txt index 1c1d57b7..ae518d89 100755 --- a/ext_conf_template.txt +++ b/ext_conf_template.txt @@ -2,7 +2,3 @@ logFilePath = # cat=logger; type=options[Emergency=0,Alert=1,Critical=2,Error=3,Warning=4,Notice=5,Info=6,Debug=7]; label="Log level threshold: The minimum log level at which a message is logged. Default is Info. See \TYPO3\CMS\Core\Log\LogLevel for more information." logLevelThreshold = error -# cat=logger; type=options[Emergency=0,Alert=1,Critical=2,Error=3,Warning=4,Notice=5,Info=6,Debug=7]; label="E-Mail log level threshold: The minimum log level at which an E-Mail is sent to specified receivers. Default is Critical. See \TYPO3\CMS\Core\Log\LogLevel for more information." -emailLogLevelThreshold = info -# cat=logger; type=string; label="E-Mail receivers: Comma separated list of e-mail receivers." -emailReceivers =