Skip to content

Commit 1442b19

Browse files
committed
Merge pull request #41 from defrag/feature/logging
Geocoder logging + profiler part 1
2 parents dbb72f8 + dd749a3 commit 1442b19

File tree

10 files changed

+388
-0
lines changed

10 files changed

+388
-0
lines changed

BazingaGeocoderBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
use Bazinga\Bundle\GeocoderBundle\DependencyInjection\Compiler\AddProvidersPass;
1717
use Bazinga\Bundle\GeocoderBundle\DependencyInjection\Compiler\AddDumperPass;
18+
use Bazinga\Bundle\GeocoderBundle\DependencyInjection\Compiler\LoggablePass;
1819

1920
/**
2021
* @author William Durand <[email protected]>
@@ -30,5 +31,6 @@ public function build(ContainerBuilder $container)
3031

3132
$container->addCompilerPass(new AddProvidersPass());
3233
$container->addCompilerPass(new AddDumperPass());
34+
$container->addCompilerPass(new LoggablePass());
3335
}
3436
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the BazingaGeocoderBundle package.
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @license MIT License
9+
*/
10+
11+
namespace Bazinga\Bundle\GeocoderBundle\DataCollector;
12+
13+
use Bazinga\Bundle\GeocoderBundle\Logger\GeocoderLogger;
14+
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
15+
use Symfony\Component\HttpFoundation\Request;
16+
use Symfony\Component\HttpFoundation\Response;
17+
18+
/**
19+
* @author Michal Dabrowski <[email protected]>
20+
*/
21+
class GeocoderDataCollector extends DataCollector
22+
{
23+
/**
24+
* @var GeocoderLogger
25+
*/
26+
protected $logger;
27+
28+
/**
29+
*
30+
* @param GeocoderLogger $logger
31+
*/
32+
public function __construct(GeocoderLogger $logger)
33+
{
34+
$this->logger = $logger;
35+
}
36+
37+
/**
38+
* {@inheritdoc}
39+
*/
40+
public function collect(Request $request, Response $response, \Exception $exception = null)
41+
{
42+
$this->data = array(
43+
'requests' => null !== $this->logger ? $this->logger->getRequests() : array(),
44+
);
45+
}
46+
47+
/**
48+
* Returns an array of collected requests.
49+
*
50+
* @return array
51+
*/
52+
public function getRequests()
53+
{
54+
return $this->data['requests'];
55+
}
56+
57+
/**
58+
* Returns the number of collected requests.
59+
*
60+
* @return integer
61+
*/
62+
public function getRequestsCount()
63+
{
64+
return count($this->data['requests']);
65+
}
66+
67+
/**
68+
* Returns the execution time of all collected requests in seconds.
69+
*
70+
* @return float
71+
*/
72+
public function getTime()
73+
{
74+
$time = 0;
75+
foreach ($this->data['requests'] as $command) {
76+
$time += $command['duration'];
77+
}
78+
79+
return $time;
80+
}
81+
82+
/**
83+
* {@inheritdoc}
84+
*/
85+
public function getName()
86+
{
87+
return 'geocoder';
88+
}
89+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the BazingaGeocoderBundle package.
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @license MIT License
9+
*/
10+
11+
namespace Bazinga\Bundle\GeocoderBundle\DependencyInjection\Compiler;
12+
13+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
14+
use Symfony\Component\DependencyInjection\ContainerBuilder;
15+
use Symfony\Component\DependencyInjection\Reference;
16+
17+
/**
18+
* @author Michal Dabrowski <[email protected]>
19+
*/
20+
class LoggablePass implements CompilerPassInterface
21+
{
22+
/**
23+
* {@inheritDoc}
24+
*/
25+
public function process(ContainerBuilder $container)
26+
{
27+
if (!$container->hasDefinition('bazinga_geocoder.geocoder')) {
28+
return;
29+
}
30+
31+
$definition = $container->getDefinition('bazinga_geocoder.geocoder');
32+
$definition->setClass(
33+
$container->getParameter('bazinga_geocoder.geocoder.loggable_class')
34+
);
35+
$definition->addMethodCall('setLogger', array(new Reference('bazinga_geocoder.logger')));
36+
37+
}
38+
}

Geocoder/LoggableGeocoder.php

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the BazingaGeocoderBundle package.
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @license MIT License
9+
*/
10+
11+
namespace Bazinga\Bundle\GeocoderBundle\Geocoder;
12+
13+
use Geocoder\Geocoder;
14+
use Bazinga\Bundle\GeocoderBundle\Logger\GeocoderLogger;
15+
16+
class LoggableGeocoder extends Geocoder
17+
{
18+
/**
19+
* @var GeocoderLogger
20+
*/
21+
protected $logger;
22+
23+
/**
24+
*
25+
* @param GeocoderLogger $logger
26+
*/
27+
public function setLogger(GeocoderLogger $logger = null)
28+
{
29+
$this->logger = $logger;
30+
}
31+
32+
/**
33+
* {@inheritdoc}
34+
*/
35+
public function geocode($value)
36+
{
37+
if (null === $this->logger) {
38+
return parent::geocode($value);
39+
}
40+
41+
$startTime = microtime(true);
42+
$result = parent::geocode($value);
43+
$duration = (microtime(true) - $startTime) * 1000;
44+
45+
$this->logger->logRequest(
46+
sprintf("[Geocoding] %s", $value),
47+
$duration,
48+
$this->getProviderClass(),
49+
json_encode($result->toArray())
50+
);
51+
52+
return $result;
53+
}
54+
55+
/**
56+
* {@inheritDoc}
57+
*/
58+
public function reverse($latitude, $longitude)
59+
{
60+
if (null === $this->logger) {
61+
return parent::reverse($latitude, $longitude);
62+
}
63+
64+
$startTime = microtime(true);
65+
$result = parent::reverse($latitude, $longitude);
66+
$duration = (microtime(true) - $startTime) * 1000;
67+
68+
$value = sprintf("[Reverse geocoding] latitude: %s, longitude: %s", $latitude, $longitude);
69+
70+
$this->logger->logRequest(
71+
$value,
72+
$duration,
73+
$this->getProviderClass(),
74+
json_encode($result->toArray())
75+
);
76+
77+
return $result;
78+
}
79+
80+
protected function getProviderClass()
81+
{
82+
$provider = explode('\\', get_class($this->getProvider()));
83+
84+
return end($provider);
85+
}
86+
}

Logger/GeocoderLogger.php

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
/**
4+
* This file is part of the BazingaGeocoderBundle package.
5+
* For the full copyright and license information, please view the LICENSE
6+
* file that was distributed with this source code.
7+
*
8+
* @license MIT License
9+
*/
10+
11+
namespace Bazinga\Bundle\GeocoderBundle\Logger;
12+
13+
use Symfony\Component\HttpKernel\Log\LoggerInterface;
14+
15+
/**
16+
* GeocoderLogger
17+
* @author Michal Dabrowski <[email protected]>
18+
*/
19+
class GeocoderLogger
20+
{
21+
protected $logger;
22+
protected $nbRequests = 0;
23+
protected $requests = array();
24+
25+
/**
26+
*
27+
* @param LoggerInterface $logger
28+
*/
29+
public function __construct(LoggerInterface $logger = null)
30+
{
31+
$this->logger = $logger;
32+
}
33+
34+
/**
35+
*
36+
* @param string $value value to geocode
37+
* @param float $duration
38+
* @param string $providerClass Geocoder provider class
39+
* @param mixed $result
40+
*/
41+
public function logRequest($value, $duration, $providerClass, $result)
42+
{
43+
++$this->nbRequests;
44+
45+
if (null !== $this->logger) {
46+
$this->requests[] = array(
47+
'value' => $value,
48+
'duration' => $duration,
49+
'providerClass' => $providerClass,
50+
'result' => $result
51+
);
52+
53+
$message = sprintf("%s %0.2f ms (%s)", $value, $duration, $providerClass);
54+
$this->logger->info($message);
55+
}
56+
}
57+
58+
/**
59+
* Returns an array of the logged requests.
60+
*
61+
* @return array
62+
*/
63+
public function getRequests()
64+
{
65+
return $this->requests;
66+
}
67+
}

Resources/config/services.xml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
<parameters>
77
<parameter key="bazinga_geocoder.geocoder.class">Geocoder\Geocoder</parameter>
8+
<parameter key="bazinga_geocoder.geocoder.loggable_class">Bazinga\Bundle\GeocoderBundle\Geocoder\LoggableGeocoder</parameter>
89
<parameter key="bazinga_geocoder.geocoder.adapter.class">Geocoder\HttpAdapter\CurlHttpAdapter</parameter>
910
<parameter key="bazinga_geocoder.geocoder.provider.bing_maps.class">Geocoder\Provider\BingMapsProvider</parameter>
1011
<parameter key="bazinga_geocoder.geocoder.provider.free_geo_ip.class">Geocoder\Provider\FreeGeoIpProvider</parameter>
@@ -29,6 +30,10 @@
2930
<parameter key="bazinga_geocoder.geocoder.provider.cache.class">Bazinga\Bundle\GeocoderBundle\Provider\CacheProvider</parameter>
3031
<parameter key="bazinga_geocoder.geocoder.provider.chain.class">Geocoder\Provider\ChainProvider</parameter>
3132

33+
<parameter key="bazinga_geocoder.logger.class">Bazinga\Bundle\GeocoderBundle\Logger\GeocoderLogger</parameter>
34+
35+
<parameter key="bazinga_geocoder.data_collector.class">Bazinga\Bundle\GeocoderBundle\DataCollector\GeocoderDataCollector</parameter>
36+
3237
<parameter key="bazinga_geocoder.event_listener.fake_request.class">Bazinga\Bundle\GeocoderBundle\EventListener\FakeRequestListener</parameter>
3338

3439
<parameter key="bazinga_geocoder.dumper_manager.class">Bazinga\Bundle\GeocoderBundle\DumperManager</parameter>
@@ -65,6 +70,18 @@
6570
<tag name="geocoder.dumper" alias="wkt" />
6671
</service>
6772

73+
<!-- Logger -->
74+
<service id="bazinga_geocoder.logger" class="%bazinga_geocoder.logger.class%">
75+
<tag name="monolog.logger" channel="bazinga_geocoder" />
76+
<argument type="service" id="logger" on-invalid="null" />
77+
</service>
78+
79+
<!-- Data collector -->
80+
<service id="bazinga_geocoder.data_collector" class="%bazinga_geocoder.data_collector.class%" public="false">
81+
<tag name="data_collector" template="BazingaGeocoderBundle:Collector:geocoder" id="geocoder" />
82+
<argument type="service" id="bazinga_geocoder.logger" />
83+
</service>
84+
6885
<!-- Listener -->
6986
<service id="bazinga_geocoder.event_listener.fake_request" class="%bazinga_geocoder.event_listener.fake_request.class%">
7087
<argument></argument>

Resources/doc/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,14 @@ bazinga_geocoder:
181181
> we recommend the [liip/doctrine-cache-bundle](https://github.com/liip/LiipDoctrineCacheBundle.git).
182182

183183

184+
### Symfony2 Profiler integration
185+
186+
Geocoder bundle additionally integrates with Syfmony2 profiler. You can check number of queries executed
187+
by each provider, total execution time and geocoding results.
188+
189+
![Example Toolbar](http://i.imgur.com/3Vy5GBW.png)
190+
191+
184192
Reference Configuration
185193
-----------------------
186194

353 Bytes
Loading

0 commit comments

Comments
 (0)