Skip to content

Instantly share code, notes, and snippets.

@thepsion5
Created December 21, 2022 20:06
Show Gist options
  • Save thepsion5/8fe226db313d43066f9203077bc3c6ca to your computer and use it in GitHub Desktop.
Save thepsion5/8fe226db313d43066f9203077bc3c6ca to your computer and use it in GitHub Desktop.
Using Aura\SQL to Log Slow Queries via a simple Decorator Class
<?php
declare(strict_types=1);
use Aura\Sql\{DecoratedPdo, Profiler\Profiler}
use Monolog\{Level, Logger, Handler\StreamHandler};
use YourProject\Infrastructure\Logging\SlowQueryLogDecorator;
$connection = get_connection_details_from_somewhere();
//create the base logger, then wrap it with the decorator
$baseLogger = new Logger('selective-logging-based-on-query-time');
$baseLogger->pushHandler(new StreamHandler('path/to/log/file.log', Level::Info));
$decorator = new SlowQueryLogDecorator($baseLogger);
//create the base PDO object and then wrap it with the Aura\SQL decorator
$originalPdo = new PDO(...$connection);
$pdo = new DecoratedPdo($originalPdo);
//create the profiler with the slow query log decorator and then set it with the Aura\SQL decorator
$profiler = new Profiler($decorator);
$pdo->setProfiler($profiler);
return $pdo;
<?php
declare(strict_types=1);
namespace YourApp\Infrastructure\Logging;
use Psr\Log\{LoggerInterface, LoggerTrait};
class SlowQueryLogDecorator implements LoggerInterface
{
use LoggerTrait;
/**
* @var int Minimum execution time before queries should be logged in milliseconds
*/
private int $querySpeedThreshold;
private LoggerInterface $next;
public function __construct(LoggerInterface $next, int $querySpeedThreshold = 5000)
{
$this->next = $next;
$this->querySpeedThreshold = $querySpeedThreshold;
}
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string $message
* @param mixed[] $context
*
* @return void
*
* @throws \Psr\Log\InvalidArgumentException
*/
public function log($level, $message, array $context = [])
{
if ($this->shouldLog($context)) {
$this->next->log($level, $message, $context);
}
}
/**
* Checks to see whether this query should be logged based on its duration
*
* @param $context array{duration: numeric, ...}
* @return bool
*/
private function shouldLog(array $context): bool
{
if (!array_key_exists('duration', $context)) {
return false;
}
return $context['duration'] >= (float) $this->querySpeedThreshold;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment