diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad1cd70..4e007c7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,3 +85,6 @@ jobs: - name: "Run code-style check" run: composer phpcs + + - name: "Run PHPStan check" + run: composer phpstan diff --git a/Cache/Memcache.php b/Cache/Memcache.php deleted file mode 100644 index 2bb0670..0000000 --- a/Cache/Memcache.php +++ /dev/null @@ -1,166 +0,0 @@ -serverName = $host . (11211 == $port ? '' : ':' . $port); - - $this->addServer($host, $port); - } - - public function setStopwatch(Stopwatch $stopwatch): void - { - $this->stopwatch = $stopwatch; - } - - public function setStopwatchTags(array $tags): void - { - $this->stopwatchAdditionalTags = $tags; - } - - protected function getStopwatchEvent($methodName) - { - $tags = $this->stopwatchAdditionalTags; - $tags['group'] = 'memcache::' . $methodName; - - if ($this->serverName) { - $tags['server'] = $this->serverName; - } - - return $this->stopwatch->start($tags); - } - - public function add($key, $var, $flag = null, $expire = null) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('add'); - } - - $result = parent::add($key, $var, $flag, $expire); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - public function set($key, $var, $flag = null, $expire = null) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('set'); - } - - $result = parent::set($key, $var, $flag, $expire); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - public function replace($key, $var, $flag = null, $expire = null) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('replace'); - } - - $result = parent::replace($key, $var, $flag, $expire); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - public function get($key, &$flags = null) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('get'); - } - - $result = parent::get($key, $flags); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - public function delete($key) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('delete'); - } - - $result = parent::delete($key); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - // methods for memcached-tags - // -------------------------- - - public function tag_add($tag, $key) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('tag_add'); - } - - $result = parent::tag_add($tag, $key); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - public function tag_delete($tag) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('tag_delete'); - } - - $result = parent::tag_delete($tag); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } - - public function tags_delete($tags) - { - if ($this->stopwatch) { - $e = $this->getStopwatchEvent('tags_delete'); - } - - $result = parent::tags_delete($tags); - - if ($this->stopwatch) { - $e->stop(); - } - - return $result; - } -} diff --git a/Cache/Redis.php b/Cache/Redis.php index 499683f..99e4fff 100644 --- a/Cache/Redis.php +++ b/Cache/Redis.php @@ -132,13 +132,13 @@ public function mSetNx($v) return $result; } - public function expire($key, $expire) + public function expire($key, $expire, $mode = null) { if ($this->stopwatch) { $e = $this->getStopwatchEvent('expire'); } - $result = parent::expire($key, $expire); + $result = parent::expire($key, $expire, $mode); if ($this->stopwatch) { $e->stop(); @@ -192,13 +192,13 @@ public function sMembers($key) return $result; } - public function sAdd($tag, $id) + public function sAdd($tag, $id, ...$other_values) { if ($this->stopwatch) { $e = $this->getStopwatchEvent('sAdd'); } - $result = parent::sAdd($tag, $id); + $result = parent::sAdd($tag, $id, ...$other_values); if ($this->stopwatch) { $e->stop(); diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index 2a1a2f4..763f664 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -20,9 +20,11 @@ public function getConfigTreeBuilder(): TreeBuilder $treeBuilder = new TreeBuilder('intaro_pinba'); if (\method_exists($treeBuilder, 'getRootNode')) { $rootNode = $treeBuilder->getRootNode(); - } else { + } elseif (\method_exists($treeBuilder, 'root')) { // BC layer for symfony/config 4.1 and older $rootNode = $treeBuilder->root('intaro_pinba'); + } else { + throw new \RuntimeException('Unsupported symfony/config version'); } $rootNode diff --git a/EventListener/ScriptNameConfigureListener.php b/EventListener/ScriptNameConfigureListener.php index 1435dce..feb519b 100644 --- a/EventListener/ScriptNameConfigureListener.php +++ b/EventListener/ScriptNameConfigureListener.php @@ -25,9 +25,9 @@ public function onRequest(KernelEvent $event): void pinba_script_name_set($event->getRequest()->getRequestUri()); } - private static function bcEvent($event) + private static function bcEvent($event): bool { - $eventClass = \Symfony\Component\HttpKernel\Event\GetResponseEvent::class; + $eventClass = 'Symfony\Component\HttpKernel\Event\GetResponseEvent'; return class_exists($eventClass) && !$event instanceof $eventClass; } diff --git a/IntaroPinbaBundle.php b/IntaroPinbaBundle.php index 4dfcea9..3d1c3f7 100644 --- a/IntaroPinbaBundle.php +++ b/IntaroPinbaBundle.php @@ -11,8 +11,6 @@ class IntaroPinbaBundle extends Bundle { public function build(ContainerBuilder $container) { - if(Kernel::MAJOR_VERSION >= 3) { - $container->addCompilerPass(new TwigPass()); - } + $container->addCompilerPass(new TwigPass()); } } diff --git a/Makefile b/Makefile index 02e5aac..52cd47a 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,10 @@ vendor: composer.json 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 + phpunit: $(PHP_CONSOLE_DEPS) @$(PHP) vendor/bin/phpunit --color=always -check: phpcs phpunit +check: phpcs phpstan phpunit diff --git a/README.md b/README.md index c149aa4..25700dc 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ PinbaBundle is Symfony bundle for [pinba](http://pinba.org). Important! Include this bundle only in `prod` environment. -It collects and sends times of execution for Doctrine queries, Twig renders and Memcache requests as pinba timers to pinba server. You can watch collected realtime metrics in [Intaro Pinboard](http://intaro.github.io/pinboard/). Example of output: +It collects and sends times of execution for Doctrine queries, Twig renders and Redis requests as pinba timers to pinba server. You can watch collected realtime metrics in [Intaro Pinboard](http://intaro.github.io/pinboard/). Example of output: ![Pinba timers in Intaro Pinboard](http://intaro.github.io/pinboard/img/timers.png) @@ -73,46 +73,6 @@ doctrine: Don't worry. This config enables pinba logger which collects only queries execution time but not logs them. -### Collecting Memcache metrics ### - -PinbaBundle supplies Memcache wrapped class `Intaro\PinbaBundle\Cache\Memcache` which collects execution times of all memcache queries. - -Example of `app/config/config_prod.yml`: -```yml -services: - memcache.db: - class: Intaro\PinbaBundle\Cache\Memcache - calls: - - [ addServer, [ %memcache.host%, %memcache.port% ]] - - [ setStopwatch, [ @intaro_pinba.stopwatch ]] - doctrine.metadata.memcache: - class: Doctrine\Common\Cache\MemcacheCache - calls: - - [ setMemcache, [ @memcache.db ]] - doctrine.query.memcache: - class: Doctrine\Common\Cache\MemcacheCache - calls: - - [ setMemcache, [ @memcache.db ]] - doctrine.result.memcache: - class: Doctrine\Common\Cache\MemcacheCache - calls: - - [ setMemcache, [ @memcache.db ]] - -doctrine: - orm: - entity_managers: - default: - metadata_cache_driver: - type: service - id: doctrine.metadata.memcache - query_cache_driver: - type: service - id: doctrine.query.memcache - result_cache_driver: - type: service - id: doctrine.result.memcache -``` - ## Development ## ### Run tests ### @@ -122,7 +82,7 @@ Install vendors: make vendor ``` -Run php-cs-fixer and phpunit: +Run php-cs-fixer, phpstan and phpunit: ```shell make check ``` diff --git a/Stopwatch/Stopwatch.php b/Stopwatch/Stopwatch.php index 4cb60eb..d98ca4b 100644 --- a/Stopwatch/Stopwatch.php +++ b/Stopwatch/Stopwatch.php @@ -43,9 +43,7 @@ public function start(array $tags) $tags = array_merge($this->initTags, $tags); if (isset($tags['group']) && !isset($tags['category']) && false !== strpos($tags['group'], '::')) { $v = explode('::', $tags['group']); - if (count($v) > 0) { - $tags['category'] = $v[0]; - } + $tags['category'] = $v[0]; } } diff --git a/Twig/TimedTwigEngine.php b/Twig/TimedTwigEngine.php index 0b09186..812d62d 100644 --- a/Twig/TimedTwigEngine.php +++ b/Twig/TimedTwigEngine.php @@ -37,6 +37,7 @@ class TimedTwigEngine extends TwigEngine */ public function __construct(\Twig\Environment $environment, TemplateNameParserInterface $parser, FileLocatorInterface $locator, Stopwatch $stopwatch) { + /* @phpstan-ignore-next-line */ parent::__construct($environment, $parser, $locator); $this->stopwatch = $stopwatch; @@ -53,6 +54,7 @@ public function render($name, array $parameters = []) 'twig_template' => (string) $name, ]); + /* @phpstan-ignore-next-line */ $ret = parent::render($name, $parameters); $e->stop(); diff --git a/composer.json b/composer.json index b267b75..fa880d5 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "intaro/pinba-bundle", - "description": "Collects and sends execution time of Doctrine queries, Twig renders and Memcache requests as pinba timers to pinba server", + "description": "Collects and sends execution time of Doctrine queries, Twig renders and Redis requests as pinba timers to pinba server", "keywords": ["symfony", "pinba", "php"], "type": "symfony-bundle", "license": "MIT", @@ -13,6 +13,7 @@ "symfony/yaml": "^4.0|^5.0|^6.0" }, "require-dev": { + "doctrine/dbal": "^2|^3|^4", "nyholm/symfony-bundle-test": "^2.0", "phpunit/phpunit": "^8.5|^9.5", "symfony/phpunit-bridge": "^5.0|^6.0", @@ -27,6 +28,7 @@ "symfony/routing": "^4.4|^5.0|^6.0", "symfony/finder": "^4.4|^5.0|^6.0", "symfony/filesystem": "^4.4|^5.0|^6.0", + "symfony/templating": "^4.4|^5.0|^6.0", "symfony/translation-contracts": "^1.1|^2.0", "symfony/var-exporter": "^4.4|^5.0|^6.0", "symfony/var-dumper": "^4.4|^5.0|^6.0", @@ -34,7 +36,8 @@ "friendsofphp/php-cs-fixer": "3.4", "twig/twig": "^v2.14 || ^3.0", "symfony/twig-bundle": "^4.4|^5.0|^6.0", - "symfony/twig-bridge": "^4.4|^5.0|^6.0" + "symfony/twig-bridge": "^4.4|^5.0|^6.0", + "phpstan/phpstan": "^1.10" }, "autoload": { "psr-4": { @@ -51,7 +54,6 @@ "phpcs": [ "vendor/bin/php-cs-fixer fix --dry-run --config=.php-cs-fixer.dist.php --using-cache=no --show-progress=none -v" ], - "docker-clean": "docker image rm $(docker image ls -qf reference=pinba-bundle-test)", - "docker": "docker build . -t pinba-bundle-test && docker image prune -f >/dev/null && docker run --rm pinba-bundle-test" + "phpstan": "vendor/bin/phpstan analyse --no-progress" } } diff --git a/meta/phpstan/stub.php b/meta/phpstan/stub.php new file mode 100644 index 0000000..1d7bc38 --- /dev/null +++ b/meta/phpstan/stub.php @@ -0,0 +1,26 @@ += 5.x + - + message: '#Access to an undefined static property Intaro\\PinbaBundle\\Tests\\BundleInitializationTest\:\:\$container#' + reportUnmatched: false diff --git a/tests/BundleInitializationTest.php b/tests/BundleInitializationTest.php index 1c95f41..6926d2c 100644 --- a/tests/BundleInitializationTest.php +++ b/tests/BundleInitializationTest.php @@ -10,6 +10,7 @@ use Nyholm\BundleTest\TestKernel; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\Bundle\TwigBundle\TwigBundle; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelInterface; class BundleInitializationTest extends KernelTestCase @@ -21,6 +22,7 @@ protected static function getKernelClass(): string protected static function createKernel(array $options = []): KernelInterface { + /** @var TestKernel $kernel */ $kernel = parent::createKernel($options); $kernel->addTestBundle(IntaroPinbaBundle::class); $kernel->addTestBundle(FixtureBundle::class); @@ -33,9 +35,9 @@ protected static function createKernel(array $options = []): KernelInterface public function testInitBundle(): void { self::bootKernel(); - $symfony = self::getSymfonyVersion(); + $symfonyVersion = self::getSymfonyVersion(); - if (version_compare($symfony, '5.0.0') >= 0) { + if ($symfonyVersion >= 5) { $container = self::getContainer(); } else { $container = self::$container; @@ -50,9 +52,9 @@ public function testInitBundle(): void public function testTwigRenderStopwatch(): void { self::bootKernel(); - $symfony = self::getSymfonyVersion(); + $symfonyVersion = self::getSymfonyVersion(); - if (version_compare($symfony, '5.0.0') >= 0) { + if ($symfonyVersion >= 5) { $container = self::getContainer(); } else { $container = self::$container; @@ -62,10 +64,11 @@ public function testTwigRenderStopwatch(): void $this->assertInstanceOf(TimedTwigEnvironment::class, $service); } - private static function getSymfonyVersion() + private static function getSymfonyVersion(): int { + /** @var Kernel $kernel */ $kernel = self::bootKernel(); - return $kernel::VERSION; + return $kernel::MAJOR_VERSION; } }