diff --git a/Model/PerformanceTracingDto.php b/Model/PerformanceTracingDto.php
new file mode 100644
index 0000000..ce31dd8
--- /dev/null
+++ b/Model/PerformanceTracingDto.php
@@ -0,0 +1,33 @@
+scope;
+ }
+
+ public function getParentSpan(): ?Span
+ {
+ return $this->parentSpan;
+ }
+
+ public function getSpan(): ?Span
+ {
+ return $this->span;
+ }
+}
diff --git a/Model/SentryInteraction.php b/Model/SentryInteraction.php
index ea484f4..5aec00f 100644
--- a/Model/SentryInteraction.php
+++ b/Model/SentryInteraction.php
@@ -6,20 +6,36 @@
// phpcs:disable Magento2.Functions.DiscouragedFunction
+use JustBetter\Sentry\Helper\Data;
+use Throwable;
+
use function Sentry\captureException;
use function Sentry\init;
class SentryInteraction
{
- public function initialize($config)
+ public function __construct(
+ private Data $sentryHelper
+ ) {
+ }
+
+ public function initialize($config): void
{
init($config);
}
- public function captureException(\Throwable $ex)
+ public function captureException(Throwable $ex): void
{
+ if (!$this->sentryHelper->shouldCaptureException($ex)) {
+ return;
+ }
+
ob_start();
- captureException($ex);
+
+ try {
+ captureException($ex);
+ } catch (Throwable) {
+ }
ob_end_clean();
}
}
diff --git a/Model/SentryPerformance.php b/Model/SentryPerformance.php
index 0c8f536..d9b096b 100644
--- a/Model/SentryPerformance.php
+++ b/Model/SentryPerformance.php
@@ -16,12 +16,15 @@
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\ObjectManagerInterface;
use Sentry\SentrySdk;
+use Sentry\Tracing\Span;
use Sentry\Tracing\SpanContext;
use Sentry\Tracing\Transaction;
use Sentry\Tracing\TransactionContext;
use Sentry\Tracing\TransactionSource;
+use Throwable;
use function Sentry\startTransaction;
+use function Sentry\trace;
class SentryPerformance
{
@@ -68,8 +71,6 @@ public function startTransaction(AppInterface $app): void
}
$this->transaction = $transaction;
-
- // Set the current transaction as the current span so we can retrieve it later
SentrySdk::getCurrentHub()->setSpan($transaction);
}
@@ -113,28 +114,38 @@ public function finishTransaction(ResponseInterface|int $statusCode): void
} elseif ($state->getAreaCode() === 'graphql') {
$this->transaction->setOp('graphql');
} else {
- $this->transaction->setOp('other');
+ $this->transaction->setOp($state->getAreaCode());
}
- // Finish the transaction, this submits the transaction and it's span to Sentry
- $this->transaction->finish();
+ try {
+ // Finish the transaction, this submits the transaction and it's span to Sentry
+ $this->transaction->finish();
+ } catch (Throwable) {
+ }
$this->transaction = null;
}
- public function addSqlQuery($sql, $startTime, $endTime = null): void
+ public static function traceStart(SpanContext $context): PerformanceTracingDto
{
- $parentSpan = SentrySdk::getCurrentHub()->getSpan();
- if (!$parentSpan) {
- return;
+ $scope = SentrySdk::getCurrentHub()->pushScope();
+ $span = null;
+
+ $parentSpan = $scope->getSpan();
+ if ($parentSpan !== null && $parentSpan->getSampled()) {
+ $span = $parentSpan->startChild($context);
+ $scope->setSpan($span);
}
- $context = new SpanContext();
- $context->setOp('db.sql.query');
- $context->setDescription($sql);
- $context->setStartTimestamp($startTime);
- $context->setEndTimestamp($endTime ?: microtime(true));
+ return new PerformanceTracingDto($scope, $parentSpan, $span);
+ }
- $parentSpan->startChild($context);
+ public static function traceEnd(PerformanceTracingDto $context): void
+ {
+ if ($context->getSpan()) {
+ $context->getSpan()->finish();
+ $context->getScope()->setSpan($context->getParentSpan());
+ }
+ SentrySdk::getCurrentHub()->popScope();
}
}
diff --git a/Plugin/GlobalExceptionCatcher.php b/Plugin/GlobalExceptionCatcher.php
index 45e66b3..9d35c19 100755
--- a/Plugin/GlobalExceptionCatcher.php
+++ b/Plugin/GlobalExceptionCatcher.php
@@ -4,7 +4,7 @@
// phpcs:disable Magento2.CodeAnalysis.EmptyBlock
-use JustBetter\Sentry\Helper\Data as SenteryHelper;
+use JustBetter\Sentry\Helper\Data as SentryHelper;
use JustBetter\Sentry\Model\ReleaseIdentifier;
use JustBetter\Sentry\Model\SentryInteraction;
use JustBetter\Sentry\Model\SentryPerformance;
@@ -12,11 +12,12 @@
use Magento\Framework\DataObject;
use Magento\Framework\DataObjectFactory;
use Magento\Framework\Event\ManagerInterface as EventManagerInterface;
+use Throwable;
class GlobalExceptionCatcher
{
public function __construct(
- protected SenteryHelper $sentryHelper,
+ private SentryHelper $sentryHelper,
private ReleaseIdentifier $releaseIdentifier,
private SentryInteraction $sentryInteraction,
private EventManagerInterface $eventManager,
@@ -71,22 +72,12 @@ public function aroundLaunch(AppInterface $subject, callable $proceed)
try {
return $response = $proceed();
- } catch (\Throwable $ex) {
- try {
- if ($this->sentryHelper->shouldCaptureException($ex)) {
- $this->sentryInteraction->captureException($ex);
- }
- } catch (\Throwable $bigProblem) {
- // do nothing if sentry fails
- }
-
- throw $ex;
+ } catch (Throwable $exception) {
+ $this->sentryInteraction->captureException($exception);
+
+ throw $exception;
} finally {
- try {
- $this->sentryPerformance->finishTransaction($response ?? 500);
- } catch (\Throwable $bigProblem) {
- // do nothing if sentry fails
- }
+ $this->sentryPerformance->finishTransaction($response ?? 500);
}
}
}
diff --git a/Plugin/LoggerProxyPlugin.php b/Plugin/LoggerProxyPlugin.php
deleted file mode 100644
index f1293ee..0000000
--- a/Plugin/LoggerProxyPlugin.php
+++ /dev/null
@@ -1,44 +0,0 @@
-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/Profiling/DbQueryLoggerPlugin.php b/Plugin/Profiling/DbQueryLoggerPlugin.php
new file mode 100644
index 0000000..fae99d1
--- /dev/null
+++ b/Plugin/Profiling/DbQueryLoggerPlugin.php
@@ -0,0 +1,35 @@
+tracingDto = SentryPerformance::traceStart(
+ SpanContext::make()
+ ->setOp('db.sql.query')
+ ->setStartTimestamp(microtime(true))
+ );
+ }
+
+ public function beforeLogStats(LoggerInterface $subject, $type, $sql, $bind = [], $result = null): void
+ {
+ if ($this->tracingDto === null) {
+ return;
+ }
+
+ $this->tracingDto->getSpan()?->setDescription($sql);
+ SentryPerformance::traceEnd($this->tracingDto);
+ $this->tracingDto = null;
+ }
+}
diff --git a/Plugin/Profiling/EventManagerPlugin.php b/Plugin/Profiling/EventManagerPlugin.php
index 593939b..b97159e 100644
--- a/Plugin/Profiling/EventManagerPlugin.php
+++ b/Plugin/Profiling/EventManagerPlugin.php
@@ -4,16 +4,13 @@
namespace JustBetter\Sentry\Plugin\Profiling;
+use JustBetter\Sentry\Model\SentryPerformance;
use Magento\Framework\Event\ConfigInterface;
use Magento\Framework\Event\ManagerInterface;
-use Sentry\SentrySdk;
-use Sentry\Tracing\Span;
use Sentry\Tracing\SpanContext;
class EventManagerPlugin
{
- private const SPAN_STORAGE_KEY = '__sentry_profiling_span';
-
public function __construct(
private ConfigInterface $config,
private array $excludePatterns = []
@@ -24,29 +21,33 @@ public function __construct(
'_load_after$',
'_$',
'^view_block_abstract_',
+ '^core_layout_render_e',
], $excludePatterns);
}
- public function beforeDispatch(ManagerInterface $subject, string|null $eventName, array $data = []): array
+ private function _canTrace(string|null $eventName): bool
{
if ($eventName === null) {
- return [$eventName, $data];
- }
-
- $parent = SentrySdk::getCurrentHub()->getSpan();
- if ($parent === null) {
- // can happen if no transaction has been started
- return [$eventName, $data];
+ return false;
}
foreach ($this->excludePatterns as $excludePattern) {
if (preg_match('/'.$excludePattern.'/i', $eventName)) {
- return [$eventName, $data];
+ return false;
}
}
if ($this->config->getObservers(mb_strtolower($eventName)) === []) {
- return [$eventName, $data];
+ return false;
+ }
+
+ return true;
+ }
+
+ public function aroundDispatch(ManagerInterface $subject, callable $callable, string $eventName, array $data = []): mixed
+ {
+ if (!$this->_canTrace($eventName)) {
+ return $callable($eventName, $data);
}
$context = SpanContext::make()
@@ -56,25 +57,12 @@ public function beforeDispatch(ManagerInterface $subject, string|null $eventName
'event.name' => $eventName,
]);
- $span = $parent->startChild($context);
- SentrySdk::getCurrentHub()->setSpan($span);
- $data[self::SPAN_STORAGE_KEY] = [$span, $parent];
-
- return [$eventName, $data];
- }
-
- public function afterDispatch(ManagerInterface $subject, $result, string $name, array $data = []): void
- {
- /** @var Span[]|null $span */
- $span = $data[self::SPAN_STORAGE_KEY] ?? null;
- if (!is_array($span)) {
- return;
- }
-
- if (isset($span[0])) {
- $span[0]->finish();
+ $tracingDto = SentryPerformance::traceStart($context);
- SentrySdk::getCurrentHub()->setSpan($span[1]);
+ try {
+ return $callable($eventName, $data);
+ } finally {
+ SentryPerformance::traceEnd($tracingDto);
}
}
}
diff --git a/Plugin/Profiling/TemplatePlugin.php b/Plugin/Profiling/TemplatePlugin.php
index 831b658..b3b9a25 100644
--- a/Plugin/Profiling/TemplatePlugin.php
+++ b/Plugin/Profiling/TemplatePlugin.php
@@ -4,48 +4,36 @@
namespace JustBetter\Sentry\Plugin\Profiling;
+use JustBetter\Sentry\Model\SentryPerformance;
use Magento\Framework\View\Element\Template;
-use Sentry\SentrySdk;
-use Sentry\Tracing\Span;
use Sentry\Tracing\SpanContext;
class TemplatePlugin
{
- private const SPAN_STORAGE_KEY = '__sentry_profiling_span_fetch_view';
-
- public function beforeFetchView(Template $subject, $fileName): void
+ public function aroundFetchView(Template $subject, callable $callable, $fileName): mixed
{
- $parentSpan = SentrySdk::getCurrentHub()->getSpan();
- if (!$parentSpan) {
- return;
+ $tags = [];
+ if (!empty($subject->getModuleName())) {
+ $tags['magento.module'] = $subject->getModuleName();
}
$context = SpanContext::make()
->setOp('template.render')
->setDescription($subject->getNameInLayout() ?: $fileName)
+ ->setTags($tags)
->setData([
'block_name' => $subject->getNameInLayout(),
'block_class' => get_class($subject),
'module' => $subject->getModuleName(),
'template' => $fileName,
]);
- $span = $parentSpan->startChild($context);
-
- SentrySdk::getCurrentHub()->setSpan($span);
- $subject->setData(self::SPAN_STORAGE_KEY, [$span, $parentSpan]);
- }
+ $tracingDto = SentryPerformance::traceStart($context);
- public function afterFetchView(Template $subject, $result, $fileName)
- {
- $span = $subject->getData(self::SPAN_STORAGE_KEY) ?: [];
-
- if ($span[0] instanceof Span) {
- $span[0]->finish();
-
- SentrySdk::getCurrentHub()->setSpan($span[1]);
+ try {
+ return $callable($fileName);
+ } finally {
+ SentryPerformance::traceEnd($tracingDto);
}
-
- return $result;
}
}
diff --git a/Plugin/SampleRequest.php b/Plugin/SampleRequest.php
index 5e45784..5f30bff 100644
--- a/Plugin/SampleRequest.php
+++ b/Plugin/SampleRequest.php
@@ -7,7 +7,7 @@
use Magento\Framework\App\ResponseInterface;
/**
- * Plugin to sample request and send them to Sentry
+ * Plugin to sample request and send them to Sentry.
*/
class SampleRequest
{
diff --git a/etc/di.xml b/etc/di.xml
index 952ba3c..c25afec 100755
--- a/etc/di.xml
+++ b/etc/di.xml
@@ -35,11 +35,14 @@
sortOrder="10" disabled="false"/>
-
+
+
+
+
diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml
index 0f98aa4..fbcf889 100644
--- a/etc/frontend/di.xml
+++ b/etc/frontend/di.xml
@@ -8,11 +8,4 @@
/>
-
-
-
-