Browse Source

Allow to log DB, redis and LDAP requests into files

Signed-off-by: Joas Schilling <coding@schilljs.com>
tags/v24.0.0beta1
Joas Schilling 2 years ago
parent
commit
168c673755
No account linked to committer's email address

+ 7
- 2
apps/user_ldap/lib/AppInfo/Application.php View File

); );
}); });


$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')
);
}); });
} }



+ 1
- 1
apps/user_ldap/lib/Jobs/Sync.php View File

if (isset($argument['ldapWrapper'])) { if (isset($argument['ldapWrapper'])) {
$this->ldap = $argument['ldapWrapper']; $this->ldap = $argument['ldapWrapper'];
} else { } else {
$this->ldap = new LDAP();
$this->ldap = new LDAP($this->config->getSystemValueString('ldap_log_file'));
} }


if (isset($argument['avatarManager'])) { if (isset($argument['avatarManager'])) {

+ 15
- 1
apps/user_ldap/lib/LDAP.php View File

use OCA\User_LDAP\PagedResults\Php73; use OCA\User_LDAP\PagedResults\Php73;


class LDAP implements ILDAPWrapper { class LDAP implements ILDAPWrapper {
protected $logFile = '';
protected $curFunc = ''; protected $curFunc = '';
protected $curArgs = []; protected $curArgs = [];


/** @var IAdapter */ /** @var IAdapter */
protected $pagedResultsAdapter; protected $pagedResultsAdapter;


public function __construct() {
public function __construct(string $logFile = '') {
$this->pagedResultsAdapter = new Php73(); $this->pagedResultsAdapter = new Php73();
$this->logFile = $logFile;
} }


/** /**
private function preFunctionCall($functionName, $args) { private function preFunctionCall($functionName, $args) {
$this->curFunc = $functionName; $this->curFunc = $functionName;
$this->curArgs = $args; $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
);
}
} }


/** /**

+ 27
- 0
config/config.sample.php View File

* Defaults to ``true`` * Defaults to ``true``
*/ */
'files_no_background_scan' => false, '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' => '',
]; ];

+ 14
- 0
lib/private/DB/Connection.php View File

$sql = $this->replaceTablePrefix($sql); $sql = $this->replaceTablePrefix($sql);
$sql = $this->adapter->fixupStatement($sql); $sql = $this->adapter->fixupStatement($sql);
$this->queriesExecuted++; $this->queriesExecuted++;
$this->logQueryToFile($sql);
return parent::executeQuery($sql, $params, $types, $qcp); return parent::executeQuery($sql, $params, $types, $qcp);
} }


$sql = $this->replaceTablePrefix($sql); $sql = $this->replaceTablePrefix($sql);
$sql = $this->adapter->fixupStatement($sql); $sql = $this->adapter->fixupStatement($sql);
$this->queriesExecuted++; $this->queriesExecuted++;
$this->logQueryToFile($sql);
return parent::executeUpdate($sql, $params, $types); return parent::executeUpdate($sql, $params, $types);
} }


$sql = $this->replaceTablePrefix($sql); $sql = $this->replaceTablePrefix($sql);
$sql = $this->adapter->fixupStatement($sql); $sql = $this->adapter->fixupStatement($sql);
$this->queriesExecuted++; $this->queriesExecuted++;
$this->logQueryToFile($sql);
return parent::executeStatement($sql, $params, $types); 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, * Returns the ID of the last inserted row, or the last value from a sequence object,
* depending on the underlying driver. * depending on the underlying driver.

+ 9
- 4
lib/private/Memcache/Factory.php View File

*/ */
private $lockingCacheClass; private $lockingCacheClass;


/** @var string */
private $logFile;

/** /**
* @param string $globalPrefix * @param string $globalPrefix
* @param ILogger $logger * @param ILogger $logger
* @param string|null $localCacheClass * @param string|null $localCacheClass
* @param string|null $distributedCacheClass * @param string|null $distributedCacheClass
* @param string|null $lockingCacheClass * @param string|null $lockingCacheClass
* @param string $logFile
*/ */
public function __construct(string $globalPrefix, ILogger $logger, 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->logger = $logger;
$this->logFile = $logFile;
$this->globalPrefix = $globalPrefix; $this->globalPrefix = $globalPrefix;


if (!$localCacheClass) { if (!$localCacheClass) {
* @return IMemcache * @return IMemcache
*/ */
public function createLocking(string $prefix = ''): IMemcache { public function createLocking(string $prefix = ''): IMemcache {
return new $this->lockingCacheClass($this->globalPrefix . '/' . $prefix);
return new $this->lockingCacheClass($this->globalPrefix . '/' . $prefix, $this->logFile);
} }


/** /**
* @return ICache * @return ICache
*/ */
public function createDistributed(string $prefix = ''): ICache { public function createDistributed(string $prefix = ''): ICache {
return new $this->distributedCacheClass($this->globalPrefix . '/' . $prefix);
return new $this->distributedCacheClass($this->globalPrefix . '/' . $prefix, $this->logFile);
} }


/** /**
* @return ICache * @return ICache
*/ */
public function createLocal(string $prefix = ''): ICache { public function createLocal(string $prefix = ''): ICache {
return new $this->localCacheClass($this->globalPrefix . '/' . $prefix);
return new $this->localCacheClass($this->globalPrefix . '/' . $prefix, $this->logFile);
} }


/** /**

+ 84
- 1
lib/private/Memcache/Redis.php View File

*/ */
private static $cache = null; private static $cache = null;


public function __construct($prefix = '') {
private $logFile;

public function __construct($prefix = '', string $logFile = '') {
parent::__construct($prefix); parent::__construct($prefix);
$this->logFile = $logFile;
if (is_null(self::$cache)) { if (is_null(self::$cache)) {
self::$cache = \OC::$server->getGetRedisFactory()->getInstance(); self::$cache = \OC::$server->getGetRedisFactory()->getInstance();
} }
} }


public function get($key) { 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); $result = self::$cache->get($this->getNameSpace() . $key);
if ($result === false && !self::$cache->exists($this->getNameSpace() . $key)) { if ($result === false && !self::$cache->exists($this->getNameSpace() . $key)) {
return null; return null;
} }


public function set($key, $value, $ttl = 0) { 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) { if ($ttl > 0) {
return self::$cache->setex($this->getNameSpace() . $key, $ttl, json_encode($value)); return self::$cache->setex($this->getNameSpace() . $key, $ttl, json_encode($value));
} else { } else {
} }


public function hasKey($key) { 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); return (bool)self::$cache->exists($this->getNameSpace() . $key);
} }


public function remove($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)) { if (self::$cache->del($this->getNameSpace() . $key)) {
return true; return true;
} else { } else {
} }


public function clear($prefix = '') { 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 . '*'; $prefix = $this->getNameSpace() . $prefix . '*';
$keys = self::$cache->keys($prefix); $keys = self::$cache->keys($prefix);
$deleted = self::$cache->del($keys); $deleted = self::$cache->del($keys);
if ($ttl !== 0 && is_int($ttl)) { if ($ttl !== 0 && is_int($ttl)) {
$args['ex'] = $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); return self::$cache->set($this->getPrefix() . $key, $value, $args);
} }
* @return int | bool * @return int | bool
*/ */
public function inc($key, $step = 1) { 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); return self::$cache->incrBy($this->getNameSpace() . $key, $step);
} }


* @return int | bool * @return int | bool
*/ */
public function dec($key, $step = 1) { 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)) { if (!$this->hasKey($key)) {
return false; return false;
} }
* @return bool * @return bool
*/ */
public function cas($key, $old, $new) { 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)) { if (!is_int($new)) {
$new = json_encode($new); $new = json_encode($new);
} }
* @return bool * @return bool
*/ */
public function cad($key, $old) { 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); self::$cache->watch($this->getNameSpace() . $key);
if ($this->get($key) === $old) { if ($this->get($key) === $old) {
$result = self::$cache->multi() $result = self::$cache->multi()

+ 2
- 1
lib/private/Server.php View File

return new \OC\Memcache\Factory($prefix, $c->get(ILogger::class), return new \OC\Memcache\Factory($prefix, $c->get(ILogger::class),
$config->getSystemValue('memcache.local', null), $config->getSystemValue('memcache.local', null),
$config->getSystemValue('memcache.distributed', null), $config->getSystemValue('memcache.distributed', null),
$config->getSystemValue('memcache.locking', null)
$config->getSystemValue('memcache.locking', null),
$config->getSystemValueString('redis_log_file')
); );
} }
return $arrayCacheFactory; return $arrayCacheFactory;

Loading…
Cancel
Save