Commit a50b8dbc authored by Sujith H's avatar Sujith H

Separate audit logs from server logs.

This change will help users to separate logs
for each apps based on conditional logging.
Changed usage of log.condition to
log.conditions.
Signed-off-by: default avatarSujith H <sharidasan@owncloud.com>
parent d17a83ea
......@@ -602,13 +602,25 @@ $CONFIG = array(
* this condition is met
* - ``apps``: if the log message is invoked by one of the specified apps,
* this condition is met
* - ``logfile``: the log message invoked by the specified apps get redirected to
* this logfile, this condition is met
* Note: Not applicapable when using syslog.
*
* Defaults to an empty array.
*/
'log.condition' => [
'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
'users' => ['sample-user'],
'apps' => ['files'],
'log.conditions' => [
[
'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
'users' => ['user1'],
'apps' => ['files_texteditor'],
'logfile' => '/tmp/test.log'
],
[
'shared_secret' => '57b58edb6637fe3059b3595cf9c41b9',
'users' => ['user1'],
'apps' => ['gallery'],
'logfile' => '/tmp/gallery.log'
],
],
/**
......
......@@ -230,7 +230,11 @@ class Log implements ILogger {
*/
public function log($level, $message, array $context = []) {
$minLevel = min($this->config->getValue('loglevel', Util::WARN), Util::FATAL);
$logCondition = $this->config->getValue('log.condition', []);
$logConditions = $this->config->getValue('log.conditions', []);
if (empty($logConditions)) {
$logConditions[] = $this->config->getValue('log.condition', []);
}
$logConditionFile = null;
array_walk($context, [$this->normalizer, 'format']);
......@@ -241,10 +245,17 @@ class Log implements ILogger {
* 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 = Util::DEBUG;
if(!empty($logConditions)) {
foreach ($logConditions as $logCondition) {
if(!empty($logCondition['apps'])
&& in_array($app, $logCondition['apps'], true)) {
$minLevel = Util::DEBUG;
if (!empty($logCondition['logfile'])) {
$logConditionFile = $logCondition['logfile'];
break;
}
}
}
}
} else {
......@@ -266,25 +277,29 @@ class Log implements ILogger {
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 && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret'))) {
$this->logConditionSatisfied = true;
if(!empty($logConditions)) {
foreach ($logConditions as $logCondition) {
// check for secret token in the request
if (!empty($logCondition['shared_secret'])) {
$request = \OC::$server->getRequest();
// if token is found in the request change set the log condition to satisfied
if ($request && hash_equals($logCondition['shared_secret'], $request->getParam('log_secret'))) {
$this->logConditionSatisfied = true;
break;
}
}
}
// check for user
if(isset($logCondition['users'])) {
$user = \OC::$server->getUserSession()->getUser();
// check for user
if (!empty($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;
// if the user matches set the log condition to satisfied
if ($user !== null && in_array($user->getUID(), $logCondition['users'], true)) {
$this->logConditionSatisfied = true;
break;
}
}
}
}
......@@ -297,7 +312,7 @@ class Log implements ILogger {
if ($level >= $minLevel) {
$logger = $this->logger;
call_user_func([$logger, 'write'], $app, $message, $level);
call_user_func([$logger, 'write'], $app, $message, $level, $logConditionFile);
}
}
......
......@@ -67,8 +67,9 @@ class Owncloud {
* @param string $app
* @param string $message
* @param int $level
* @param string conditionalLogFile
*/
public static function write($app, $message, $level) {
public static function write($app, $message, $level, $conditionalLogFile = null) {
$config = \OC::$server->getSystemConfig();
// default to ISO8601
......@@ -110,8 +111,13 @@ class Owncloud {
'user'
);
$entry = json_encode($entry);
$handle = @fopen(self::$logFile, 'a');
@chmod(self::$logFile, 0640);
if (!is_null($conditionalLogFile)) {
$handle = @fopen($conditionalLogFile, 'a');
@chmod($conditionalLogFile, 0640);
} else {
$handle = @fopen(self::$logFile, 'a');
@chmod(self::$logFile, 0640);
}
if ($handle) {
fwrite($handle, $entry."\n");
fclose($handle);
......
......@@ -59,6 +59,24 @@ class LoggerTest extends TestCase {
$this->assertEquals($expected, $this->getLogs());
}
public function testAppLogCondition() {
$this->config->expects($this->any())
->method('getValue')
->will(($this->returnValueMap([
['loglevel', Util::WARN, Util::WARN],
['log.conditions', [], [['apps' => ['files'], 'logfile' => '/tmp/test.log']]]
])));
$logger = $this->logger;
$logger->info('Don\'t display info messages');
$logger->info('Show info messages of files app', ['app' => 'files']);
$expected = [
'1 Show info messages of files app',
];
$this->assertEquals($expected, $this->getLogs());
}
private function getLogs() {
return self::$logs;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment