From ecdc8d86a5e961f48b597fa7227ce81aab2dd8c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 00:11:04 +0200 Subject: [PATCH 01/11] Update phpunit to 8.5 --- phpunit.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/phpunit.xml b/phpunit.xml index 527c2585e..d989cdc8b 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,11 +1,11 @@ - + - + ./tests From f810ee2fc9f06c54fb3430658bda10be83afde56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 00:39:49 +0200 Subject: [PATCH 02/11] Fix assertInternalType deprecation --- tests/Controller/RunTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Controller/RunTest.php b/tests/Controller/RunTest.php index b9ec93d3c..641c35f37 100644 --- a/tests/Controller/RunTest.php +++ b/tests/Controller/RunTest.php @@ -157,7 +157,7 @@ public function testCallgraphData(): void ]); $result = $this->runs->callgraphData($this->request); - $this->assertInternalType('array', $result); + $this->assertIsArray($result); $this->assertArrayHasKey('metric', $result); $this->assertArrayHasKey('total', $result); $this->assertArrayHasKey('nodes', $result); From 4127eff9f4c0ae4934eddaaf0d50922d6911b1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 00:37:30 +0200 Subject: [PATCH 03/11] Fix withConsecutive arguments --- tests/Saver/MongoTest.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/Saver/MongoTest.php b/tests/Saver/MongoTest.php index 3d45cc6ff..e235f934b 100644 --- a/tests/Saver/MongoTest.php +++ b/tests/Saver/MongoTest.php @@ -17,9 +17,23 @@ public function testSave(): void $collection = $this->getMockBuilder(MongoCollection::class) ->disableOriginalConstructor() ->getMock(); - $collection->expects($this->exactly(count($data))) + + $collection + ->expects($this->exactly(count($data))) ->method('insert') - ->withConsecutive($this->equalTo($data)); + ->withConsecutive(...array_map(function () { + return [ + $this->callback(function ($data) { + $this->assertIsArray($data); + $this->assertArrayHasKey('_id', $data); + $this->assertArrayHasKey('meta', $data); + $this->assertArrayHasKey('profile', $data); + + return true; + }), + $this->equalTo(['w' => 0]), + ]; + }, $data)); $saver = new MongoSaver($collection); From 0be12135993511f858162b70f079b80cb67356aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 12:02:10 +0200 Subject: [PATCH 04/11] Add php 8.1 to working php versions --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33e22ee21..f569bbe21 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ it. XHGui has the following requirements: -- Known to work: PHP >= 7.2, 8.0. +- Known to work: PHP >= 7.2, 8.0, 8.1 - If using MongoDB storage, see [MongoDB](#MongoDB) requirements - If using PDO storage, see [PDO](#PDO) requirements - To profile an application, one of the profiling PHP extensions is required. From 5956e70f6e3a26d7e9fc01c488f8aed703635d2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 12:02:24 +0200 Subject: [PATCH 05/11] Make it explicit that 8.0 and 8.1 supported --- composer.json | 2 +- composer.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index d2636addf..dc8ed756e 100644 --- a/composer.json +++ b/composer.json @@ -21,7 +21,7 @@ "platform-check": "php-only" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.2 || ~8.0 || ~8.1", "ext-json": "*", "alcaeus/mongo-php-adapter": "^1.1", "pimple/pimple": "^3.0", diff --git a/composer.lock b/composer.lock index 05b3aac22..ec653466a 100644 --- a/composer.lock +++ b/composer.lock @@ -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": "129ea9eeefd256ce64df58c35f868657", + "content-hash": "49b9bd7851f3673825184d351c4ecd2c", "packages": [ { "name": "alcaeus/mongo-php-adapter", @@ -948,7 +948,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^7.2 || ^8.0", + "php": "^7.2 || ~8.0 || ~8.1", "ext-json": "*" }, "platform-dev": [], From 79409f209fda6c93f14c2828f0531e3673ac25d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 12:37:24 +0200 Subject: [PATCH 06/11] Promote perftools/php-profiler more earlier As seems people still want to install GUI aside their application while there's is no such need to pull so much dependencies to their application. --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f569bbe21..b1edec7df 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,17 @@ A graphical interface for XHProf profiling data that can store the results in MongoDB or PDO database. -Application is [profiled](#profiling-a-web-request-or-cli-script) and the +Application is profiled and the profiling data is transferred to XHGui, which takes that information, saves it in MongoDB (or PDO database), and provides a convenient GUI for working with it. +This project is the GUI for showing profiling results, +to profile your application, use specific minimal library: +- [perftools/php-profiler] + +[perftools/php-profiler]: #profiling-a-web-request-or-cli-script + [![Build Status](https://travis-ci.org/perftools/xhgui.svg?branch=master)](https://travis-ci.org/perftools/xhgui) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/perftools/xhgui/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/perftools/xhgui/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/perftools/xhgui/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/perftools/xhgui/?branch=master) From 20cd4912b63798ddc0fe983abf85c678da285184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 12:47:27 +0200 Subject: [PATCH 07/11] Cleanup error/view.twig template. No longer used --- src/ServiceProvider/RouteProvider.php | 17 ----------------- templates/error/view.twig | 19 ------------------- 2 files changed, 36 deletions(-) delete mode 100644 templates/error/view.twig diff --git a/src/ServiceProvider/RouteProvider.php b/src/ServiceProvider/RouteProvider.php index 8cadabe41..c09ec2d9e 100644 --- a/src/ServiceProvider/RouteProvider.php +++ b/src/ServiceProvider/RouteProvider.php @@ -19,23 +19,6 @@ public function register(Container $di): void private function registerRoutes(Container $di, App $app): void { - /* - $app->error(static function (Exception $e) use ($di, $app): void { - // @var Twig $view - $view = $di['view']; - $view->parserOptions['cache'] = false; - $view->parserExtensions = [ - new TwigExtension($app), - ]; - - $app->view($view); - $app->render('error/view.twig', [ - 'message' => $e->getMessage(), - 'stack_trace' => $e->getTraceAsString(), - ]); - }); - */ - /** * Wrap Request/Response with RequestProxuy/RequestWrapper */ diff --git a/templates/error/view.twig b/templates/error/view.twig deleted file mode 100644 index 975acf312..000000000 --- a/templates/error/view.twig +++ /dev/null @@ -1,19 +0,0 @@ -{% extends 'layout/base.twig' %} - -{% block content %} -

Aw shoot, XHGui hit an error

- -

{{ message }}

- -

-You should check the following things: -

-
    -
  • Ensure that Mongo has been started
  • -
  • That config/config.php has the right connection information.
  • -
  • That the cache/ directory has the correct permissions.
  • -
- -
Stack trace
-
{{ stack_trace }}
-{% endblock %} From 847f190e5cc78976904e10faf63fe9079088b88c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 12:47:53 +0200 Subject: [PATCH 08/11] Fix minor RequestProxy typo in phpdoc --- src/ServiceProvider/RouteProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ServiceProvider/RouteProvider.php b/src/ServiceProvider/RouteProvider.php index c09ec2d9e..ce805f244 100644 --- a/src/ServiceProvider/RouteProvider.php +++ b/src/ServiceProvider/RouteProvider.php @@ -20,7 +20,7 @@ public function register(Container $di): void private function registerRoutes(Container $di, App $app): void { /** - * Wrap Request/Response with RequestProxuy/RequestWrapper + * Wrap Request/Response with RequestProxy/RequestWrapper */ $wrap = static function ($handler) use ($di, $app) { return function () use ($handler, $di, $app) { From aa1eb216c3125a5d780c0dbc2bd78b94452a9c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 21:42:29 +0200 Subject: [PATCH 09/11] Add storage backend compatibility matrix --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index f569bbe21..6bb960122 100644 --- a/README.md +++ b/README.md @@ -242,6 +242,31 @@ Some Notes: health are exposed on `/metrics`. (This currently only works if using PDO for storage.) +# Compatibility matrix + +| Feature | MongoDB | PDO | +|---------------------------------|----------|----------| +| Prometheus exporter | ✗ | ✓ [#305] | +| Searcher::latest() | ✓ | ✓ | +| Searcher::query() | ✓ | ✗ [#384] | +| Searcher::get() | ✓ | ✓ | +| Searcher::getForUrl() | ✓ | ✓ [#436] | +| Searcher::getPercentileForUrl() | ✓ | ✓ [#436] | +| Searcher::getAvgsForUrl() | ✓ | ✗ [#384] | +| Searcher::getAll(sort) | ✓ | ✓ [#436] | +| Searcher::getAll(direction) | ✓ | ✓ [#436] | +| Searcher::delete() | ✓ | ✓ | +| Searcher::truncate() | ✓ | ✓ | +| Searcher::saveWatch() | ✓ | ✓ [#435] | +| Searcher::getAllWatches() | ✓ | ✓ [#435] | +| Searcher::truncateWatches() | ✓ | ✓ [#435] | +| Searcher::stats() | ✗ [#305] | ✓ | + +[#305]: https://github.com/perftools/xhgui/pull/305 +[#384]: https://github.com/perftools/xhgui/pull/384 +[#435]: https://github.com/perftools/xhgui/pull/435 +[#436]: https://github.com/perftools/xhgui/pull/436 + # Releases / Changelog See the [releases](https://github.com/perftools/xhgui/releases) for changelogs, From c76a91017e100dd8b884d0ab151eb47e99f46c28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Elan=20Ruusam=C3=A4e?= Date: Tue, 18 Jan 2022 21:44:42 +0200 Subject: [PATCH 10/11] Link to compatibility matrix --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 6bb960122..d42836315 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ XHGui has the following requirements: See [Profiling a Web Request or CLI script](#profiling-a-web-request-or-cli-script). The extension is not needed to run XHGui itself. +If you need to decide which backend to use, you can check the [compatibility +matrix](#compatibility-matrix) what features are implemented or missing per +backend. + ## MongoDB The default installation uses MongoDB database. Most of the documentation speaks about MongoDB. From 6a63ccc5573cedae6e1a5bd08ac147f1196a9302 Mon Sep 17 00:00:00 2001 From: Gocha Ossinkine Date: Tue, 18 Jan 2022 19:07:01 +0200 Subject: [PATCH 11/11] Add selectbox for server name --- README.md | 3 +++ mongo.init.d/xhgui.js | 1 + src/Controller/RunController.php | 3 +++ src/Searcher/MongoSearcher.php | 8 ++++++++ src/Searcher/PdoSearcher.php | 8 ++++++++ src/Searcher/SearcherInterface.php | 7 +++++++ templates/runs/list.twig | 11 ++++++++++- tests/Searcher/MongoTest.php | 8 ++++++++ tests/fixtures/normalized.json | 20 ++++++++++++++++++++ 9 files changed, 68 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 56590355c..6740582ec 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ NOTE: PDO may not support all the features of XHGui, see [#320]. > db.results.ensureIndex( { 'profile.main().cpu' : -1 } ) > db.results.ensureIndex( { 'meta.url' : 1 } ) > db.results.ensureIndex( { 'meta.simple_url' : 1 } ) + > db.results.ensureIndex( { 'meta.SERVER.SERVER_NAME' : 1 } ) ``` 7. Install dependencies with composer @@ -271,11 +272,13 @@ storage.) | Searcher::getAllWatches() | ✓ | ✓ [#435] | | Searcher::truncateWatches() | ✓ | ✓ [#435] | | Searcher::stats() | ✗ [#305] | ✓ | +| Searcher::getAllServerNames() | ✓ [#460] | ✗ | [#305]: https://github.com/perftools/xhgui/pull/305 [#384]: https://github.com/perftools/xhgui/pull/384 [#435]: https://github.com/perftools/xhgui/pull/435 [#436]: https://github.com/perftools/xhgui/pull/436 +[#460]: https://github.com/perftools/xhgui/pull/460 # Releases / Changelog diff --git a/mongo.init.d/xhgui.js b/mongo.init.d/xhgui.js index c386fca36..09472b510 100644 --- a/mongo.init.d/xhgui.js +++ b/mongo.init.d/xhgui.js @@ -3,3 +3,4 @@ db.results.ensureIndex( { 'profile.main().wt' : -1 } ); db.results.ensureIndex( { 'profile.main().mu' : -1 } ); db.results.ensureIndex( { 'profile.main().cpu' : -1 } ); db.results.ensureIndex( { 'meta.url' : 1 } ); +db.results.ensureIndex( { 'meta.SERVER.SERVER_NAME' : 1 } ); diff --git a/src/Controller/RunController.php b/src/Controller/RunController.php index c7db7a244..14def25de 100644 --- a/src/Controller/RunController.php +++ b/src/Controller/RunController.php @@ -47,6 +47,8 @@ public function index(Request $request): void 'projection' => true, ])); + $serverNames = $this->searcher->getAllServerNames(); + $title = 'Recent runs'; $titleMap = [ 'wt' => 'Longest wall time', @@ -71,6 +73,7 @@ public function index(Request $request): void 'search' => $search, 'has_search' => implode('', $search) !== '', 'title' => $title, + 'server_names' => $serverNames, ]); } diff --git a/src/Searcher/MongoSearcher.php b/src/Searcher/MongoSearcher.php index e5bcd9a30..39229297c 100644 --- a/src/Searcher/MongoSearcher.php +++ b/src/Searcher/MongoSearcher.php @@ -364,4 +364,12 @@ public function stats(): array 'bytes' => 0, ]; } + + /** + * {@inheritdoc} + */ + public function getAllServerNames(): ?array + { + return $this->_collection->distinct('meta.SERVER.SERVER_NAME'); + } } diff --git a/src/Searcher/PdoSearcher.php b/src/Searcher/PdoSearcher.php index 836208a42..617248f05 100644 --- a/src/Searcher/PdoSearcher.php +++ b/src/Searcher/PdoSearcher.php @@ -226,6 +226,14 @@ public function stats() return $row; } + /** + * {@inheritdoc} + */ + public function getAllServerNames(): ?array + { + return null; + } + /** * {@inheritdoc} */ diff --git a/src/Searcher/SearcherInterface.php b/src/Searcher/SearcherInterface.php index 8444204f6..f71dfcba9 100644 --- a/src/Searcher/SearcherInterface.php +++ b/src/Searcher/SearcherInterface.php @@ -140,4 +140,11 @@ public function truncateWatches(); * @return array array of stats */ public function stats(); + + /** + * Get all the known server names. + * + * @return array|null array of server names or null if not supported + */ + public function getAllServerNames(): ?array; } diff --git a/templates/runs/list.twig b/templates/runs/list.twig index 90e763988..95ad82192 100644 --- a/templates/runs/list.twig +++ b/templates/runs/list.twig @@ -30,7 +30,16 @@
- + {% if server_names is iterable %} + + {% else %} + + {% endif %}
diff --git a/tests/Searcher/MongoTest.php b/tests/Searcher/MongoTest.php index 0ccb7f94f..af8f5fbf2 100644 --- a/tests/Searcher/MongoTest.php +++ b/tests/Searcher/MongoTest.php @@ -254,4 +254,12 @@ public function testTruncateWatchesPreserveIndexes(): void $this->assertEquals($options['name'], $name); } } + + public function testGetAllServerNames(): void + { + $result = $this->mongo->getAllServerNames(); + $this->assertCount(2, $result); + $this->assertContains('localhost', $result); + $this->assertContains('foo', $result); + } } diff --git a/tests/fixtures/normalized.json b/tests/fixtures/normalized.json index 9f70b74f9..56f27cbe4 100644 --- a/tests/fixtures/normalized.json +++ b/tests/fixtures/normalized.json @@ -279,5 +279,25 @@ "pmu": 0 } } + }, + { + "_id": "aaaaaaaaaaaaaaaaaaaaaab2", + "meta": { + "url": "/bar", + "simple_url": "/bar", + "get": [], + "env": [], + "SERVER": {"REQUEST_TIME": 1358614812, "SERVER_NAME": "foo", "REQUEST_METHOD": "GET"}, + "request_ts_micro": {"sec": 1358614812, "usec": 123456} + }, + "profile": { + "main()": { + "ct": 1, + "wt": 10, + "cpu": 12, + "mu": 3000, + "pmu": 3001 + } + } } ]