Skip to content

Commit d5f2c42

Browse files
committed
Improve the profiler and data collector
Using Symfonys event dispatcher Created a service for connection manager Updated the DataCollector and profiler page Using a LoggerSubscriber
1 parent f86c124 commit d5f2c42

File tree

9 files changed

+273
-220
lines changed

9 files changed

+273
-220
lines changed

Collector/DebugLogger.php

Lines changed: 0 additions & 83 deletions
This file was deleted.

Collector/Neo4jDataCollector.php

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,61 +4,66 @@
44

55
namespace Neo4j\Neo4jBundle\Collector;
66

7+
use GraphAware\Neo4j\Client\Connection\ConnectionManager;
78
use Symfony\Component\HttpFoundation\Request;
89
use Symfony\Component\HttpFoundation\Response;
910
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
1011

1112
/**
12-
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
13+
* @author Xavier Coureau <xavier@pandawan-technology.com>
1314
*/
1415
final class Neo4jDataCollector extends DataCollector
1516
{
16-
private $logger;
17+
/**
18+
* @var QueryLogger
19+
*/
20+
private $queryLogger;
1721

18-
public function __construct(DebugLogger $logger)
22+
public function __construct(QueryLogger $logger)
1923
{
20-
$this->logger = $logger;
24+
$this->queryLogger = $logger;
2125
}
2226

2327
/**
2428
* {@inheritdoc}
2529
*/
2630
public function collect(Request $request, Response $response, \Exception $exception = null)
2731
{
32+
$this->data['nb_queries'] = count($this->queryLogger);
33+
$this->data['statements'] = $this->queryLogger->getStatements();
34+
$this->data['time'] = $this->queryLogger->getElapsedTime();
2835
}
2936

3037
/**
31-
* @return array|\GraphAware\Common\Cypher\StatementInterface[]
38+
* @return int
3239
*/
33-
public function getStatements()
40+
public function getQueryCount()
3441
{
35-
return $this->logger->getStatements();
42+
return $this->data['nb_queries'];
3643
}
3744

3845
/**
39-
* @return array|\GraphAware\Common\Result\Result[]
46+
* @return QueryLogger
4047
*/
41-
public function getResults()
48+
public function getStatements()
4249
{
43-
return $this->logger->getResults();
50+
return $this->data['statements'];
4451
}
4552

4653
/**
47-
* @return array|\GraphAware\Neo4j\Client\Exception\Neo4jExceptionInterface[]
54+
* @return float
4855
*/
49-
public function getExceptions()
56+
public function getTime()
5057
{
51-
return $this->logger->getExceptions();
58+
return $this->data['time'];
5259
}
5360

5461
/**
55-
* @param int $idx
56-
*
57-
* @return bool
62+
* @return float
5863
*/
59-
public function wasSuccessful(int $idx): bool
64+
public function getTimeForQuery()
6065
{
61-
return isset($this->logger->getResults()[$idx]);
66+
return $this->data['time'];
6267
}
6368

6469
/**
@@ -68,20 +73,4 @@ public function getName()
6873
{
6974
return 'neo4j';
7075
}
71-
72-
/**
73-
* {@inheritdoc}
74-
*/
75-
public function serialize()
76-
{
77-
return serialize($this->logger);
78-
}
79-
80-
/**
81-
* {@inheritdoc}
82-
*/
83-
public function unserialize($data)
84-
{
85-
$this->logger = unserialize($data);
86-
}
8776
}

Collector/QueryLogger.php

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Neo4j\Neo4jBundle\Collector;
6+
7+
use GraphAware\Common\Cypher\StatementInterface;
8+
use GraphAware\Common\Result\StatementResult as StatementResultInterface;
9+
10+
/**
11+
* @author Xavier Coureau <[email protected]>
12+
*/
13+
class QueryLogger implements \Countable
14+
{
15+
/**
16+
* @var int
17+
*/
18+
private $nbQueries = 0;
19+
20+
/**
21+
* @var array
22+
*/
23+
private $statements = [];
24+
25+
/**
26+
* @var array
27+
*/
28+
private $statementsHash = [];
29+
30+
/**
31+
* @param StatementInterface $statement
32+
*/
33+
public function record(StatementInterface $statement)
34+
{
35+
$statementText = $statement->text();
36+
$statementParams = json_encode($statement->parameters());
37+
$tag = $statement->getTag() ?: -1;
38+
39+
if (isset($this->statementsHash[$statementText][$statementParams][$tag])) {
40+
return;
41+
}
42+
43+
$idx = $this->nbQueries++;
44+
$this->statements[$idx]['start_time'] = microtime(true) * 1000;
45+
$this->statementsHash[$statementText][$statementParams][$tag] = $idx;
46+
}
47+
48+
/**
49+
* @param StatementResultInterface $statementResult
50+
*/
51+
public function finish(StatementResultInterface $statementResult)
52+
{
53+
$statement = $statementResult->statement();
54+
$statementText = $statement->text();
55+
$statementParams = $statement->parameters();
56+
$encodedParameters = json_encode($statementParams);
57+
$tag = $statement->getTag() ?: -1;
58+
59+
if (!isset($this->statementsHash[$statementText][$encodedParameters][$tag])) {
60+
$idx = $this->nbQueries++;
61+
$this->statements[$idx]['start_time'] = null;
62+
$this->statementsHash[$idx] = $idx;
63+
} else {
64+
$idx = $this->statementsHash[$statementText][$encodedParameters][$tag];
65+
}
66+
67+
$this->statements[$idx] += [
68+
'end_time' => microtime(true) * 1000,
69+
'query' => $statementText,
70+
'parameters' => $statementParams,
71+
'tag' => $statement->getTag(),
72+
'nb_results' => $statementResult->size(),
73+
];
74+
}
75+
76+
/**
77+
* {@inheritdoc}
78+
*/
79+
public function count()
80+
{
81+
return $this->nbQueries;
82+
}
83+
84+
/**
85+
* @return array[]
86+
*/
87+
public function getStatements()
88+
{
89+
return $this->statements;
90+
}
91+
92+
/**
93+
* @return array
94+
*/
95+
public function getStatementsHash()
96+
{
97+
return $this->statementsHash;
98+
}
99+
100+
/**
101+
* @return int
102+
*/
103+
public function getElapsedTime()
104+
{
105+
$time = 0;
106+
107+
foreach ($this->statements as $statement) {
108+
if (!isset($statement['start_time'], $statement['end_time'])) {
109+
continue;
110+
}
111+
112+
$time += $statement['end_time'] - $statement['start_time'];
113+
}
114+
115+
return $time;
116+
}
117+
}

DependencyInjection/Neo4jExtension.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ public function load(array $configs, ContainerBuilder $container)
4242
// Configure toolbar
4343
if ($this->isConfigEnabled($container, $config['profiling'])) {
4444
$loader->load('data-collector.xml');
45-
46-
$container->getDefinition('neo4j.factory.client')
47-
->replaceArgument(0, new Reference('neo4j.client_logger'));
4845
}
4946
}
5047

@@ -64,7 +61,6 @@ private function handleClients(array &$config, ContainerBuilder $container): arr
6461
$serviceIds = [];
6562
foreach ($config['clients'] as $name => $data) {
6663
$serviceIds[$name] = $serviceId = sprintf('neo4j.client.%s', $name);
67-
$urls = [];
6864
foreach ($data['connections'] as $connectionName) {
6965
if (empty($config['connections'][$connectionName])) {
7066
throw new InvalidConfigurationException(sprintf(
@@ -73,15 +69,15 @@ private function handleClients(array &$config, ContainerBuilder $container): arr
7369
$connectionName
7470
));
7571
}
76-
$urls[] = $this->getUrl($config['connections'][$connectionName]);
72+
$connections[] = $connectionName;
7773
}
78-
if (empty($urls)) {
79-
$urls[] = $this->getUrl($config['connections']['default']);
74+
if (empty($connections)) {
75+
$connections[] = 'default';
8076
}
8177

8278
$container
8379
->setDefinition($serviceId, new DefinitionDecorator('neo4j.client.abstract'))
84-
->setArguments([$urls]);
80+
->setArguments([$connections]);
8581
}
8682

8783
return $serviceIds;
@@ -140,7 +136,7 @@ private function handleConnections(array &$config, ContainerBuilder $container):
140136
$def = new Definition(Connection::class);
141137
$def->addArgument($name);
142138
$def->addArgument($this->getUrl($data));
143-
$serviceIds[] = $serviceId = 'neo4j.connection.'.$name;
139+
$serviceIds[$name] = $serviceId = 'neo4j.connection.'.$name;
144140
$container->setDefinition($serviceId, $def);
145141
}
146142

@@ -149,6 +145,13 @@ private function handleConnections(array &$config, ContainerBuilder $container):
149145
$config['connections']['default'] = $config['connections'][$firstName];
150146
}
151147

148+
// Add connections to connection manager
149+
$connectionManager = $container->getDefinition('neo4j.connection_manager');
150+
foreach ($serviceIds as $name => $serviceId) {
151+
$connectionManager->addMethodCall('registerExistingConnection', [$name, new Reference($serviceId)]);
152+
}
153+
$connectionManager->addMethodCall('setMaster', [$firstName]);
154+
152155
return $serviceIds;
153156
}
154157

0 commit comments

Comments
 (0)