diff --git a/core/Command/Log/Manage.php b/core/Command/Log/Manage.php index 267e84c140..5a1dd3d048 100644 --- a/core/Command/Log/Manage.php +++ b/core/Command/Log/Manage.php @@ -6,6 +6,7 @@ * @author Robin McCorkell * @author Roeland Jago Douma * @author Thomas Pulzer + * @author Johannes Ernst * * @license AGPL-3.0 * @@ -55,7 +56,7 @@ class Manage extends Command implements CompletionAwareInterface { 'backend', null, InputOption::VALUE_REQUIRED, - 'set the logging backend [file, syslog, errorlog]' + 'set the logging backend [file, syslog, errorlog, systemd]' ) ->addOption( 'level', @@ -181,7 +182,7 @@ class Manage extends Command implements CompletionAwareInterface { */ public function completeOptionValues($optionName, CompletionContext $context) { if ($optionName === 'backend') { - return ['file', 'syslog', 'errorlog']; + return ['file', 'syslog', 'errorlog', 'systemd']; } else if ($optionName === 'level') { return ['debug', 'info', 'warning', 'error']; } else if ($optionName === 'timezone') { diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index a3d4564e3f..0853180c1f 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -794,6 +794,7 @@ return array( 'OC\\Log\\LogFactory' => $baseDir . '/lib/private/Log/LogFactory.php', 'OC\\Log\\Rotate' => $baseDir . '/lib/private/Log/Rotate.php', 'OC\\Log\\Syslog' => $baseDir . '/lib/private/Log/Syslog.php', + 'OC\\Log\\Systemdlog' => $baseDir . '/lib/private/Log/Systemdlog.php', 'OC\\Mail\\Attachment' => $baseDir . '/lib/private/Mail/Attachment.php', 'OC\\Mail\\EMailTemplate' => $baseDir . '/lib/private/Mail/EMailTemplate.php', 'OC\\Mail\\Mailer' => $baseDir . '/lib/private/Mail/Mailer.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index e0b158f90f..3d8856be91 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -824,6 +824,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Log\\LogFactory' => __DIR__ . '/../../..' . '/lib/private/Log/LogFactory.php', 'OC\\Log\\Rotate' => __DIR__ . '/../../..' . '/lib/private/Log/Rotate.php', 'OC\\Log\\Syslog' => __DIR__ . '/../../..' . '/lib/private/Log/Syslog.php', + 'OC\\Log\\Systemdlog' => __DIR__ . '/../../..' . '/lib/private/Log/Systemdlog.php', 'OC\\Mail\\Attachment' => __DIR__ . '/../../..' . '/lib/private/Mail/Attachment.php', 'OC\\Mail\\EMailTemplate' => __DIR__ . '/../../..' . '/lib/private/Mail/EMailTemplate.php', 'OC\\Mail\\Mailer' => __DIR__ . '/../../..' . '/lib/private/Mail/Mailer.php', diff --git a/lib/private/Log/LogFactory.php b/lib/private/Log/LogFactory.php index 9b9d12abfa..5bb803cbaf 100644 --- a/lib/private/Log/LogFactory.php +++ b/lib/private/Log/LogFactory.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2018 Arthur Schiwon * * @author Arthur Schiwon + * @author Johannes Ernst * * @license GNU AGPL version 3 or any later version * @@ -50,6 +51,8 @@ class LogFactory implements ILogFactory { return new Errorlog(); case 'syslog': return $this->c->resolve(Syslog::class); + case 'systemd': + return $this->c->resolve(Systemdlog::class); case 'file': return $this->buildLogFile(); diff --git a/lib/private/Log/Systemdlog.php b/lib/private/Log/Systemdlog.php new file mode 100644 index 0000000000..63b228bfa0 --- /dev/null +++ b/lib/private/Log/Systemdlog.php @@ -0,0 +1,68 @@ + + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program 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 Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OC\Log; + +use OCP\ILogger; +use OCP\IConfig; +use OCP\Log\IWriter; + +// The following fields are understood by systemd/journald, see +// man systemd.journal-fields. All are optional: +// MESSAGE= +// The human-readable message string for this entry. +// MESSAGE_ID= +// A 128-bit message identifier ID +// PRIORITY= +// A priority value between 0 ("emerg") and 7 ("debug") +// CODE_FILE=, CODE_LINE=, CODE_FUNC= +// The code location generating this message, if known +// ERRNO= +// The low-level Unix error number causing this entry, if any. +// SYSLOG_FACILITY=, SYSLOG_IDENTIFIER=, SYSLOG_PID= +// Syslog compatibility fields + +class Systemdlog implements IWriter { + protected $levels = [ + ILogger::DEBUG => 7, + ILogger::INFO => 6, + ILogger::WARN => 4, + ILogger::ERROR => 3, + ILogger::FATAL => 2, + ]; + + public function __construct(IConfig $config) { + } + + /** + * write a message in the log + * @param string $app + * @param string $message + * @param int $level + */ + public function write(string $app, $message, int $level) { + $journal_level = $this->levels[$level]; + sd_journal_send('PRIORITY='.$journal_level, + 'SYSLOG_IDENTIFIER=nextcloud', + 'MESSAGE={'.$app.'} '.$message); + } +} diff --git a/lib/public/Log/ILogFactory.php b/lib/public/Log/ILogFactory.php index d8e1ab4ee7..6f843d1268 100644 --- a/lib/public/Log/ILogFactory.php +++ b/lib/public/Log/ILogFactory.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2018 Arthur Schiwon * * @author Arthur Schiwon + * @author Johannes Ernst * * @license GNU AGPL version 3 or any later version * @@ -33,7 +34,7 @@ use OCP\ILogger; */ interface ILogFactory { /** - * @param string $type - one of: file, errorlog, syslog + * @param string $type - one of: file, errorlog, syslog, systemd * @return IWriter * @since 14.0.0 */ diff --git a/tests/lib/Log/LogFactoryTest.php b/tests/lib/Log/LogFactoryTest.php index 08139f54df..b9b4c2c218 100644 --- a/tests/lib/Log/LogFactoryTest.php +++ b/tests/lib/Log/LogFactoryTest.php @@ -3,6 +3,7 @@ * @copyright Copyright (c) 2018 Arthur Schiwon * * @author Arthur Schiwon + * @author Johannes Ernst * * @license GNU AGPL version 3 or any later version * @@ -26,6 +27,7 @@ use OC\Log\Errorlog; use OC\Log\File; use OC\Log\LogFactory; use OC\Log\Syslog; +use OC\Log\Systemdlog; use OC\SystemConfig; use OCP\IConfig; use OCP\IServerContainer; @@ -141,4 +143,17 @@ class LogFactoryTest extends TestCase { $log = $this->factory->get('syslog'); $this->assertInstanceOf(Syslog::class, $log); } + + /** + * @throws \OCP\AppFramework\QueryException + */ + public function testSystemdLog() { + $this->c->expects($this->once()) + ->method('resolve') + ->with(Systemdlog::class) + ->willReturn($this->createMock(Systemdlog::class)); + + $log = $this->factory->get('systemd'); + $this->assertInstanceOf(Systemdlog::class, $log); + } }