Skip to content

Commit c293122

Browse files
authored
Merge pull request #10 from neo4j-contrib/Nyholm-datacollector
Improve the profiler and data collector
2 parents 18c7f85 + 11504cf commit c293122

File tree

10 files changed

+273
-266
lines changed

10 files changed

+273
-266
lines changed

Collector/DebugLogger.php

-83
This file was deleted.

Collector/Neo4jDataCollector.php

+22-34
Original file line numberDiff line numberDiff line change
@@ -9,56 +9,60 @@
99
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
1010

1111
/**
12-
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
12+
* @author Xavier Coureau <xavier@pandawan-technology.com>
1313
*/
1414
final class Neo4jDataCollector extends DataCollector
1515
{
16-
private $logger;
16+
/**
17+
* @var QueryLogger
18+
*/
19+
private $queryLogger;
1720

18-
public function __construct(DebugLogger $logger)
21+
public function __construct(QueryLogger $logger)
1922
{
20-
$this->logger = $logger;
23+
$this->queryLogger = $logger;
2124
}
2225

2326
/**
2427
* {@inheritdoc}
2528
*/
2629
public function collect(Request $request, Response $response, \Exception $exception = null)
2730
{
31+
$this->data['nb_queries'] = count($this->queryLogger);
32+
$this->data['statements'] = $this->queryLogger->getStatements();
33+
$this->data['time'] = $this->queryLogger->getElapsedTime();
2834
}
2935

3036
/**
31-
* @return array|\GraphAware\Common\Cypher\StatementInterface[]
37+
* @return int
3238
*/
33-
public function getStatements()
39+
public function getQueryCount()
3440
{
35-
return $this->logger->getStatements();
41+
return $this->data['nb_queries'];
3642
}
3743

3844
/**
39-
* @return array|\GraphAware\Common\Result\Result[]
45+
* @return QueryLogger
4046
*/
41-
public function getResults()
47+
public function getStatements()
4248
{
43-
return $this->logger->getResults();
49+
return $this->data['statements'];
4450
}
4551

4652
/**
47-
* @return array|\GraphAware\Neo4j\Client\Exception\Neo4jExceptionInterface[]
53+
* @return float
4854
*/
49-
public function getExceptions()
55+
public function getTime()
5056
{
51-
return $this->logger->getExceptions();
57+
return $this->data['time'];
5258
}
5359

5460
/**
55-
* @param int $idx
56-
*
57-
* @return bool
61+
* @return float
5862
*/
59-
public function wasSuccessful(int $idx): bool
63+
public function getTimeForQuery()
6064
{
61-
return isset($this->logger->getResults()[$idx]);
65+
return $this->data['time'];
6266
}
6367

6468
/**
@@ -68,20 +72,4 @@ public function getName()
6872
{
6973
return 'neo4j';
7074
}
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-
}
8775
}

Collector/QueryLogger.php

+117
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

+14-10
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,20 @@ public function load(array $configs, ContainerBuilder $container)
3535

3636
$this->handleConnections($config, $container);
3737
$clientServiceIds = $this->handleClients($config, $container);
38+
3839
if ($this->validateEntityManagers($config)) {
3940
$loader->load('entity_manager.xml');
4041
$this->handleEntityMangers($config, $container, $clientServiceIds);
42+
$container->setAlias('neo4j.entity_manager', 'neo4j.entity_manager.default');
4143
}
4244

4345
// add aliases for the default services
4446
$container->setAlias('neo4j.connection', 'neo4j.connection.default');
4547
$container->setAlias('neo4j.client', 'neo4j.client.default');
46-
$container->setAlias('neo4j.entity_manager', 'neo4j.entity_manager.default');
4748

4849
// Configure toolbar
4950
if ($this->isConfigEnabled($container, $config['profiling'])) {
5051
$loader->load('data-collector.xml');
51-
52-
$container->getDefinition('neo4j.factory.client')
53-
->replaceArgument(0, new Reference('neo4j.client_logger'));
5452
}
5553
}
5654

@@ -86,7 +84,6 @@ private function handleClients(array &$config, ContainerBuilder $container): arr
8684
$serviceIds = [];
8785
foreach ($config['clients'] as $name => $data) {
8886
$serviceIds[$name] = $serviceId = sprintf('neo4j.client.%s', $name);
89-
$urls = [];
9087
foreach ($data['connections'] as $connectionName) {
9188
if (empty($config['connections'][$connectionName])) {
9289
throw new InvalidConfigurationException(sprintf(
@@ -95,15 +92,15 @@ private function handleClients(array &$config, ContainerBuilder $container): arr
9592
$connectionName
9693
));
9794
}
98-
$urls[] = $this->getUrl($config['connections'][$connectionName]);
95+
$connections[] = $connectionName;
9996
}
100-
if (empty($urls)) {
101-
$urls[] = $this->getUrl($config['connections']['default']);
97+
if (empty($connections)) {
98+
$connections[] = 'default';
10299
}
103100

104101
$container
105102
->setDefinition($serviceId, new DefinitionDecorator('neo4j.client.abstract'))
106-
->setArguments([$urls]);
103+
->setArguments([$connections]);
107104
}
108105

109106
return $serviceIds;
@@ -157,7 +154,7 @@ private function handleConnections(array &$config, ContainerBuilder $container):
157154
$def = new Definition(Connection::class);
158155
$def->addArgument($name);
159156
$def->addArgument($this->getUrl($data));
160-
$serviceIds[] = $serviceId = 'neo4j.connection.'.$name;
157+
$serviceIds[$name] = $serviceId = 'neo4j.connection.'.$name;
161158
$container->setDefinition($serviceId, $def);
162159
}
163160

@@ -166,6 +163,13 @@ private function handleConnections(array &$config, ContainerBuilder $container):
166163
$config['connections']['default'] = $config['connections'][$firstName];
167164
}
168165

166+
// Add connections to connection manager
167+
$connectionManager = $container->getDefinition('neo4j.connection_manager');
168+
foreach ($serviceIds as $name => $serviceId) {
169+
$connectionManager->addMethodCall('registerExistingConnection', [$name, new Reference($serviceId)]);
170+
}
171+
$connectionManager->addMethodCall('setMaster', [$firstName]);
172+
169173
return $serviceIds;
170174
}
171175

0 commit comments

Comments
 (0)