Completed
Push — in-memory-cache2 ( f7b62a...ac5a8f )
by André
30:41
created

PersistenceCacheCollector::getCallData()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 4
nop 1
dl 0
loc 38
rs 9.312
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the eZ Publish Kernel package.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 */
9
namespace eZ\Bundle\EzPublishDebugBundle\Collector;
10
11
use eZ\Publish\Core\Persistence\Cache\PersistenceLogger;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpFoundation\Response;
14
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
15
16
/**
17
 * Data collector listing SPI cache calls.
18
 */
19
class PersistenceCacheCollector extends DataCollector
20
{
21
    /**
22
     * @var PersistenceLogger
23
     */
24
    private $logger;
25
26
    public function __construct(PersistenceLogger $logger)
27
    {
28
        $this->logger = $logger;
29
    }
30
31
    public function collect(Request $request, Response $response, \Exception $exception = null)
32
    {
33
        $this->data = [
34
            'stats' => $this->logger->getStats(),
35
            'calls_logging_enabled' => $this->logger->isCallsLoggingEnabled(),
36
            'calls' => $this->logger->getCalls(),
37
            'cached' => $this->logger->getCached(),
38
            'handlers' => $this->logger->getLoadedUnCachedHandlers(),
39
        ];
40
    }
41
42
    public function getName()
43
    {
44
        return 'ezpublish.debug.persistence';
45
    }
46
47
    /**
48
     * Returns call count.
49
     *
50
     * @deprecaterd since 7.5, use getStats().
51
     *
52
     * @return int
53
     */
54
    public function getCount()
55
    {
56
        return $this->data['stats']['calls'] + $this->data['stats']['misses'];
57
    }
58
59
    /**
60
     * Returns stats on Persistance cache usage.
61
     *
62
     * @since 7.5
63
     *
64
     * @return int[<string>]
0 ignored issues
show
Documentation introduced by
The doc-type int[<string>] could not be parsed: Expected "]" at position 2, but found "<". (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
65
     */
66
    public function getStats()
67
    {
68
        return $this->data['stats'];
69
    }
70
71
    /**
72
     * Returns flag to indicate if logging of calls is enabled or not.
73
     *
74
     * Typically not enabled in prod.
75
     *
76
     * @return bool
77
     */
78
    public function getCallsLoggingEnabled()
79
    {
80
        return $this->data['calls_logging_enabled'];
81
    }
82
83
    /**
84
     * Returns all calls.
85
     *
86
     * @return array
87
     */
88
    public function getCalls()
89
    {
90
        return $this->getCallData(array_merge($this->data['calls'], $this->data['cached']));
91
    }
92
93
    private function getCallData(array $data): array
94
    {
95
        if (empty($data)) {
96
            return [];
97
        }
98
99
        $calls = $count = [];
100
        foreach ($data as $call) {
101
            $callArguments = $this->simplifyCallArguments($call['arguments']);
102
            $hash = hash('md5', $call['method'] . $callArguments);
103
            if (isset($calls[$hash])) {
104
                $calls[$hash]['traces'][$call['type']][] = implode(', ', $call['trace']);
105
                ++$calls[$hash]['count'];
106
                ++$count[$hash];
107
108
                continue;
109
            }
110
111
            list($class, $method) = explode('::', $call['method']);
112
            $namespace = explode('\\', $class);
113
            $class = array_pop($namespace);
114
            $calls[$hash] = [
115
                'namespace' => $namespace,
116
                'class' => $class,
117
                'method' => $method,
118
                'arguments' => $callArguments,
119
                'traces' => [],
120
                'count' => 1,
121
            ];
122
            $calls[$hash]['traces'][$call['type']][] = implode(', ', $call['trace']);
123
            $count[$hash] = 1;
124
        }
125
        unset($data);
126
127
        array_multisort($count, SORT_DESC, $calls);
128
129
        return $calls;
130
    }
131
132
    private function simplifyCallArguments(array $arguments): string
133
    {
134
        $string = '';
135
        foreach ($arguments as $key => $value) {
136
            if (!empty($string)) {
137
                $string .= ', ';
138
            }
139
140
            if (!is_numeric($key)) {
141
                $string .= $key . ':';
142
            }
143
144
            if (is_array($value)) {
145
                $string .= '[' . implode(',', $value) . ']';
146
            } else {
147
                $string .= $value;
148
            }
149
        }
150
151
        return $string;
152
    }
153
154
    /**
155
     * Returns un cached handlers being loaded.
156
     *
157
     * @return array
158
     */
159
    public function getHandlers()
160
    {
161
        $handlers = [];
162
        foreach ($this->data['handlers'] as $handler => $count) {
163
            list($class, $method) = explode('::', $handler);
164
            unset($class);
165
            $handlers[$method] = $method . '(' . $count . ')';
166
        }
167
168
        return $handlers;
169
    }
170
171
    /**
172
     * Returns un cached handlers being loaded.
173
     *
174
     * @return array
175
     */
176
    public function getHandlersCount()
177
    {
178
        return array_sum($this->data['handlers']);
179
    }
180
}
181