function raven_watchdog in Raven: Sentry Integration 7.4
Same name and namespace in other branches
- 7 raven.module \raven_watchdog()
- 7.2 raven.module \raven_watchdog()
- 7.3 raven.module \raven_watchdog()
Implements hook_watchdog().
File
- ./
raven.module, line 134 - Allows to track errors to Sentry server.
Code
function raven_watchdog($log_entry) {
static $counter = 0;
if (!variable_get('raven_enabled', FALSE)) {
return;
}
$client = raven_get_client();
if (!$client) {
return;
}
$watchdog_levels = variable_get('raven_watchdog_levels', []);
$levels_map = [
WATCHDOG_EMERGENCY => Severity::FATAL,
WATCHDOG_ALERT => Severity::FATAL,
WATCHDOG_CRITICAL => Severity::FATAL,
WATCHDOG_ERROR => Severity::ERROR,
WATCHDOG_WARNING => Severity::WARNING,
WATCHDOG_NOTICE => Severity::INFO,
WATCHDOG_INFO => Severity::INFO,
WATCHDOG_DEBUG => Severity::DEBUG,
];
$variables = $log_entry['variables'];
if (!$variables) {
$variables = [];
}
$event = Event::createEvent();
$event
->setLevel(new Severity($levels_map[$log_entry['severity']]));
$message = html_entity_decode(strip_tags(strtr($log_entry['message'], $variables)), ENT_QUOTES, 'UTF-8');
$event
->setMessage($log_entry['message'], $variables, $message);
$extra = [
'request_uri' => $log_entry['request_uri'],
];
if ($log_entry['referer']) {
$extra['referer'] = $log_entry['referer'];
}
if ($log_entry['link']) {
$extra['link'] = $log_entry['link'];
}
$event
->setExtra($extra);
$event
->setLogger($log_entry['type']);
$user = UserDataBag::createFromUserIdentifier($log_entry['uid']);
$user
->setIpAddress($log_entry['ip']);
if ($log_entry['user'] && $log_entry['uid']) {
if (variable_get('raven_send_user_data', FALSE)) {
$user
->setEmail($log_entry['user']->mail);
$user
->setUsername($log_entry['user']->name);
}
$user
->setMetadata('roles', implode(', ', $log_entry['user']->roles));
}
$event
->setUser($user);
$filter = [
'process' => !empty($watchdog_levels[$log_entry['severity'] + 1]),
'log_entry' => $log_entry,
'event' => $event,
];
$ignored_types = array_map('trim', preg_split('/\\R/', variable_get('raven_ignored_types', ''), -1, PREG_SPLIT_NO_EMPTY));
if (in_array($log_entry['type'], $ignored_types)) {
$filter['process'] = FALSE;
}
drupal_alter('raven_watchdog_filter', $filter);
if ($filter['process']) {
// Save memory by not copying the object for each frame.
$stack = debug_backtrace(0);
// Ignore error handling and logging frames.
if (empty($stack[0]['class']) && isset($stack[0]['function']) && $stack[0]['function'] == 'raven_watchdog') {
array_shift($stack);
}
if (empty($stack[0]['class']) && isset($stack[0]['function']) && $stack[0]['function'] == 'call_user_func_array') {
array_shift($stack);
}
if (empty($stack[0]['class']) && isset($stack[0]['function']) && ($stack[0]['function'] == 'module_invoke_all' || $stack[0]['function'] == 'module_invoke')) {
array_shift($stack);
}
if (empty($stack[0]['class']) && isset($stack[0]['function']) && $stack[0]['function'] == 'watchdog' && empty($stack[1]['class']) && isset($stack[1]['function']) && $stack[1]['function'] == 'watchdog_exception') {
array_shift($stack);
}
elseif (empty($stack[0]['class']) && isset($stack[0]['function']) && $stack[0]['function'] == 'watchdog' && empty($stack[1]['class']) && isset($stack[1]['function']) && $stack[1]['function'] == '_drupal_log_error') {
array_shift($stack);
array_shift($stack);
}
if (empty($stack[0]['class']) && isset($stack[0]['function']) && $stack[0]['function'] == '_drupal_error_handler_real') {
array_shift($stack);
}
if (empty($stack[0]['class']) && isset($stack[0]['function']) && $stack[0]['function'] == '_drupal_error_handler' && empty($stack[0]['line'])) {
array_shift($stack);
}
if (empty($stack[0]['class']) && isset($stack[0]['function']) && ($stack[0]['function'] == 'watchdog_exception' || $stack[0]['function'] == '_drupal_exception_handler')) {
$arg = [
'watchdog_exception' => 1,
'_drupal_exception_handler' => 0,
];
// Use the exception backtrace for (usually) easier debugging.
$exception = $stack[0]['args'][$arg[$stack[0]['function']]];
$stack = $exception
->getTrace();
// Copy logic from _drupal_decode_exception().
array_unshift($stack, [
'line' => $exception
->getLine(),
'file' => $exception
->getFile(),
]);
if ($exception instanceof PDOException) {
$db_functions = [
'db_query',
'db_query_range',
];
while (!empty($stack[1]) && ($caller = $stack[1]) && (isset($caller['class']) && (strpos($caller['class'], 'Query') !== FALSE || strpos($caller['class'], 'Database') !== FALSE || strpos($caller['class'], 'PDO') !== FALSE) || in_array($caller['function'], $db_functions))) {
array_shift($stack);
}
}
}
if (!variable_get('raven_trace', FALSE)) {
foreach ($stack as &$frame) {
unset($frame['args']);
}
}
$stacktraceBuilder = new StacktraceBuilder($client
->getOptions(), new RepresentationSerializer($client
->getOptions()));
$stacktrace = $stacktraceBuilder
->buildFromBacktrace($stack, '', 0);
$stacktrace
->removeFrame(count($stacktrace
->getFrames()) - 1);
$rateLimit = variable_get('raven_rate_limit', 0);
if (!$rateLimit || $counter < $rateLimit) {
\Sentry\captureEvent($event, EventHint::fromArray([
'stacktrace' => $stacktrace,
]));
}
elseif ($counter == $rateLimit) {
\Sentry\captureException(new RavenRateLimitException('Log event discarded due to rate limit exceeded; future log events will not be captured by Sentry.'));
}
$counter++;
}
// Record a breadcrumb.
$breadcrumb = [
'log_entry' => $log_entry,
'process' => TRUE,
'breadcrumb' => [
'category' => $log_entry['type'],
'message' => $message,
'level' => $levels_map[$log_entry['severity']],
],
];
foreach ([
'%line',
'%file',
'%type',
'%function',
] as $key) {
if (isset($log_entry['variables'][$key])) {
$breadcrumb['breadcrumb']['data'][substr($key, 1)] = $log_entry['variables'][$key];
}
}
drupal_alter('raven_breadcrumb', $breadcrumb);
if (!empty($breadcrumb['process'])) {
\Sentry\addBreadcrumb(Breadcrumb::fromArray($breadcrumb['breadcrumb']));
}
}