RequestSubscriber.php in Raven: Sentry Integration 3.x
File
src/EventSubscriber/RequestSubscriber.php
View source
<?php
namespace Drupal\raven\EventSubscriber;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Database\Database;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Security\TrustedCallbackInterface;
use Drupal\raven\Logger\Raven;
use Sentry\SentrySdk;
use Sentry\Tracing\SpanContext;
use Sentry\Tracing\TransactionContext;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class RequestSubscriber implements EventSubscriberInterface, ContainerAwareInterface, TrustedCallbackInterface {
use ContainerAwareTrait;
protected $configFactory;
protected $container;
protected $logger;
protected $time;
public $transaction;
public function __construct(ConfigFactoryInterface $config_factory = NULL, Raven $logger = NULL, TimeInterface $time = NULL) {
$this->configFactory = $config_factory;
$this->logger = $logger;
$this->time = $time;
}
public function onRequest(KernelEvent $event) {
$method = method_exists($event, 'isMainRequest') ? 'isMainRequest' : 'isMasterRequest';
if (!$event
->{$method}() || !$this->configFactory) {
return;
}
$config = $this->configFactory
->get('raven.settings');
if (!$config
->get('request_tracing') || !$this->logger || !$this->logger
->getClient()) {
return;
}
$request = $event
->getRequest();
$sentryTraceHeader = $request->headers
->get('sentry-trace');
$transactionContext = $sentryTraceHeader && method_exists(TransactionContext::class, 'fromSentryTrace') ? TransactionContext::fromSentryTrace($sentryTraceHeader) : new TransactionContext();
$transactionContext
->setName($request
->getMethod() . ' ' . $request
->getUri());
$transactionContext
->setOp('http.server');
$transactionContext
->setTags([
'http.method' => $request
->getMethod(),
'http.url' => $request
->getUri(),
]);
$transactionContext
->setStartTimestamp($this->time
->getRequestMicroTime());
$this->transaction = \Sentry\startTransaction($transactionContext);
SentrySdk::getCurrentHub()
->setSpan($this->transaction);
if ($config
->get('database_tracing')) {
foreach (Database::getAllConnectionInfo() as $key => $info) {
Database::startLog('raven', $key);
}
}
}
public function onTerminate(KernelEvent $event) {
if (!$this->transaction) {
return;
}
if (method_exists($event, 'getResponse')) {
$this->transaction
->setHttpStatus($event
->getResponse()
->getStatusCode());
}
if ($this->configFactory
->get('raven.settings')
->get('database_tracing')) {
$this
->collectDatabaseLog();
}
$this->transaction
->finish();
}
public function collectDatabaseLog() {
if (!$this->transaction || !$this->container || !$this->container
->initialized('database')) {
return;
}
$connections = [];
foreach (Database::getAllConnectionInfo() as $key => $info) {
try {
$database = Database::getConnection('default', $key);
if ($logger = $database
->getLogger()) {
$connections[$key] = $logger
->get('raven');
}
} catch (\Exception $e) {
}
}
foreach ($connections as $key => $queries) {
foreach ($queries as $query) {
if (empty($query['start'])) {
return;
}
$context = new SpanContext();
$context
->setOp('sql.query');
$context
->setDescription($query['query']);
$context
->setTags([
'database' => $key,
]);
$context
->setStartTimestamp($query['start']);
$context
->setEndTimestamp($query['start'] + $query['time']);
$this->transaction
->startChild($context);
}
}
}
public static function getSubscribedEvents() {
$events[KernelEvents::REQUEST][] = [
'onRequest',
222,
];
$events[KernelEvents::TERMINATE][] = [
'onTerminate',
222,
];
return $events;
}
public static function trustedCallbacks() {
return [
'getTraceparent',
];
}
public function getTraceParent() {
$markup = '';
if (class_exists(SentrySdk::class)) {
if ($span = SentrySdk::getCurrentHub()
->getSpan()) {
$markup = $span
->toTraceparent();
}
}
return [
'#markup' => $markup,
];
}
}