Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MySQL: retry on 2006 audit log failure #2905

Merged
merged 1 commit into from
Feb 10, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions lib/Service/LogService.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php
/*
* Copyright (C) 2024 Xibo Signage Ltd
* Copyright (C) 2025 Xibo Signage Ltd
*
* Xibo - Digital Signage - https://xibosignage.com
*
Expand Down Expand Up @@ -155,10 +155,55 @@ public function audit($entity, $entityId, $message, $object)
));

if ($this->_auditLogStatement == null) {
// Use the default connection
// audit log should rollback on failure.
$dbh = PdoStorageService::newConnection('default');
$this->_auditLogStatement = $dbh->prepare('
$this->prepareAuditLogStatement();
}

// If we aren't a string then encode
if (!is_string($object)) {
$object = json_encode($object);
}

$params = [
'logDate' => Carbon::now()->format('U'),
'userId' => $this->userId,
'entity' => $entity,
'message' => $message,
'entityId' => $entityId,
'ipAddress' => $this->ipAddress,
'objectAfter' => $object,
'sessionHistoryId' => $this->sessionHistoryId,
'requestId' => $this->requestId
];

try {
$this->_auditLogStatement->execute($params);
} catch (\PDOException $PDOException) {
$errorCode = $PDOException->errorInfo[1] ?? $PDOException->getCode();

// Catch 2006 errors (mysql gone away)
if ($errorCode != 2006) {
throw $PDOException;
} else {
$this->prepareAuditLogStatement();
$this->_auditLogStatement->execute($params);
}
}

// Although we use the default connection, track audit status separately.
PdoStorageService::incrementStat('audit', 'insert');
}

/**
* Helper function to prepare a PDO statement for inserting into the Audit Log.
* sets $_auditLogStatement
* @return void
*/
private function prepareAuditLogStatement(): void
{
// Use the default connection
// audit log should rollback on failure.
$dbh = PdoStorageService::newConnection('default');
$this->_auditLogStatement = $dbh->prepare('
INSERT INTO `auditlog` (
`logDate`,
`userId`,
Expand All @@ -182,27 +227,6 @@ public function audit($entity, $entityId, $message, $object)
:requestId
)
');
}

// If we aren't a string then encode
if (!is_string($object)) {
$object = json_encode($object);
}

// Although we use the default connection, track audit status separately.
PdoStorageService::incrementStat('audit', 'insert');

$this->_auditLogStatement->execute([
'logDate' => Carbon::now()->format('U'),
'userId' => $this->userId,
'entity' => $entity,
'message' => $message,
'entityId' => $entityId,
'ipAddress' => $this->ipAddress,
'objectAfter' => $object,
'sessionHistoryId' => $this->sessionHistoryId,
'requestId' => $this->requestId
]);
}

/**
Expand Down