Completed
Push — log_trace_for_un_cached ( d20892...676aba )
by André
47:57 queued 29:23
created

PersistenceLogger::getSimpleCallTrace()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
nc 6
nop 1
dl 0
loc 24
rs 8.6026
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * File containing the Persistence Cache SPI logger class.
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\Publish\Core\Persistence\Cache;
10
11
/**
12
 * Log un-cached use of SPI Persistence.
13
 *
14
 * Stops logging details when reaching $maxLogCalls to conserve memory use
15
 */
16
class PersistenceLogger
17
{
18
    const NAME = 'PersistenceLogger';
19
20
    /**
21
     * @var int
22
     */
23
    protected $count = 0;
24
25
    /**
26
     * @var bool
27
     */
28
    protected $logCalls = true;
29
30
    /**
31
     * @var array
32
     */
33
    protected $calls = array();
34
35
    /**
36
     * @var array
37
     */
38
    protected $unCachedHandlers = array();
39
40
    /**
41
     * @param bool $logCalls Flag to enable logging of calls or not, should be disabled in prod
42
     */
43
    public function __construct($logCalls = true)
44
    {
45
        $this->logCalls = $logCalls;
46
    }
47
48
    /**
49
     * Log SPI calls with method name and arguments until $maxLogCalls is reached.
50
     *
51
     * @param string $method
52
     * @param array $arguments
53
     */
54
    public function logCall($method, array $arguments = array())
55
    {
56
        ++$this->count;
57
        if ($this->logCalls) {
58
            $this->calls[] = array(
59
                'method' => $method,
60
                'arguments' => $arguments,
61
                'trace' => $this->getSimpleCallTrace(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 7)),
62
            );
63
        }
64
    }
65
66
    private function getSimpleCallTrace(array $backtrace) :array
67
    {
68
        $calls = [];
69
        foreach (array_slice($backtrace, 2) as $call) {
70
            if (isset($call['class']) && strpos($call['class'], '\\') === false) {
71
                // skip if class has no namspace (in the slice of call graph here that would be a Symfony lazy proxy)
72
                continue;
73
            }
74
75
            if (isset($call['class'])) {
76
                $calls[] = $call['class'] ?? '' . $call['type'] . $call['function']. '()';
77
            } else {
78
                $calls[] = $call['function']. '()';
79
            }
80
81
82
            // Break out as soon as we have listed a class outside of kernel
83
            if (isset($call['class']) && strpos($call['class'], 'eZ\\Publish\\Core\\') !== 0) {
84
                break;
85
            }
86
        }
87
88
        return $calls;
89
    }
90
91
    /**
92
     * Log uncached handler being loaded.
93
     *
94
     * @param string $handler
95
     */
96
    public function logUnCachedHandler($handler)
97
    {
98
        if (!isset($this->unCachedHandlers[$handler])) {
99
            $this->unCachedHandlers[$handler] = 0;
100
        }
101
        ++$this->unCachedHandlers[$handler];
102
    }
103
104
    /**
105
     * @return string
106
     */
107
    public function getName()
108
    {
109
        return self::NAME;
110
    }
111
112
    /**
113
     * @return int
114
     */
115
    public function getCount()
116
    {
117
        return $this->count;
118
    }
119
120
    /**
121
     * @return bool
122
     */
123
    public function isCallsLoggingEnabled()
124
    {
125
        return $this->logCalls;
126
    }
127
128
    /**
129
     * @return array
130
     */
131
    public function getCalls()
132
    {
133
        return $this->calls;
134
    }
135
136
    /**
137
     * @return array
138
     */
139
    public function getLoadedUnCachedHandlers()
140
    {
141
        return $this->unCachedHandlers;
142
    }
143
}
144