From 46aaeb45612e20b6f460396533faf7f26ed1d6f7 Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 14 Jan 2020 10:43:50 +0100 Subject: log Flow activity Signed-off-by: Arthur Schiwon --- apps/workflowengine/lib/Service/Logger.php | 170 +++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 apps/workflowengine/lib/Service/Logger.php (limited to 'apps/workflowengine/lib/Service/Logger.php') diff --git a/apps/workflowengine/lib/Service/Logger.php b/apps/workflowengine/lib/Service/Logger.php new file mode 100644 index 00000000000..0bf09ed8a72 --- /dev/null +++ b/apps/workflowengine/lib/Service/Logger.php @@ -0,0 +1,170 @@ + + * + * @author Arthur Schiwon + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +namespace OCA\WorkflowEngine\Service; + +use OCA\WorkflowEngine\AppInfo\Application; +use OCA\WorkflowEngine\Helper\LogContext; +use OCP\IConfig; +use OCP\ILogger; +use OCP\Log\IDataLogger; +use OCP\Log\ILogFactory; + +class Logger { + /** @var ILogger */ + protected $generalLogger; + /** @var ILogger */ + protected $flowLogger; + /** @var IConfig */ + private $config; + /** @var ILogFactory */ + private $logFactory; + + public function __construct(ILogger $generalLogger, IConfig $config, ILogFactory $logFactory) { + $this->generalLogger = $generalLogger; + $this->config = $config; + $this->logFactory = $logFactory; + + $this->initLogger(); + } + + protected function initLogger() { + $default = $this->config->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/flow.log'; + $logFile = trim((string)$this->config->getAppValue(Application::APP_ID, 'logfile', $default)); + if($logFile !== '') { + $this->flowLogger = $this->logFactory->getCustomLogger($logFile); + } + } + + public function logFlowRequests(LogContext $logContext) { + $message = 'Flow activation: rules were requested for operation {op}'; + $context = ['op' => $logContext->getDetails()['operation']['name']]; + + $logContext->setDescription('Flow activation: rules were requested'); + + $this->log($message, $context, $logContext); + } + + public function logScopeExpansion(LogContext $logContext) { + $message = 'Flow rule of a different user is legit for operation {op}'; + $context = ['op' => $logContext->getDetails()['operation']['name']]; + + $logContext->setDescription('Flow rule of a different user is legit'); + + $this->log($message, $context, $logContext); + } + + public function logPassedCheck(LogContext $logContext) { + $message = 'Flow rule qualified to run {op}, config: {config}'; + $context = [ + 'op' => $logContext->getDetails()['operation']['name'], + 'config' => $logContext->getDetails()['configuration'], + ]; + + $logContext->setDescription('Flow rule qualified to run'); + + $this->log($message, $context, $logContext); + } + + public function logRunSingle(LogContext $logContext) { + $message = 'Last qualified flow configuration is going to run {op}'; + $context = [ + 'op' => $logContext->getDetails()['operation']['name'], + ]; + + $logContext->setDescription('Last qualified flow configuration is going to run'); + + $this->log($message, $context, $logContext); + } + + public function logRunAll(LogContext $logContext) { + $message = 'All qualified flow configurations are going to run {op}'; + $context = [ + 'op' => $logContext->getDetails()['operation']['name'], + ]; + + $logContext->setDescription('All qualified flow configurations are going to run'); + + $this->log($message, $context, $logContext); + } + + public function logRunNone(LogContext $logContext) { + $message = 'No flow configurations is going to run {op}'; + $context = [ + 'op' => $logContext->getDetails()['operation']['name'], + ]; + + $logContext->setDescription('No flow configurations is going to run'); + + $this->log($message, $context, $logContext); + } + + public function logEventInit(LogContext $logContext) { + $message = 'Flow activated by event {ev}'; + + $context = [ + 'ev' => $logContext->getDetails()['eventName'], + ]; + + $logContext->setDescription('Flow activated by event'); + + $this->log($message, $context, $logContext); + } + + public function logEventDone(LogContext $logContext) { + $message = 'Flow handling done for event {ev}'; + + $context = [ + 'ev' => $logContext->getDetails()['eventName'], + ]; + + $logContext->setDescription('Flow handling for event done'); + + $this->log($message, $context, $logContext); + } + + protected function log( + string $message, + array $context, + LogContext $logContext + ): void + { + if(!isset($context['app'])) { + $context['app'] = Application::APP_ID; + } + if(!isset($context['level'])) { + $context['level'] = ILogger::INFO; + } + $this->generalLogger->log($context['level'], $message, $context); + + if(!$this->flowLogger instanceof IDataLogger) { + return; + } + + $this->flowLogger->logData( + $logContext->getDetails(), + ['app' => Application::APP_ID, 'level' => $context['level']] + ); + } +} -- cgit v1.2.3 From e00844488709552febdc07c19bed4c7ceb52a98d Mon Sep 17 00:00:00 2001 From: Arthur Schiwon Date: Tue, 28 Jan 2020 13:00:13 +0100 Subject: always require a message paramter for data logging also ensure it plays well with current log reader Signed-off-by: Arthur Schiwon --- apps/workflowengine/lib/Helper/LogContext.php | 2 +- apps/workflowengine/lib/Service/Logger.php | 4 +++- lib/private/Log.php | 3 ++- lib/private/Log/LogDetails.php | 10 ++++++++++ lib/public/Log/IDataLogger.php | 6 +++--- 5 files changed, 19 insertions(+), 6 deletions(-) (limited to 'apps/workflowengine/lib/Service/Logger.php') diff --git a/apps/workflowengine/lib/Helper/LogContext.php b/apps/workflowengine/lib/Helper/LogContext.php index 786aa7cf85a..548e8722073 100644 --- a/apps/workflowengine/lib/Helper/LogContext.php +++ b/apps/workflowengine/lib/Helper/LogContext.php @@ -33,7 +33,7 @@ class LogContext { protected $details; public function setDescription(string $description): LogContext { - $this->details['description'] = $description; + $this->details['message'] = $description; return $this; } diff --git a/apps/workflowengine/lib/Service/Logger.php b/apps/workflowengine/lib/Service/Logger.php index 0bf09ed8a72..8b90e6fa159 100644 --- a/apps/workflowengine/lib/Service/Logger.php +++ b/apps/workflowengine/lib/Service/Logger.php @@ -162,8 +162,10 @@ class Logger { return; } + $details = $logContext->getDetails(); $this->flowLogger->logData( - $logContext->getDetails(), + $details['message'], + $details, ['app' => Application::APP_ID, 'level' => $context['level']] ); } diff --git a/lib/private/Log.php b/lib/private/Log.php index 8d51a673a46..d288e724179 100644 --- a/lib/private/Log.php +++ b/lib/private/Log.php @@ -340,7 +340,7 @@ class Log implements ILogger, IDataLogger { } } - public function logData(array $data, array $context = []): void { + public function logData(string $message, array $data, array $context = []): void { $app = $context['app'] ?? 'no app in context'; $level = $context['level'] ?? ILogger::ERROR; @@ -350,6 +350,7 @@ class Log implements ILogger, IDataLogger { try { if ($level >= $minLevel) { + $data['message'] = $message; if (!$this->logger instanceof IFileBased) { $data = json_encode($data, JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_UNESCAPED_SLASHES); } diff --git a/lib/private/Log/LogDetails.php b/lib/private/Log/LogDetails.php index 2eea17ad73d..b1dc6e4311b 100644 --- a/lib/private/Log/LogDetails.php +++ b/lib/private/Log/LogDetails.php @@ -80,6 +80,16 @@ abstract class LogDetails { 'userAgent', 'version' ); + + if(is_array($message) && !array_key_exists('Exception', $message)) { + // Exception messages should stay as they are, + // anything else modern is split to 'message' (string) and + // data (array) fields + $shortMessage = $message['message'] ?? '(no message provided)'; + $entry['data'] = $message; + $entry['message'] = $shortMessage; + } + return $entry; } diff --git a/lib/public/Log/IDataLogger.php b/lib/public/Log/IDataLogger.php index 895ba43f5ca..b5d3aa3075b 100644 --- a/lib/public/Log/IDataLogger.php +++ b/lib/public/Log/IDataLogger.php @@ -28,15 +28,15 @@ namespace OCP\Log; * Interface IDataLogger * * @package OCP\Log - * @since 18.0.0 + * @since 18.0.1 */ interface IDataLogger { /** * allows to log custom data, similar to how logException works * - * @since 18.0.0 + * @since 18.0.1 */ - public function logData(array $data, array $context = []): void; + public function logData(string $message, array $data, array $context = []): void; } -- cgit v1.2.3