Skip to content

Commit

Permalink
add: breadcrumbs to monolog handler
Browse files Browse the repository at this point in the history
  • Loading branch information
B-Galati committed Jul 4, 2019
1 parent e85c748 commit 940cc61
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 2 deletions.
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
"phpunit/phpunit": "^7.0",
"symfony/phpunit-bridge": "^4.1.6"
},
"suggest": {
"monolog/monolog": "If you want to use the monolog sentry handler."
},
"conflict": {
"php-http/client-common": "1.8.0",
"raven/raven": "*"
Expand Down
108 changes: 106 additions & 2 deletions src/Monolog/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Monolog\Handler\AbstractProcessingHandler;
use Monolog\Logger;
use Sentry\Breadcrumb;
use Sentry\Severity;
use Sentry\State\HubInterface;
use Sentry\State\Scope;
Expand All @@ -23,6 +24,11 @@ final class Handler extends AbstractProcessingHandler
*/
private $hub;

/**
* @var array
*/
protected $breadcrumbsBuffer = [];

/**
* Constructor.
*
Expand All @@ -37,6 +43,50 @@ public function __construct(HubInterface $hub, $level = Logger::DEBUG, bool $bub
$this->hub = $hub;

parent::__construct($level, $bubble);

$this->hub = $hub;
}

/**
* {@inheritdoc}
*/
public function handleBatch(array $records): void
{
if (!$records) {
return;
}

// filter records
$records = array_filter(
$records,
function ($record) {
return $record['level'] >= $this->level;
}
);

// the record with the highest severity is the "main" one
$main = array_reduce(
$records,
static function ($highest, $record) {
if ($record['level'] > $highest['level']) {
return $record;
}

return $highest;
}
);

// the other ones are added as a context items
foreach ($records as $record) {
$record = $this->processRecord($record);
$record['formatted'] = $this->getFormatter()->format($record);

$this->breadcrumbsBuffer[] = $record;
}

$this->handle($main);

$this->breadcrumbsBuffer = [];
}

/**
Expand All @@ -56,19 +106,29 @@ protected function write(array $record): void
$this->hub->withScope(function (Scope $scope) use ($record, $payload): void {
$scope->setExtra('monolog.channel', $record['channel']);
$scope->setExtra('monolog.level', $record['level_name']);
$scope->setExtra('monolog.formatted', $record['formatted']);

if (isset($record['context']['extra']) && \is_array($record['context']['extra'])) {
foreach ($record['context']['extra'] as $key => $value) {
$scope->setExtra((string) $key, $value);
$scope->setExtra($key, $value);
}
}

if (isset($record['context']['tags']) && \is_array($record['context']['tags'])) {
foreach ($record['context']['tags'] as $key => $value) {
$scope->setTag($key, $value);
$scope->setTag((string) $key, $value ?? 'N/A');
}
}

foreach ($this->breadcrumbsBuffer as $breadcrumbRecord) {
$scope->addBreadcrumb(new Breadcrumb(
$this->getBreadcrumbLevelFromLevel($breadcrumbRecord['level']),
$this->getBreadcrumbTypeFromLevel($breadcrumbRecord['level']),
$breadcrumbRecord['channel'] ?? 'N/A',
$breadcrumbRecord['formatted']
));
}

$this->hub->captureEvent($payload);
});
}
Expand Down Expand Up @@ -100,4 +160,48 @@ private function getSeverityFromLevel(int $level): Severity
return Severity::info();
}
}

/**
* Translates the Monolog level into the Sentry breadcrumb level.
*
* @param int $level The Monolog log level
*
* @return string
*/
private function getBreadcrumbLevelFromLevel(int $level): string
{
switch ($level) {
case Logger::DEBUG:
return Breadcrumb::LEVEL_DEBUG;
case Logger::INFO:
case Logger::NOTICE:
return Breadcrumb::LEVEL_INFO;
case Logger::WARNING:
return Breadcrumb::LEVEL_WARNING;
case Logger::ERROR:
return Breadcrumb::LEVEL_ERROR;
case Logger::CRITICAL:
case Logger::ALERT:
case Logger::EMERGENCY:
return Breadcrumb::LEVEL_CRITICAL;
default:
return Breadcrumb::LEVEL_CRITICAL;
}
}

/**
* Translates the Monolog level into the Sentry breadcrumb type.
*
* @param int $level The Monolog log level
*
* @return string
*/
private function getBreadcrumbTypeFromLevel(int $level): string
{
if ($level >= Logger::ERROR) {
return Breadcrumb::TYPE_ERROR;
}

return Breadcrumb::TYPE_DEFAULT;
}
}

0 comments on commit 940cc61

Please sign in to comment.