[Pkg-owncloud-commits] [owncloud] 08/457: Conditional logging

David Prévot taffit at moszumanska.debian.org
Sun Jun 28 20:05:16 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch stable8
in repository owncloud.

commit e79c255cabecb768061bb58ea508a38011ef6284
Author: Morris Jobke <hey at morrisjobke.de>
Date:   Thu Apr 30 12:43:58 2015 +0200

    Conditional logging
    
     * Log condition for log level increase based on conditions. Once one of these
       conditions is met, the required log level is set to debug. This allows to
       debug specific requests, users or apps
    
     * Supported conditions (setting `log_condition` in `config.php`):
        - `shared_secret`: if a request parameter with the name `log_secret` is set to
                    this value the condition is met
        - `users`:  if the current request is done by one of the specified users,
                    this condition is met
        - `apps`:   if the log message is invoked by one of the specified apps,
                    this condition is met
     * fix unit test and add app log condition test
---
 config/config.sample.php | 21 +++++++++++++++
 lib/private/log.php      | 69 +++++++++++++++++++++++++++++++++++++++++++++---
 tests/lib/logger.php     | 30 ++++++++++++++++++---
 3 files changed, 113 insertions(+), 7 deletions(-)

diff --git a/config/config.sample.php b/config/config.sample.php
index 45aaf6a..9a40f82 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -487,6 +487,27 @@ $CONFIG = array(
 'loglevel' => 2,
 
 /**
+ * Log condition for log level increase based on conditions. Once one of these
+ * conditions is met, the required log level is set to debug. This allows to
+ * debug specific requests, users or apps
+ *
+ * Supported conditions:
+ *  - ``shared_secret``: if a request parameter with the name `log_secret` is set to
+ *                this value the condition is met
+ *  - ``users``:  if the current request is done by one of the specified users,
+ *                this condition is met
+ *  - ``apps``:   if the log message is invoked by one of the specified apps,
+ *                this condition is met
+ *
+ * Defaults to an empty array.
+ */
+'log.condition' => [
+	'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
+	'users' => ['sample-user'],
+	'apps' => ['files'],
+],
+
+/**
  * This uses PHP.date formatting; see http://php.net/manual/en/function.date.php
  */
 'logdateformat' => 'F d, Y H:i:s',
diff --git a/lib/private/log.php b/lib/private/log.php
index 2f15bec..840713b 100644
--- a/lib/private/log.php
+++ b/lib/private/log.php
@@ -28,6 +28,7 @@
 namespace OC;
 
 use \OCP\ILogger;
+use OCP\Security\StringUtils;
 
 /**
  * logging utilities
@@ -41,15 +42,29 @@ use \OCP\ILogger;
 
 class Log implements ILogger {
 
+	/** @var string */
 	private $logger;
+	/** @var SystemConfig */
+	private $config;
+
+	/** @var boolean|null cache the result of the log condition check for the request */
+	private $logConditionSatisfied = null;
 
 	/**
 	 * @param string $logger The logger that should be used
+	 * @param SystemConfig $config the system config object
 	 */
-	public function __construct($logger=null) {
+	public function __construct($logger=null, SystemConfig $config=null) {
+		// FIXME: Add this for backwards compatibility, should be fixed at some point probably
+		if($config === null) {
+			$config = \OC::$server->getSystemConfig();
+		}
+
+		$this->config = $config;
+
 		// FIXME: Add this for backwards compatibility, should be fixed at some point probably
 		if($logger === null) {
-			$this->logger = 'OC_Log_'.ucfirst(\OC_Config::getValue('log_type', 'owncloud'));
+			$this->logger = 'OC_Log_'.ucfirst($this->config->getValue('log_type', 'owncloud'));
 			call_user_func(array($this->logger, 'init'));
 		} else {
 			$this->logger = $logger;
@@ -158,8 +173,22 @@ class Log implements ILogger {
 	 * @param array $context
 	 */
 	public function log($level, $message, array $context = array()) {
+		$minLevel = min($this->config->getValue('loglevel', \OC_Log::WARN), \OC_Log::ERROR);
+		$logCondition = $this->config->getValue('log.condition', []);
+
 		if (isset($context['app'])) {
 			$app = $context['app'];
+
+			/**
+			 * check log condition based on the context of each log message
+			 * once this is met -> change the required log level to debug
+			 */
+			if(!empty($logCondition)
+				&& isset($logCondition['apps'])
+				&& in_array($app, $logCondition['apps'], true)) {
+				$minLevel = \OC_Log::DEBUG;
+			}
+
 		} else {
 			$app = 'no app in context';
 		}
@@ -172,9 +201,41 @@ class Log implements ILogger {
 		// interpolate replacement values into the message and return
 		$message = strtr($message, $replace);
 
-		$config = \OC::$server->getSystemConfig();
+		/**
+		 * check for a special log condition - this enables an increased log on
+		 * a per request/user base
+		 */
+		if($this->logConditionSatisfied === null) {
+			// default to false to just process this once per request
+			$this->logConditionSatisfied = false;
+			if(!empty($logCondition)) {
+
+				// check for secret token in the request
+				if(isset($logCondition['shared_secret'])) {
+					$request = \OC::$server->getRequest();
+
+					// if token is found in the request change set the log condition to satisfied
+					if($request && StringUtils::equals($request->getParam('log_secret'), $logCondition['shared_secret'])) {
+						$this->logConditionSatisfied = true;
+					}
+				}
+
+				// check for user
+				if(isset($logCondition['users'])) {
+					$user = \OC::$server->getUserSession()->getUser();
+
+					// if the user matches set the log condition to satisfied
+					if($user !== null && in_array($user->getUID(), $logCondition['users'], true)) {
+						$this->logConditionSatisfied = true;
+					}
+				}
+			}
+		}
 
-		$minLevel = min($config->getValue('loglevel', \OC_Log::WARN), \OC_Log::ERROR);
+		// if log condition is satisfied change the required log level to DEBUG
+		if($this->logConditionSatisfied) {
+			$minLevel = \OC_Log::DEBUG;
+		}
 
 		if ($level >= $minLevel) {
 			$logger = $this->logger;
diff --git a/tests/lib/logger.php b/tests/lib/logger.php
index 700a847..9a9f5be 100644
--- a/tests/lib/logger.php
+++ b/tests/lib/logger.php
@@ -21,14 +21,38 @@ class Logger extends TestCase {
 		parent::setUp();
 
 		self::$logs = array();
-		$this->logger = new Log('Test\Logger');
+		$this->config = $this->getMockBuilder(
+			'\OC\SystemConfig')
+			->disableOriginalConstructor()
+			->getMock();
+		$this->logger = new Log('Test\Logger', $this->config);
 	}
 
 	public function testInterpolation() {
 		$logger = $this->logger;
-		$logger->info('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
+		$logger->warning('{Message {nothing} {user} {foo.bar} a}', array('user' => 'Bob', 'foo.bar' => 'Bar'));
 
-		$expected = array('1 {Message {nothing} Bob Bar a}');
+		$expected = array('2 {Message {nothing} Bob Bar a}');
+		$this->assertEquals($expected, $this->getLogs());
+	}
+
+	public function testAppCondition() {
+		$this->config->expects($this->any())
+			->method('getValue')
+			->will(($this->returnValueMap([
+				['loglevel', \OC_Log::WARN, \OC_Log::WARN],
+				['log.condition', [], ['apps' => ['files']]]
+			])));
+		$logger = $this->logger;
+
+		$logger->info('Don\'t display info messages');
+		$logger->info('Show info messages of files app', ['app' => 'files']);
+		$logger->warning('Show warning messages of other apps');
+
+		$expected = [
+			'1 Show info messages of files app',
+			'2 Show warning messages of other apps',
+		];
 		$this->assertEquals($expected, $this->getLogs());
 	}
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list