ElasticsearchProfiler   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 114
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 3
dl 0
loc 114
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A addLogger() 0 4 1
A setIndexes() 0 4 1
A collect() 0 12 4
A reset() 0 6 1
A getTime() 0 4 1
A getQueryCount() 0 4 1
A getQueries() 0 4 1
A getIndexes() 0 4 1
A getName() 0 4 1
A handleRecords() 0 15 4
A addQuery() 0 14 2
A getRoute() 0 6 2
1
<?php
2
3
/*
4
 * This file is part of the ONGR package.
5
 *
6
 * (c) NFQ Technologies UAB <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace ONGR\ElasticsearchBundle\Profiler;
13
14
use Monolog\Logger;
15
use ONGR\ElasticsearchBundle\Profiler\Handler\CollectionHandler;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpFoundation\Response;
18
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
19
20
/**
21
 * Data collector for profiling elasticsearch bundle.
22
 */
23
class ElasticsearchProfiler implements DataCollectorInterface
24
{
25
    const UNDEFINED_ROUTE = 'undefined_route';
26
27
    private $loggers = [];
28
    private $queries = [];
29
    private $count = 0;
30
    private $time = .0;
31
    private $indexes = [];
32
33
    public function addLogger(Logger $logger)
34
    {
35
        $this->loggers[] = $logger;
36
    }
37
38
    public function setIndexes(array $indexes): void
39
    {
40
        $this->indexes = $indexes;
41
    }
42
43
    public function collect(Request $request, Response $response, \Throwable $exception = null)
44
    {
45
        /** @var Logger $logger */
46
        foreach ($this->loggers as $logger) {
47
            foreach ($logger->getHandlers() as $handler) {
48
                if ($handler instanceof CollectionHandler) {
49
                    $this->handleRecords($this->getRoute($request), $handler->getRecords());
50
                    $handler->clearRecords();
51
                }
52
            }
53
        }
54
    }
55
56
    public function reset()
57
    {
58
        $this->queries = [];
59
        $this->count = 0;
60
        $this->time = 0;
61
    }
62
63
    public function getTime(): float
64
    {
65
        return round($this->time * 1000, 2);
66
    }
67
68
    public function getQueryCount(): int
69
    {
70
        return $this->count;
71
    }
72
73
    /**
74
     * Returns information about executed queries.
75
     *
76
     * Eg. keys:
77
     *      'body'    - Request body.
78
     *      'method'  - HTTP method.
79
     *      'uri'     - Uri request was sent.
80
     *      'time'    - Time client took to respond.
81
     *
82
     * @return array
83
     */
84
    public function getQueries(): array
85
    {
86
        return $this->queries;
87
    }
88
89
    public function getIndexes(): array
90
    {
91
        return $this->indexes;
92
    }
93
94
    public function getName()
95
    {
96
        return 'ongr.profiler';
97
    }
98
99
    private function handleRecords($route, $records)
100
    {
101
        $this->count += count($records) / 2;
102
        $queryBody = '';
103
        foreach ($records as $record) {
104
            // First record will never have context.
105
            if (!empty($record['context'])) {
106
                $this->time += $record['context']['duration'];
107
                $this->addQuery($route, $record, $queryBody);
108
            } else {
109
                $position = strpos($record['message'], ' -d');
110
                $queryBody = $position !== false ? substr($record['message'], $position + 3) : '';
111
            }
112
        }
113
    }
114
115
    private function addQuery($route, $record, $queryBody)
116
    {
117
        parse_str(parse_url($record['context']['uri'], PHP_URL_QUERY), $httpParameters);
118
        $body = json_decode(trim($queryBody, " '\r\t\n"));
119
        $this->queries[$route][] = array_merge(
120
            [
121
                'body' => $body !== null ? json_encode($body, JSON_PRETTY_PRINT) : '',
122
                'method' => $record['context']['method'],
123
                'httpParameters' => $httpParameters,
124
                'time' => $record['context']['duration'] * 1000,
125
            ],
126
            array_diff_key(parse_url($record['context']['uri']), array_flip(['query']))
127
        );
128
    }
129
130
    private function getRoute(Request $request)
131
    {
132
        $route = $request->attributes->get('_route');
133
134
        return empty($route) ? self::UNDEFINED_ROUTE : $route;
135
    }
136
}
137