Skip to content

Commit

Permalink
[FEATURE] Special handling for log records with "exception" keys
Browse files Browse the repository at this point in the history
TYPO3 scheduler catches exceptions of failed tasks and logs messages
with the exception as "exception" data property.

PHP Exception objects do not get serialized by json_encode() and thus
never reach Sentry; all information about them is lost.

If a log record contains an 'exception' data key, then the exception
itself is logged to Sentry. The log message is kept as breadcrumb.

Resolves: #106
  • Loading branch information
cweiske committed May 7, 2024
1 parent 5978be6 commit cd1fa4f
Showing 1 changed file with 38 additions and 1 deletion.
39 changes: 38 additions & 1 deletion Classes/SentryLogWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Networkteam\SentryClient\Service\ConfigurationService;
use Networkteam\SentryClient\Service\SentryService;
use Networkteam\SentryClient\Trait\IgnoreMessage;
use Sentry\Breadcrumb;
use Sentry\Event;
use Sentry\Stacktrace;
use Sentry\State\Scope;
Expand Down Expand Up @@ -36,6 +37,12 @@ public function writeLog(LogRecord $record)
if (SentryService::isEnabled()
&& $this->shouldHandleLogMessage($record)
) {
$data = $record->getData();
if (isset($data['exception']) && $data['exception'] instanceof \Throwable) {
$this->writeException($record);
return $this;
}

withScope(function (Scope $scope) use ($record): void {
$scope->setExtra('component', $record->getComponent());
if ($record->getData()) {
Expand All @@ -46,7 +53,7 @@ public function writeLog(LogRecord $record)
$record->getMessage(),
$record->getComponent()
]);

$message = $record->getMessage();
if (method_exists($this, 'interpolate')) {
$message = $this->interpolate($message, $record->getData());
Expand All @@ -59,6 +66,36 @@ public function writeLog(LogRecord $record)
return $this;
}

/**
* Report a log record with an 'exception' object in its data.
*
* Exception objects in Sentry data properties do not get serialized
* and thus get lost.
* To keep them and their stacktrace, we send it as exception to Sentry.
* The log message is kept as breadcrumb.
*
* TYPO3 scheduler logs such messages when tasks fail.
*/
protected function writeException(LogRecord $record): void
{
$data = $record->getData();
$exception = $data['exception'];
unset($data['exception']);

withScope(function (Scope $scope) use ($data, $exception, $record): void {
$scope->setExtra('component', $record->getComponent());
$scope->setExtra('data', $data);

$message = $record->getMessage();
if (method_exists($this, 'interpolate')) {
$message = $this->interpolate($message, $record->getData());
}
$scope->addBreadcrumb(new Breadcrumb('error', 'default', 'log message', $message, []));

Client::captureException($exception);
});
}

protected function shouldHandleLogMessage(LogRecord $logRecord): bool
{
if ($this->shouldIgnoreMessage($logRecord->getMessage())) {
Expand Down

0 comments on commit cd1fa4f

Please sign in to comment.