Skip to content

Commit

Permalink
Merge pull request #95 from Sebobo/feature/metrics-by-segment
Browse files Browse the repository at this point in the history
FEATURE: Show render metrics for cached elements
  • Loading branch information
johannessteu authored Aug 28, 2020
2 parents 2e6e390 + 1abce77 commit bf5477b
Show file tree
Hide file tree
Showing 4 changed files with 151 additions and 3 deletions.
4 changes: 2 additions & 2 deletions Classes/Aspect/CollectDebugInformationAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ public function addDebugValues(JoinPointInterface $joinPoint): string
*/
public function startSqlLogging(\Neos\Flow\AOP\JoinPointInterface $joinPoint): void
{
$this->sqlLoggingStack = new DebugStack();
$this->entityManager->getConfiguration()->setSQLLogger($this->sqlLoggingStack);
$this->sqlLoggingStack = new DebugStack();
$this->entityManager->getConfiguration()->setSQLLogger($this->sqlLoggingStack);
}

/**
Expand Down
13 changes: 12 additions & 1 deletion Classes/Aspect/ContentCacheSegmentAspect.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Neos\Fusion\Core\Cache\ContentCache;
use Neos\Fusion\FusionObjects\AbstractFusionObject;
use Neos\Utility\ObjectAccess;
use t3n\Neos\Debug\Service\RenderTimer;

/**
* @Flow\Scope("singleton")
Expand All @@ -46,6 +47,13 @@ class ContentCacheSegmentAspect
*/
protected $interceptedFusionObject;

/**
* @Flow\Inject
*
* @var RenderTimer
*/
protected $renderTimer;

public function injectContentCache(ContentCache $contentCache): void
{
$randomCacheMarker = ObjectAccess::getProperty($contentCache, 'randomCacheMarker', true);
Expand All @@ -65,10 +73,13 @@ public function debuggingActive(): void
public function wrapCachedSegment(JoinPointInterface $joinPoint): string
{
$segment = $joinPoint->getAdviceChain()->proceed($joinPoint);
$fusionPath = $joinPoint->getMethodArgument('fusionPath');
$renderTime = $this->renderTimer->stop($fusionPath);

return $this->renderCacheInfoIntoSegment($segment, [
'mode' => static::MODE_CACHED,
'fusionPath' => $joinPoint->getMethodArgument('fusionPath'),
'fusionPath' => $fusionPath,
'renderMetrics' => $renderTime,
'entryIdentifier' => $this->interceptedCacheEntryValues,
'entryTags' => $joinPoint->getMethodArgument('tags'),
'lifetime' => $joinPoint->getMethodArgument('lifetime')
Expand Down
57 changes: 57 additions & 0 deletions Classes/Aspect/RuntimeTracingAspect.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace t3n\Neos\Debug\Aspect;

/**
* This file is part of the t3n.Neos.Debugger package.
*
* (c) 2019 yeebase media GmbH
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Neos\Flow\Annotations as Flow;
use Neos\Flow\Aop\JoinPointInterface;
use t3n\Neos\Debug\Service\RenderTimer;

/**
* @Flow\Aspect
* @Flow\Scope("singleton")
*/
class RuntimeTracingAspect
{
/**
* @Flow\Inject
*
* @var RenderTimer
*/
protected $renderTimer;

/**
* @Flow\Pointcut("setting(t3n.Neos.Debug.enabled)")
*/
public function debuggingActive(): void
{
}

/**
* @Flow\Before("method(Neos\Fusion\Core\Cache\RuntimeContentCache->enter()) && t3n\Neos\Debug\Aspect\RuntimeTracingAspect->debuggingActive")
*/
public function onEnter(JoinPointInterface $joinPoint): void
{
$configuration = $joinPoint->getMethodArgument('configuration');
$fusionPath = $joinPoint->getMethodArgument('fusionPath');

$cacheMode = $configuration['mode'] ?? null;

if (! $cacheMode) {
return;
}

$this->renderTimer->start($fusionPath);
}
}
80 changes: 80 additions & 0 deletions Classes/Service/RenderTimer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace t3n\Neos\Debug\Service;

/**
* This file is part of the t3n.Neos.Debugger package.
*
* (c) 2019 yeebase media GmbH
*
* This package is Open Source Software. For the full copyright and license
* information, please view the LICENSE file which was distributed with this
* source code.
*/

use Doctrine\ORM\EntityManagerInterface;
use Neos\Flow\Annotations as Flow;
use t3n\Neos\Debug\Logging\DebugStack;

/**
* @Flow\Scope("singleton")
*/
class RenderTimer
{
/**
* @Flow\Inject()
*
* @var EntityManagerInterface
*/
protected $entityManager;

/**
* @var mixed[]
*/
protected $renderMetrics = [];

/**
* Starts a render timer for a certain fusion path
*/
public function start(string $fusionPath): void
{
$sqlLoggingStack = $this->entityManager->getConfiguration()->getSQLLogger();
$queryCount = $sqlLoggingStack instanceof DebugStack ? $sqlLoggingStack->queryCount : 0;

$this->renderMetrics[$fusionPath] = [
'startRenderAt' => $this->ts(),
'sqlQueryCount' => $queryCount,
];
}

/**
* Return current microtime in ms
*/
private function ts(): float
{
return microtime(true) * 1000;
}

/**
* Stops the timer and returns the computed values
*
* @return mixed[]|null
*/
public function stop(string $fusionPath): ?array
{
if (! array_key_exists($fusionPath, $this->renderMetrics)) {
return null;
}

$metrics = $this->renderMetrics[$fusionPath];
$sqlLoggingStack = $this->entityManager->getConfiguration()->getSQLLogger();
$queryCount = $sqlLoggingStack instanceof DebugStack ? $sqlLoggingStack->queryCount : 0;

return [
'renderTime' => round($this->ts() - $metrics['startRenderAt'], 2) . ' ms',
'sqlQueryCount' => $queryCount - $metrics['sqlQueryCount'],
];
}
}

0 comments on commit bf5477b

Please sign in to comment.