diff --git a/Helper/Data.php b/Helper/Data.php index 95a6aff..480d81f 100644 --- a/Helper/Data.php +++ b/Helper/Data.php @@ -233,6 +233,14 @@ public function isPhpTrackingEnabled() return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_php_tracking'); } + /** + * @return bool + */ + public function isPerformanceTrackingEnabled() + { + return $this->scopeConfig->isSetFlag(static::XML_PATH_SRS.'enable_performance_tracking'); + } + /** * @return bool */ diff --git a/Model/SentryPerformance.php b/Model/SentryPerformance.php new file mode 100644 index 0000000..cc808e4 --- /dev/null +++ b/Model/SentryPerformance.php @@ -0,0 +1,98 @@ +resourceConnection = $resourceConnection; + } + + public function startTransaction(HttpRequest $request) + { + $requestStartTime = $request->getServer('REQUEST_TIME_FLOAT', microtime(true)); + + $context = TransactionContext::fromHeaders( + $request->getHeader('sentry-trace') ?: '', + $request->getHeader('baggage') ?: '' + ); + + $requestPath = '/'.ltrim($request->getRequestUri(), '/'); + + $context->setOp('http.server'); + $context->setName($requestPath); + $context->setSource(TransactionSource::url()); + $context->setStartTimestamp($requestStartTime); + + $context->setData([ + 'url' => $requestPath, + 'method' => strtoupper($request->getMethod()), + ]); + + // Start the transaction + $transaction = \Sentry\startTransaction($context); + + // If this transaction is not sampled, don't set it either and stop doing work from this point on + if (!$transaction->getSampled()) { + return; + } + + $this->transaction = $transaction; + + // Set the current transaction as the current span so we can retrieve it later + \Sentry\SentrySdk::getCurrentHub()->setSpan($transaction); + } + + /** + * @param ResponseInterface|Response $response + */ + public function finishTransaction(ResponseInterface $response) + { + if ($this->transaction) { + if ($response instanceof HttpResponse) { + $this->transaction->setHttpStatus($response->getStatusCode()); + } + + // Finish the transaction, this submits the transaction and it's span to Sentry + $this->transaction->finish(); + + $this->transaction = null; + } + } + + public function addSqlQuery($sql, $startTime, $endTime = null) + { + $parentSpan = SentrySdk::getCurrentHub()->getSpan(); + if (!$parentSpan) { + return; + } + + $context = new SpanContext(); + $context->setOp('db.sql.query'); + $context->setDescription($sql); + $context->setStartTimestamp($startTime); + $context->setEndTimestamp($endTime ?: microtime(true)); + + $parentSpan->startChild($context); + } +} diff --git a/Observer/ControllerActionPredispatchObserver.php b/Observer/ControllerActionPredispatchObserver.php new file mode 100644 index 0000000..c59bd0b --- /dev/null +++ b/Observer/ControllerActionPredispatchObserver.php @@ -0,0 +1,27 @@ +sentryPerformance = $sentryPerformance; + $this->request = $request; + } + + public function execute(\Magento\Framework\Event\Observer $observer) + { + $this->sentryPerformance->startTransaction($this->request); + } +} diff --git a/Plugin/GlobalExceptionCatcher.php b/Plugin/GlobalExceptionCatcher.php index 7a6cebb..4472b31 100755 --- a/Plugin/GlobalExceptionCatcher.php +++ b/Plugin/GlobalExceptionCatcher.php @@ -68,6 +68,10 @@ public function aroundLaunch(AppInterface $subject, callable $proceed) $config->setEnvironment($environment); } + if ($this->sentryHelper->isTracingEnabled() && $this->sentryHelper->isPerformanceTrackingEnabled()) { + $config->setTracesSampleRate($this->sentryHelper->getTracingSampleRate()); + } + $this->eventManager->dispatch('sentry_before_init', [ 'config' => $config, ]); diff --git a/Plugin/LoggerProxyPlugin.php b/Plugin/LoggerProxyPlugin.php new file mode 100644 index 0000000..f1293ee --- /dev/null +++ b/Plugin/LoggerProxyPlugin.php @@ -0,0 +1,44 @@ +sentryPerformance = $sentryPerformance; + } + + /** + * {@inheritdoc} + */ + public function beforeStartTimer() + { + $this->timer = microtime(true); + } + + /** + * @param LoggerProxy $subject + * @param string $type + * @param string $sql + * @param array $bind + * @param \Zend_Db_Statement_Pdo|null $result + * @return void + */ + public function beforeLogStats(LoggerProxy $subject, $type, $sql, $bind = [], $result = null) + { + $this->sentryPerformance->addSqlQuery($sql, $this->timer); + } +} diff --git a/Plugin/SampleRequest.php b/Plugin/SampleRequest.php new file mode 100644 index 0000000..5e45784 --- /dev/null +++ b/Plugin/SampleRequest.php @@ -0,0 +1,35 @@ +sentryPerformance = $sentryPerformance; + $this->request = $request; + } + + /** + * Add our toolbar to the response. + * + * @param ResponseInterface $response + */ + public function beforeSendResponse(ResponseInterface $response) + { + $this->sentryPerformance->finishTransaction($response); + } +} diff --git a/etc/adminhtml/system.xml b/etc/adminhtml/system.xml index 3358a73..98a88a9 100755 --- a/etc/adminhtml/system.xml +++ b/etc/adminhtml/system.xml @@ -19,6 +19,10 @@ Magento\Config\Model\Config\Source\Yesno + + + Magento\Config\Model\Config\Source\Yesno + Magento\Config\Model\Config\Source\Yesno diff --git a/etc/config.xml b/etc/config.xml index 37b1572..1b44ed4 100755 --- a/etc/config.xml +++ b/etc/config.xml @@ -4,6 +4,7 @@ 1 + 0 0 before.body.end 0 diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml new file mode 100644 index 0000000..0f98aa4 --- /dev/null +++ b/etc/frontend/di.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/etc/frontend/events.xml b/etc/frontend/events.xml new file mode 100644 index 0000000..3bbe102 --- /dev/null +++ b/etc/frontend/events.xml @@ -0,0 +1,6 @@ + + + + + +