Skip to content

Commit

Permalink
Logging as Middleware support for newer versions of DBAL
Browse files Browse the repository at this point in the history
  • Loading branch information
muxx committed Oct 29, 2024
1 parent 9cdf4f3 commit 3dc4be0
Show file tree
Hide file tree
Showing 7 changed files with 208 additions and 1 deletion.
81 changes: 81 additions & 0 deletions Doctrine/Middleware/Connection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

namespace Intaro\PinbaBundle\Doctrine\Middleware;

use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
use Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware;
use Doctrine\DBAL\Driver\Result;
use Intaro\PinbaBundle\Stopwatch\StopwatchEvent;
use Intaro\PinbaBundle\Stopwatch\Stopwatch;

final class Connection extends AbstractConnectionMiddleware
{
private string $databaseHost;
private ?Stopwatch $stopwatch;

public function __construct(
ConnectionInterface $connection,
string $databaseHost,
?Stopwatch $stopwatch
) {
parent::__construct($connection);

$this->databaseHost = $databaseHost;
$this->stopwatch = $stopwatch;
}

public function prepare(string $sql): Statement
{
return new Statement(
parent::prepare($sql),
$this->databaseHost,
$sql,
$this->stopwatch,
);
}

public function query(string $sql): Result
{
$stopwatchEvent = $this->getStopwatchEvent($sql);

try {
return parent::query($sql);
} finally {
if ($stopwatchEvent) {
$stopwatchEvent->stop();
}
}
}

public function exec(string $sql): int
{
$stopwatchEvent = $this->getStopwatchEvent($sql);

try {
return parent::exec($sql);
} finally {
if ($stopwatchEvent) {
$stopwatchEvent->stop();
}
}
}

private function getStopwatchEvent(string $sql): ?StopwatchEvent
{
if (null === $this->stopwatch) {
return null;
}

$tags = [
'server' => $this->databaseHost ?: ($_SERVER['HOSTNAME'] ?? ''),
];

if (preg_match('/^\s*(\w+)\s/u', $sql, $matches)) {
$tags['group'] = 'doctrine::' . strtolower($matches[1]);
} else {
$tags['group'] = 'doctrine::';
}

return $this->stopwatch->start($tags);
}
}
36 changes: 36 additions & 0 deletions Doctrine/Middleware/Driver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Intaro\PinbaBundle\Doctrine\Middleware;

use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\Driver\Connection as ConnectionInterface;
use Doctrine\DBAL\Driver\Middleware\AbstractDriverMiddleware;
use Intaro\PinbaBundle\Stopwatch\Stopwatch;

final class Driver extends AbstractDriverMiddleware
{
private string $databaseHost;
private ?Stopwatch $stopwatch;

public function __construct(
DriverInterface $driver,
string $databaseHost,
?Stopwatch $stopwatch
) {
parent::__construct($driver);

$this->databaseHost = $databaseHost;
$this->stopwatch = $stopwatch;
}

public function connect(array $params): ConnectionInterface
{
$connection = parent::connect($params);

return new Connection(
$connection,
$this->databaseHost,
$this->stopwatch
);
}
}
26 changes: 26 additions & 0 deletions Doctrine/Middleware/LoggingMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace Intaro\PinbaBundle\Doctrine\Middleware;

use Doctrine\DBAL\Driver as DriverInterface;
use Doctrine\DBAL\Driver\Middleware;
use Intaro\PinbaBundle\Stopwatch\Stopwatch;

class LoggingMiddleware implements Middleware
{
private string $databaseHost;
private ?Stopwatch $stopwatch;

public function __construct(
string $databaseHost,
?Stopwatch $stopwatch = null
) {
$this->databaseHost = $databaseHost;
$this->stopwatch = $stopwatch;
}

public function wrap(DriverInterface $driver): DriverInterface
{
return new Driver($driver, $this->databaseHost, $this->stopwatch);
}
}
54 changes: 54 additions & 0 deletions Doctrine/Middleware/Statement.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Intaro\PinbaBundle\Doctrine\Middleware;

use Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware;
use Doctrine\DBAL\Driver\Result as ResultInterface;
use Doctrine\DBAL\Driver\Statement as StatementInterface;
use Intaro\PinbaBundle\Stopwatch\Stopwatch;

final class Statement extends AbstractStatementMiddleware
{
private string $databaseHost;
private string $sql;
private ?Stopwatch $stopwatch;

public function __construct(
StatementInterface $statement,
string $databaseHost,
string $sql,
?Stopwatch $stopwatch = null
) {
parent::__construct($statement);

$this->databaseHost = $databaseHost;
$this->sql = $sql;
$this->stopwatch = $stopwatch;
}

public function execute($params = null): ResultInterface
{
$stopwatchEvent = null;
if (null !== $this->stopwatch) {
$tags = [
'server' => $this->databaseHost ?: ($_SERVER['HOSTNAME'] ?? ''),
];

if (preg_match('/^\s*(\w+)\s/u', $this->sql, $matches)) {
$tags['group'] = 'doctrine::' . strtolower($matches[1]);
} else {
$tags['group'] = 'doctrine::';
}

$stopwatchEvent = $this->stopwatch->start($tags);
}

try {
return parent::execute($params);
} finally {
if ($stopwatchEvent) {
$stopwatchEvent->stop();
}
}
}
}
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ phpcs: $(PHP_CONSOLE_DEPS)
@$(PHP) vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --using-cache=no -v

phpstan: $(PHP_CONSOLE_DEPS)
@$(PHP) vendor/bin/phpstan analyse
@$(PHP) vendor/bin/phpstan analyse -v

phpunit: $(PHP_CONSOLE_DEPS)
@$(PHP) vendor/bin/phpunit --color=always
Expand Down
7 changes: 7 additions & 0 deletions Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,10 @@ services:
arguments:
- "@intaro_pinba.stopwatch"
- "%intaro_pinba.doctrine.database_host%"

Intaro\PinbaBundle\Doctrine\Middleware\LoggingMiddleware:
arguments:
$stopwatch: "@intaro_pinba.stopwatch"
$databaseHost: "%intaro_pinba.doctrine.database_host%"
tags:
- { name: doctrine.middleware }
3 changes: 3 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@ parameters:
-
message: '#Access to an undefined static property Intaro\\PinbaBundle\\Tests\\BundleInitializationTest\:\:\$container#'
reportUnmatched: false
-
message: '#Method Doctrine\\DBAL\\Driver\\Middleware\\AbstractStatementMiddleware\:\:execute\(\) invoked with 1 parameter, 0 required#'
reportUnmatched: false

0 comments on commit 3dc4be0

Please sign in to comment.