From 2b7d5e382f86ba26bbcb98e8a0cdf79b9d0a2c03 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Wed, 20 Jan 2016 12:09:39 +0100 Subject: [PATCH] Add call summaries by type and key in cache profiler --- .../Subscriber/CacheStatisticsSubscriber.php | 15 +++++ .../Core/Profiler/CacheDataCollector.php | 11 ++++ .../Phrasea/Core/Profiler/TraceableCache.php | 35 ++++++++++- .../Provider/WebProfilerServiceProvider.php | 2 +- templates-profiler/cache.html.twig | 63 +++++++++++++++++++ 5 files changed, 124 insertions(+), 2 deletions(-) diff --git a/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php b/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php index a40e70f20d..ab39cc8dd5 100644 --- a/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php +++ b/lib/Alchemy/Phrasea/Core/Event/Subscriber/CacheStatisticsSubscriber.php @@ -42,6 +42,21 @@ class CacheStatisticsSubscriber implements EventSubscriberInterface return '[ root ]'; } + public function getCallSummary() + { + if ($this->cache instanceof TraceableCache) { + return $this->cache->getSummary(); + } + + return [ + 'calls' => 0, + 'hits' => 0, + 'misses' => 0, + 'calls_by_type' => [], + 'calls_by_key' => [] + ]; + } + public function getCalls() { if ($this->cache instanceof TraceableCache) { diff --git a/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php b/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php index 316244783d..d0d6bdc6a8 100644 --- a/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php +++ b/lib/Alchemy/Phrasea/Core/Profiler/CacheDataCollector.php @@ -35,6 +35,11 @@ class CacheDataCollector implements DataCollectorInterface */ private $calls = []; + /** + * @var array + */ + private $callSummary; + /** * @param CacheStatisticsSubscriber $cacheStatisticsSubscriber */ @@ -73,6 +78,7 @@ class CacheDataCollector implements DataCollectorInterface ); $this->calls = $this->statsListener->getCalls(); + $this->callSummary = $this->statsListener->getCallSummary(); } /** @@ -96,6 +102,11 @@ class CacheDataCollector implements DataCollectorInterface return $this->calls; } + public function getCallSummary() + { + return $this->callSummary; + } + /** * @return CacheProfileSummary */ diff --git a/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php b/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php index 2781fefa3a..da3499a32a 100644 --- a/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php +++ b/lib/Alchemy/Phrasea/Core/Profiler/TraceableCache.php @@ -24,7 +24,15 @@ class TraceableCache implements Cache, PhraseaCache */ private $calls = []; - /** + private $summary = [ + 'calls' => 0, + 'hits' => 0, + 'misses' => 0, + 'calls_by_type' => [], + 'calls_by_key' => [], + ]; + + /*s* * @param PhraseaCache $cache */ public function __construct(PhraseaCache $cache) @@ -34,12 +42,29 @@ class TraceableCache implements Cache, PhraseaCache private function collect($type, $id, $hit = true, $result = null) { + $this->summary['calls']++; + $this->summary['hits'] += $hit ? 1 : 0; + $this->summary['misses'] += $hit ? 0 : 1; + + if (! array_key_exists($type, $this->summary['calls_by_type'])) { + $this->summary['calls_by_type'][$type] = 0; + } + + $this->summary['calls_by_type'][$type]++; + + if (! array_key_exists($id, $this->summary['calls_by_key'])) { + $this->summary['calls_by_key'][$id] = 0; + } + + $this->summary['calls_by_key'][$id]++; + $this->calls[] = [ 'type' => $type, 'key' => $id, 'result' => $result, 'hit' => (bool) $hit ]; + } /** @@ -58,6 +83,14 @@ class TraceableCache implements Cache, PhraseaCache return $this->calls; } + /** + * @return array + */ + public function getSummary() + { + return $this->summary; + } + /** * Fetches an entry from the cache. * diff --git a/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php b/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php index feb92a1ce8..d6fd0d25f8 100644 --- a/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php +++ b/lib/Alchemy/Phrasea/Core/Provider/WebProfilerServiceProvider.php @@ -75,7 +75,7 @@ class WebProfilerServiceProvider implements ServiceProviderInterface return new CacheStatisticsSubscriber($app['cache']); }); - $app->share($app->extend('data_collectors', function ($collectors) use ($app) { + $app['data_collectors'] = $app->share($app->extend('data_collectors', function ($collectors) use ($app) { $collectors['db'] = $app->share(function ($app) { /** @var DoctrineDataCollector $collector */ $collector = $app['data_collectors.doctrine']; diff --git a/templates-profiler/cache.html.twig b/templates-profiler/cache.html.twig index 8723a41d23..dcc22a63ad 100644 --- a/templates-profiler/cache.html.twig +++ b/templates-profiler/cache.html.twig @@ -80,6 +80,69 @@ +

Hit miss summary

+ + + + + + + + + + + + + + + + + + + + + + +
Call statValue
Hits{{ collector.callSummary['hits'] }}
Misses{{ collector.callSummary['misses'] }}
Total{{ collector.callSummary['calls'] }}
+ +

Calls by type summary

+ + + + + + + + + + {% for callType, count in collector.callSummary['calls_by_type'] %} + + + + + {% endfor %} + +
OperationCount
{{ callType }}{{ count }}
+ +

Calls by key summary

+ + + + + + + + + + {% for callKey, count in collector.callSummary['calls_by_key'] %} + + + + + {% endfor %} + +
OperationCount
{{ callKey }}{{ count }}
+

Call list