Skip to content

Commit

Permalink
Merge pull request #46751 from nextcloud/backport/44788/stable28
Browse files Browse the repository at this point in the history
[stable28] feat: add additional logging for database errors
  • Loading branch information
AndyScherzinger authored Jul 25, 2024
2 parents e126034 + bd28c9f commit 4100c18
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 4 deletions.
71 changes: 67 additions & 4 deletions lib/private/DB/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -110,6 +113,7 @@ public function __construct(
$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 */
Expand Down Expand Up @@ -263,7 +267,12 @@ public function executeQuery(string $sql, array $params = [], $types = [], Query
$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;
}
}

/**
Expand Down Expand Up @@ -294,7 +303,12 @@ public function executeStatement($sql, array $params = [], array $types = []): i
$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 {
Expand Down Expand Up @@ -356,11 +370,21 @@ public function realLastInsertId($seqName = null) {
* @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) {
Expand Down Expand Up @@ -616,4 +640,43 @@ private function getMigrator() {
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]);
}
}
}
}
4 changes: 4 additions & 0 deletions lib/private/DB/ConnectionAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,8 @@ public function getDatabaseProvider(): string {
throw new \Exception('Database ' . $platform::class . ' not supported');
}
}

public function logDatabaseException(\Exception $exception) {
$this->inner->logDatabaseException($exception);
}
}

0 comments on commit 4100c18

Please sign in to comment.