diff options
-rw-r--r-- | apps/user_ldap/lib/AppInfo/Application.php | 9 | ||||
-rw-r--r-- | apps/user_ldap/lib/Jobs/Sync.php | 2 | ||||
-rw-r--r-- | apps/user_ldap/lib/LDAP.php | 16 | ||||
-rw-r--r-- | config/config.sample.php | 27 | ||||
-rw-r--r-- | lib/private/DB/Connection.php | 14 | ||||
-rw-r--r-- | lib/private/Memcache/Factory.php | 13 | ||||
-rw-r--r-- | lib/private/Memcache/Redis.php | 85 | ||||
-rw-r--r-- | lib/private/Server.php | 3 |
8 files changed, 159 insertions, 10 deletions
diff --git a/apps/user_ldap/lib/AppInfo/Application.php b/apps/user_ldap/lib/AppInfo/Application.php index 8c48682eddb..79998a580e5 100644 --- a/apps/user_ldap/lib/AppInfo/Application.php +++ b/apps/user_ldap/lib/AppInfo/Application.php @@ -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') + ); }); } diff --git a/apps/user_ldap/lib/Jobs/Sync.php b/apps/user_ldap/lib/Jobs/Sync.php index 10036f8dc12..3d0dd88dfd2 100644 --- a/apps/user_ldap/lib/Jobs/Sync.php +++ b/apps/user_ldap/lib/Jobs/Sync.php @@ -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'])) { diff --git a/apps/user_ldap/lib/LDAP.php b/apps/user_ldap/lib/LDAP.php index 7210977e0e4..900f5a7030f 100644 --- a/apps/user_ldap/lib/LDAP.php +++ b/apps/user_ldap/lib/LDAP.php @@ -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 + ); + } } /** diff --git a/config/config.sample.php b/config/config.sample.php index fd25815dece..4a28748b69c 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -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' => '', ]; diff --git a/lib/private/DB/Connection.php b/lib/private/DB/Connection.php index 1965bb3eee4..9efacb0f9ae 100644 --- a/lib/private/DB/Connection.php +++ b/lib/private/DB/Connection.php @@ -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. diff --git a/lib/private/Memcache/Factory.php b/lib/private/Memcache/Factory.php index 08f19e11ef3..7791c4beae9 100644 --- a/lib/private/Memcache/Factory.php +++ b/lib/private/Memcache/Factory.php @@ -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); } /** diff --git a/lib/private/Memcache/Redis.php b/lib/private/Memcache/Redis.php index aee1773d565..74d8da187fe 100644 --- a/lib/private/Memcache/Redis.php +++ b/lib/private/Memcache/Redis.php @@ -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() diff --git a/lib/private/Server.php b/lib/private/Server.php index baebbe7558d..c0c69749aa8 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -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; |