mirror of
https://github.com/nextcloud/server.git
synced 2026-06-08 16:26:59 -04:00
Merge pull request #46751 from nextcloud/backport/44788/stable28
[stable28] feat: add additional logging for database errors
This commit is contained in:
commit
4100c1802e
2 changed files with 71 additions and 4 deletions
|
|
@ -79,6 +79,9 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
/** @var DbDataCollector|null */
|
||||
protected $dbDataCollector = null;
|
||||
|
||||
protected bool $logDbException = false;
|
||||
private ?array $transactionBacktrace = null;
|
||||
|
||||
protected bool $logRequestId;
|
||||
protected string $requestId;
|
||||
|
||||
|
|
@ -110,6 +113,7 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
$this->logger = \OC::$server->get(LoggerInterface::class);
|
||||
|
||||
$this->logRequestId = $this->systemConfig->getValue('db.log_request_id', false);
|
||||
$this->logDbException = $this->systemConfig->getValue('db.log_exceptions', false);
|
||||
$this->requestId = Server::get(IRequestId::class)->getId();
|
||||
|
||||
/** @var \OCP\Profiler\IProfiler */
|
||||
|
|
@ -263,7 +267,12 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
$sql = $this->finishQuery($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
return parent::executeQuery($sql, $params, $types, $qcp);
|
||||
try {
|
||||
return parent::executeQuery($sql, $params, $types, $qcp);
|
||||
} catch (\Exception $e) {
|
||||
$this->logDatabaseException($e);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -294,7 +303,12 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
$sql = $this->finishQuery($sql);
|
||||
$this->queriesExecuted++;
|
||||
$this->logQueryToFile($sql);
|
||||
return (int)parent::executeStatement($sql, $params, $types);
|
||||
try {
|
||||
return (int)parent::executeStatement($sql, $params, $types);
|
||||
} catch (\Exception $e) {
|
||||
$this->logDatabaseException($e);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
protected function logQueryToFile(string $sql): void {
|
||||
|
|
@ -356,11 +370,21 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
* @deprecated 15.0.0 - use unique index and "try { $db->insert() } catch (UniqueConstraintViolationException $e) {}" instead, because it is more reliable and does not have the risk for deadlocks - see https://github.com/nextcloud/server/pull/12371
|
||||
*/
|
||||
public function insertIfNotExist($table, $input, array $compare = null) {
|
||||
return $this->adapter->insertIfNotExist($table, $input, $compare);
|
||||
try {
|
||||
return $this->adapter->insertIfNotExist($table, $input, $compare);
|
||||
} catch (\Exception $e) {
|
||||
$this->logDatabaseException($e);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
public function insertIgnoreConflict(string $table, array $values) : int {
|
||||
return $this->adapter->insertIgnoreConflict($table, $values);
|
||||
try {
|
||||
return $this->adapter->insertIgnoreConflict($table, $values);
|
||||
} catch (\Exception $e) {
|
||||
$this->logDatabaseException($e);
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function getType($value) {
|
||||
|
|
@ -616,4 +640,43 @@ class Connection extends \Doctrine\DBAL\Connection {
|
|||
return new Migrator($this, $config, $dispatcher);
|
||||
}
|
||||
}
|
||||
|
||||
public function beginTransaction() {
|
||||
if (!$this->inTransaction()) {
|
||||
$this->transactionBacktrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
|
||||
}
|
||||
return parent::beginTransaction();
|
||||
}
|
||||
|
||||
public function commit() {
|
||||
$result = parent::commit();
|
||||
if ($this->getTransactionNestingLevel() === 0) {
|
||||
$this->transactionBacktrace = null;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
public function rollBack() {
|
||||
$result = parent::rollBack();
|
||||
if ($this->getTransactionNestingLevel() === 0) {
|
||||
$this->transactionBacktrace = null;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log a database exception if enabled
|
||||
*
|
||||
* @param \Exception $exception
|
||||
* @return void
|
||||
*/
|
||||
public function logDatabaseException(\Exception $exception): void {
|
||||
if ($this->logDbException) {
|
||||
if ($exception instanceof Exception\UniqueConstraintViolationException) {
|
||||
$this->logger->info($exception->getMessage(), ['exception' => $exception, 'transaction' => $this->transactionBacktrace]);
|
||||
} else {
|
||||
$this->logger->error($exception->getMessage(), ['exception' => $exception, 'transaction' => $this->transactionBacktrace]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -261,4 +261,8 @@ class ConnectionAdapter implements IDBConnection {
|
|||
throw new \Exception('Database ' . $platform::class . ' not supported');
|
||||
}
|
||||
}
|
||||
|
||||
public function logDatabaseException(\Exception $exception) {
|
||||
$this->inner->logDatabaseException($exception);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue