mirror of
https://github.com/nextcloud/server.git
synced 2026-04-22 14:50:17 -04:00
Allow to log DB, redis and LDAP requests into files
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
parent
44ecd0d1d5
commit
168c673755
8 changed files with 159 additions and 10 deletions
|
|
@ -75,8 +75,13 @@ class Application extends App implements IBootstrap {
|
|||
);
|
||||
});
|
||||
|
||||
$container->registerService(ILDAPWrapper::class, function () {
|
||||
return new LDAP();
|
||||
$container->registerService(ILDAPWrapper::class, function (IAppContainer $appContainer) {
|
||||
/** @var IServerContainer $server */
|
||||
$server = $appContainer->get(IServerContainer::class);
|
||||
|
||||
return new LDAP(
|
||||
$server->getConfig()->getSystemValueString('ldap_log_file')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -317,7 +317,7 @@ class Sync extends TimedJob {
|
|||
if (isset($argument['ldapWrapper'])) {
|
||||
$this->ldap = $argument['ldapWrapper'];
|
||||
} else {
|
||||
$this->ldap = new LDAP();
|
||||
$this->ldap = new LDAP($this->config->getSystemValueString('ldap_log_file'));
|
||||
}
|
||||
|
||||
if (isset($argument['avatarManager'])) {
|
||||
|
|
|
|||
|
|
@ -38,14 +38,16 @@ use OCA\User_LDAP\PagedResults\IAdapter;
|
|||
use OCA\User_LDAP\PagedResults\Php73;
|
||||
|
||||
class LDAP implements ILDAPWrapper {
|
||||
protected $logFile = '';
|
||||
protected $curFunc = '';
|
||||
protected $curArgs = [];
|
||||
|
||||
/** @var IAdapter */
|
||||
protected $pagedResultsAdapter;
|
||||
|
||||
public function __construct() {
|
||||
public function __construct(string $logFile = '') {
|
||||
$this->pagedResultsAdapter = new Php73();
|
||||
$this->logFile = $logFile;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -349,6 +351,18 @@ class LDAP implements ILDAPWrapper {
|
|||
private function preFunctionCall($functionName, $args) {
|
||||
$this->curFunc = $functionName;
|
||||
$this->curArgs = $args;
|
||||
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
$args = array_reduce($this->curArgs, static function (array $carry, $item): array {
|
||||
$carry[] = !is_resource($item) ? $item : '(resource)';
|
||||
return $carry;
|
||||
}, []);
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->curFunc . '::' . json_encode($args) . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1982,4 +1982,31 @@ $CONFIG = [
|
|||
* Defaults to ``true``
|
||||
*/
|
||||
'files_no_background_scan' => false,
|
||||
|
||||
/**
|
||||
* Log all queries into a file
|
||||
*
|
||||
* Warning: This heavily decreases the performance of the server and is only
|
||||
* meant to debug/profile the query interaction manually.
|
||||
* Also, it might log sensitive data into a plain text file.
|
||||
*/
|
||||
'query_log_file' => '',
|
||||
|
||||
/**
|
||||
* Log all redis requests into a file
|
||||
*
|
||||
* Warning: This heavily decreases the performance of the server and is only
|
||||
* meant to debug/profile the redis interaction manually.
|
||||
* Also, it might log sensitive data into a plain text file.
|
||||
*/
|
||||
'redis_log_file' => '',
|
||||
|
||||
/**
|
||||
* Log all LDAP requests into a file
|
||||
*
|
||||
* Warning: This heavily decreases the performance of the server and is only
|
||||
* meant to debug/profile the LDAP interaction manually.
|
||||
* Also, it might log sensitive data into a plain text file.
|
||||
*/
|
||||
'ldap_log_file' => '',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
$sql = $this->replaceTablePrefix($sql);
|
||||
$sql = $this->adapter->fixupStatement($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
return parent::executeQuery($sql, $params, $types, $qcp);
|
||||
}
|
||||
|
||||
|
|
@ -243,6 +244,7 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
$sql = $this->replaceTablePrefix($sql);
|
||||
$sql = $this->adapter->fixupStatement($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
return parent::executeUpdate($sql, $params, $types);
|
||||
}
|
||||
|
||||
|
|
@ -264,9 +266,21 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
$sql = $this->replaceTablePrefix($sql);
|
||||
$sql = $this->adapter->fixupStatement($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
return parent::executeStatement($sql, $params, $types);
|
||||
}
|
||||
|
||||
protected function logQueryToFile(string $sql): void {
|
||||
$logFile = $this->systemConfig->getValue('query_log_file', '');
|
||||
if ($logFile !== '' && is_writable($logFile)) {
|
||||
file_put_contents(
|
||||
$this->systemConfig->getValue('query_log_file', ''),
|
||||
$sql . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ID of the last inserted row, or the last value from a sequence object,
|
||||
* depending on the underlying driver.
|
||||
|
|
|
|||
|
|
@ -64,16 +64,21 @@ class Factory implements ICacheFactory {
|
|||
*/
|
||||
private $lockingCacheClass;
|
||||
|
||||
/** @var string */
|
||||
private $logFile;
|
||||
|
||||
/**
|
||||
* @param string $globalPrefix
|
||||
* @param ILogger $logger
|
||||
* @param string|null $localCacheClass
|
||||
* @param string|null $distributedCacheClass
|
||||
* @param string|null $lockingCacheClass
|
||||
* @param string $logFile
|
||||
*/
|
||||
public function __construct(string $globalPrefix, ILogger $logger,
|
||||
$localCacheClass = null, $distributedCacheClass = null, $lockingCacheClass = null) {
|
||||
$localCacheClass = null, $distributedCacheClass = null, $lockingCacheClass = null, string $logFile = '') {
|
||||
$this->logger = $logger;
|
||||
$this->logFile = $logFile;
|
||||
$this->globalPrefix = $globalPrefix;
|
||||
|
||||
if (!$localCacheClass) {
|
||||
|
|
@ -112,7 +117,7 @@ class Factory implements ICacheFactory {
|
|||
* @return IMemcache
|
||||
*/
|
||||
public function createLocking(string $prefix = ''): IMemcache {
|
||||
return new $this->lockingCacheClass($this->globalPrefix . '/' . $prefix);
|
||||
return new $this->lockingCacheClass($this->globalPrefix . '/' . $prefix, $this->logFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -122,7 +127,7 @@ class Factory implements ICacheFactory {
|
|||
* @return ICache
|
||||
*/
|
||||
public function createDistributed(string $prefix = ''): ICache {
|
||||
return new $this->distributedCacheClass($this->globalPrefix . '/' . $prefix);
|
||||
return new $this->distributedCacheClass($this->globalPrefix . '/' . $prefix, $this->logFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,7 +137,7 @@ class Factory implements ICacheFactory {
|
|||
* @return ICache
|
||||
*/
|
||||
public function createLocal(string $prefix = ''): ICache {
|
||||
return new $this->localCacheClass($this->globalPrefix . '/' . $prefix);
|
||||
return new $this->localCacheClass($this->globalPrefix . '/' . $prefix, $this->logFile);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -37,8 +37,11 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
*/
|
||||
private static $cache = null;
|
||||
|
||||
public function __construct($prefix = '') {
|
||||
private $logFile;
|
||||
|
||||
public function __construct($prefix = '', string $logFile = '') {
|
||||
parent::__construct($prefix);
|
||||
$this->logFile = $logFile;
|
||||
if (is_null(self::$cache)) {
|
||||
self::$cache = \OC::$server->getGetRedisFactory()->getInstance();
|
||||
}
|
||||
|
|
@ -52,6 +55,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
}
|
||||
|
||||
public function get($key) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::get::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
$result = self::$cache->get($this->getNameSpace() . $key);
|
||||
if ($result === false && !self::$cache->exists($this->getNameSpace() . $key)) {
|
||||
return null;
|
||||
|
|
@ -61,6 +72,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
}
|
||||
|
||||
public function set($key, $value, $ttl = 0) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::set::' . $key . '::' . $ttl . '::' . json_encode($value) . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
if ($ttl > 0) {
|
||||
return self::$cache->setex($this->getNameSpace() . $key, $ttl, json_encode($value));
|
||||
} else {
|
||||
|
|
@ -69,10 +88,26 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
}
|
||||
|
||||
public function hasKey($key) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::hasKey::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
return (bool)self::$cache->exists($this->getNameSpace() . $key);
|
||||
}
|
||||
|
||||
public function remove($key) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::remove::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
if (self::$cache->del($this->getNameSpace() . $key)) {
|
||||
return true;
|
||||
} else {
|
||||
|
|
@ -81,6 +116,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
}
|
||||
|
||||
public function clear($prefix = '') {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::clear::' . $prefix . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
$prefix = $this->getNameSpace() . $prefix . '*';
|
||||
$keys = self::$cache->keys($prefix);
|
||||
$deleted = self::$cache->del($keys);
|
||||
|
|
@ -106,6 +149,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
if ($ttl !== 0 && is_int($ttl)) {
|
||||
$args['ex'] = $ttl;
|
||||
}
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::add::' . $key . '::' . $value . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return self::$cache->set($this->getPrefix() . $key, $value, $args);
|
||||
}
|
||||
|
|
@ -118,6 +169,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
* @return int | bool
|
||||
*/
|
||||
public function inc($key, $step = 1) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::inc::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
return self::$cache->incrBy($this->getNameSpace() . $key, $step);
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +188,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
* @return int | bool
|
||||
*/
|
||||
public function dec($key, $step = 1) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::dec::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
if (!$this->hasKey($key)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -144,6 +211,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
* @return bool
|
||||
*/
|
||||
public function cas($key, $old, $new) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::cas::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
if (!is_int($new)) {
|
||||
$new = json_encode($new);
|
||||
}
|
||||
|
|
@ -166,6 +241,14 @@ class Redis extends Cache implements IMemcacheTTL {
|
|||
* @return bool
|
||||
*/
|
||||
public function cad($key, $old) {
|
||||
if ($this->logFile !== '' && is_writable($this->logFile)) {
|
||||
file_put_contents(
|
||||
$this->logFile,
|
||||
$this->getNameSpace() . '::cad::' . $key . "\n",
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
|
||||
self::$cache->watch($this->getNameSpace() . $key);
|
||||
if ($this->get($key) === $old) {
|
||||
$result = self::$cache->multi()
|
||||
|
|
|
|||
|
|
@ -697,7 +697,8 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
return new \OC\Memcache\Factory($prefix, $c->get(ILogger::class),
|
||||
$config->getSystemValue('memcache.local', null),
|
||||
$config->getSystemValue('memcache.distributed', null),
|
||||
$config->getSystemValue('memcache.locking', null)
|
||||
$config->getSystemValue('memcache.locking', null),
|
||||
$config->getSystemValueString('redis_log_file')
|
||||
);
|
||||
}
|
||||
return $arrayCacheFactory;
|
||||
|
|
|
|||
Loading…
Reference in a new issue