Verified Commit ef555efa authored by Bastien Durel's avatar Bastien Durel
Browse files

add another logger, which loads after query to add execution time in params[]

parent 5628f8dc
Loading
Loading
Loading
Loading
+166 −5
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
        "This file is @generated automatically"
    ],
    "content-hash": "5f725162e32cfa7c6a9b3a013405a390",
    "content-hash": "6a64f341b36f76d7470073066fd2ddf7",
    "packages": [
        {
            "name": "doctrine/cache",
@@ -936,12 +936,173 @@
            "time": "2021-11-29T18:10:03+00:00"
        }
    ],
    "packages-dev": [],
    "packages-dev": [
        {
            "name": "doctrine/dbal",
            "version": "3.3.x-dev",
            "source": {
                "type": "git",
                "url": "https://github.com/doctrine/dbal.git",
                "reference": "b2ebd20ec1edf60506847b56e2fad873373493b7"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/doctrine/dbal/zipball/b2ebd20ec1edf60506847b56e2fad873373493b7",
                "reference": "b2ebd20ec1edf60506847b56e2fad873373493b7",
                "shasum": ""
            },
            "require": {
                "composer-runtime-api": "^2",
                "doctrine/cache": "^1.11|^2.0",
                "doctrine/deprecations": "^0.5.3",
                "doctrine/event-manager": "^1.0",
                "php": "^7.3 || ^8.0",
                "psr/cache": "^1|^2|^3",
                "psr/log": "^1|^2|^3"
            },
            "require-dev": {
                "doctrine/coding-standard": "9.0.0",
                "jetbrains/phpstorm-stubs": "2021.1",
                "phpstan/phpstan": "1.3.0",
                "phpstan/phpstan-strict-rules": "^1.1",
                "phpunit/phpunit": "9.5.11",
                "psalm/plugin-phpunit": "0.16.1",
                "squizlabs/php_codesniffer": "3.6.2",
                "symfony/cache": "^5.2|^6.0",
                "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0",
                "vimeo/psalm": "4.16.1"
            },
            "suggest": {
                "symfony/console": "For helpful console commands such as SQL execution and import of files."
            },
            "bin": [
                "bin/doctrine-dbal"
            ],
            "type": "library",
            "autoload": {
                "psr-4": {
                    "Doctrine\\DBAL\\": "src"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "Guilherme Blanco",
                    "email": "guilhermeblanco@gmail.com"
                },
                {
                    "name": "Roman Borschel",
                    "email": "roman@code-factory.org"
                },
                {
                    "name": "Benjamin Eberlei",
                    "email": "kontakt@beberlei.de"
                },
                {
                    "name": "Jonathan Wage",
                    "email": "jonwage@gmail.com"
                }
            ],
            "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
            "homepage": "https://www.doctrine-project.org/projects/dbal.html",
            "keywords": [
                "abstraction",
                "database",
                "db2",
                "dbal",
                "mariadb",
                "mssql",
                "mysql",
                "oci8",
                "oracle",
                "pdo",
                "pgsql",
                "postgresql",
                "queryobject",
                "sasql",
                "sql",
                "sqlite",
                "sqlserver",
                "sqlsrv"
            ],
            "support": {
                "issues": "https://github.com/doctrine/dbal/issues",
                "source": "https://github.com/doctrine/dbal/tree/3.3.x"
            },
            "funding": [
                {
                    "url": "https://www.doctrine-project.org/sponsorship.html",
                    "type": "custom"
                },
                {
                    "url": "https://www.patreon.com/phpdoctrine",
                    "type": "patreon"
                },
                {
                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
                    "type": "tidelift"
                }
            ],
            "time": "2022-01-12T21:41:05+00:00"
        },
        {
            "name": "psr/log",
            "version": "dev-master",
            "source": {
                "type": "git",
                "url": "https://github.com/php-fig/log.git",
                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
            },
            "dist": {
                "type": "zip",
                "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
                "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
                "shasum": ""
            },
            "require": {
                "php": ">=8.0.0"
            },
            "default-branch": true,
            "type": "library",
            "extra": {
                "branch-alias": {
                    "dev-master": "3.x-dev"
                }
            },
            "autoload": {
                "psr-4": {
                    "Psr\\Log\\": "src"
                }
            },
            "notification-url": "https://packagist.org/downloads/",
            "license": [
                "MIT"
            ],
            "authors": [
                {
                    "name": "PHP-FIG",
                    "homepage": "https://www.php-fig.org/"
                }
            ],
            "description": "Common interface for logging libraries",
            "homepage": "https://github.com/php-fig/log",
            "keywords": [
                "log",
                "psr",
                "psr-3"
            ],
            "support": {
                "source": "https://github.com/php-fig/log/tree/3.0.0"
            },
            "time": "2021-07-14T16:46:02+00:00"
        }
    ],
    "aliases": [],
    "minimum-stability": "dev",
    "stability-flags": {
        "symfony/doctrine-bridge": 20
    },
    "stability-flags": [],
    "prefer-stable": false,
    "prefer-lowest": false,
    "platform": [],
+107 −0
Original line number Diff line number Diff line
<?php

/*
 * This file is based on the work of Fabien Potencier <fabien@symfony.com>
 * Symfony\Bridge\Doctrine\Logger\DbalLogger.php -- which is part of
 * the Symfony package.
 */

namespace Data\DbalLogTime\Params;

use Doctrine\DBAL\Logging\SQLLogger;
use Psr\Log\LoggerInterface;
use Symfony\Component\Stopwatch\Stopwatch;

/**
 * This version of the logger puts a "_duration" item in the parameters
 * which holds the query duration. It logs only after the query returned
 */
class DbalLogger implements SQLLogger
{
    public const MAX_STRING_LENGTH = 32;
    public const BINARY_DATA_VALUE = '(binary value)';

    protected $logger;
    protected $stopwatch;
    protected $sql;
    protected $params;
    protected $start;

    public function __construct(LoggerInterface $logger = null, Stopwatch $stopwatch = null)
    {
        $this->logger = $logger;
        $this->stopwatch = $stopwatch;
    }

    /**
     * {@inheritdoc}
     *
     * @return void
     */
    public function startQuery($sql, ?array $params = null, ?array $types = null): void
    {
        if (null !== $this->stopwatch) {
            $this->stopwatch->start('doctrine', 'doctrine');
        }

        if (null !== $this->logger) {
            $this->sql = $sql;
            $this->params = null === $params ? [] : $this->normalizeParams($params);
            if (null === $this->stopwatch)
                $this->start = hrtime(false);
        }
    }

    /**
     * {@inheritdoc}
     *
     * @return void
     */
    public function stopQuery(): void
    {
        if (null !== $this->stopwatch) {
            $ev = $this->stopwatch->stop('doctrine');
        }
        if (null !== $this->logger) {
            if (empty($ev)) {
                list ($sec, $nsec) = hrtime(false);
                $sd = $sec - $this->start[0];
                $nd = $nsec - $this->start[1];
                $this->params['_duration'] = $sd + ($nd / 1000000000);
            }
            else {
                $this->params['_duration'] = $ev->getDuration() / 1000;
            }
            $this->logger->debug($this->sql, $this->params);
        }
    }

    private function normalizeParams(array $params): array
    {
        foreach ($params as $index => $param) {
            // normalize recursively
            if (\is_array($param)) {
                $params[$index] = $this->normalizeParams($param);
                continue;
            }

            if (!\is_string($params[$index])) {
                continue;
            }

            // non utf-8 strings break json encoding
            if (!preg_match('//u', $params[$index])) {
                $params[$index] = self::BINARY_DATA_VALUE;
                continue;
            }

            // detect if the too long string must be shorten
            if (self::MAX_STRING_LENGTH < mb_strlen($params[$index], 'UTF-8')) {
                $params[$index] = mb_substr($params[$index], 0, self::MAX_STRING_LENGTH - 6, 'UTF-8').' [...]';
                continue;
            }
        }

        return $params;
    }
}

test/test.php

0 → 100644
+13 −0
Original line number Diff line number Diff line
<?php

require_once __DIR__ . '/../vendor/autoload.php'; // Autoload files using Composer autoload

use Data\DbalLogTime\DbalLogger;

$logger = new DbalLogger(null, null);

echo $logger::MAX_STRING_LENGTH . "\n";

$logger2 = new Data\DbalLogTime\Params\DbalLogger(null, null);

echo $logger2::MAX_STRING_LENGTH . "\n";