From 9632b60faacf69af731e835faf8478737911bc53 Mon Sep 17 00:00:00 2001 From: Jan Brauer Date: Wed, 21 Sep 2016 14:58:29 +0200 Subject: [PATCH 1/7] Require guzzlehttp/guzzle ^6.2 --- README.md | 1 - composer.json | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d5e1ff0..ba705f7 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,6 @@ composer install Just start the nginx, fpm & Redis setup with docker-compose: ``` -composer require guzzlehttp/guzzle=~6.0 docker-compose up ``` Pick the adapter you want to test. diff --git a/composer.json b/composer.json index 121d587..3c49f70 100644 --- a/composer.json +++ b/composer.json @@ -11,13 +11,13 @@ } ], "require": { - "php": ">=5.6.3" + "php": ">=5.6.3", + "guzzlehttp/guzzle": "^6.2" }, "require-dev": { "phpunit/phpunit": "4.1.0" }, "suggest": { - "guzzlehttp/guzzle": "~6.0 for running the blackbox tests.", "ext-redis": "Required if using Redis.", "ext-apc": "Required if using APCu." }, From e8053e905411b511ad9a5e7a748c21386cc91cc4 Mon Sep 17 00:00:00 2001 From: Jan Brauer Date: Wed, 21 Sep 2016 15:32:46 +0200 Subject: [PATCH 2/7] Add PushGateway --- src/Prometheus/PushGateway.php | 54 ++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/Prometheus/PushGateway.php diff --git a/src/Prometheus/PushGateway.php b/src/Prometheus/PushGateway.php new file mode 100644 index 0000000..f96f882 --- /dev/null +++ b/src/Prometheus/PushGateway.php @@ -0,0 +1,54 @@ +host = $host; + } + + /** + * Pushes all metrics in a Collector, replacing all those with the same job. + * @param CollectorRegistry $collectorRegistry + * @param $job + * @param $groupingKey + */ + public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = null) + { + $url = "http://" . $this->host . "/metrics/job/" . $job; + if (!empty($groupingKey)) { + foreach ($groupingKey as $label => $value) { + $url .= "/" . $label . "/" . $value; + } + } + $renderer = new RenderTextFormat(); + $textData = $renderer->render($collectorRegistry->getMetricFamilySamples()); + $client = new Client(); + $response = $client->post($url, array( + 'headers' => array( + 'Content-Type' => RenderTextFormat::MIME_TYPE + ), + 'body' => $textData, + 'connect_timeout' => 10, + 'timeout' => 20, + )); + $statusCode = $response->getStatusCode(); + if ($statusCode != 202) { + $msg = "Unexpected status code " . $statusCode . " received from pushgateway " . $this->host . ": " . $response->getBody(); + throw new \RuntimeException($msg); + } + } + +} From 6fd50fc6701ba4d3ba372a427dcd02d7c7cbf6a1 Mon Sep 17 00:00:00 2001 From: Jan Brauer Date: Wed, 21 Sep 2016 15:32:56 +0200 Subject: [PATCH 3/7] Add example for PushGateway usage --- examples/pushgateway.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 examples/pushgateway.php diff --git a/examples/pushgateway.php b/examples/pushgateway.php new file mode 100644 index 0000000..e92baae --- /dev/null +++ b/examples/pushgateway.php @@ -0,0 +1,13 @@ +registerCounter('test', 'some_counter', 'it increases', ['type']); +$counter->incBy(6, ['blue']); + +$pushGateway = new \Prometheus\PushGateway('192.168.59.100:9091'); +$pushGateway->push($registry, 'my_job', array('instance'=>'foo')); From 1cf91077eed09cb06dafe2fd94405a583d185aae Mon Sep 17 00:00:00 2001 From: Jan Brauer Date: Wed, 21 Sep 2016 15:34:34 +0200 Subject: [PATCH 4/7] Rename host to address --- src/Prometheus/PushGateway.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Prometheus/PushGateway.php b/src/Prometheus/PushGateway.php index f96f882..6fb6a01 100644 --- a/src/Prometheus/PushGateway.php +++ b/src/Prometheus/PushGateway.php @@ -8,15 +8,15 @@ class PushGateway { - private $host; + private $address; /** * PushGateway constructor. - * @param $host string host name of the push gateway + * @param $address string host:port of the push gateway */ - public function __construct($host) + public function __construct($address) { - $this->host = $host; + $this->address = $address; } /** @@ -27,7 +27,7 @@ public function __construct($host) */ public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = null) { - $url = "http://" . $this->host . "/metrics/job/" . $job; + $url = "http://" . $this->address . "/metrics/job/" . $job; if (!empty($groupingKey)) { foreach ($groupingKey as $label => $value) { $url .= "/" . $label . "/" . $value; @@ -46,7 +46,7 @@ public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = )); $statusCode = $response->getStatusCode(); if ($statusCode != 202) { - $msg = "Unexpected status code " . $statusCode . " received from pushgateway " . $this->host . ": " . $response->getBody(); + $msg = "Unexpected status code " . $statusCode . " received from pushgateway " . $this->address . ": " . $response->getBody(); throw new \RuntimeException($msg); } } From e3d2de8da3233e6ea28831219785c36325fc3a4f Mon Sep 17 00:00:00 2001 From: Ilya Margolin Date: Wed, 21 Sep 2016 18:20:50 +0200 Subject: [PATCH 5/7] Add an integration test for PushGateway - runs BlackBox tests with docker-compose - adds a phpunit container (needed to avoid dependency cycle between php-fpm and nginx) - enables apcu on cli --- README.md | 4 +-- docker-compose.yml | 17 ++++++++++++ php-fpm/Dockerfile | 1 + php-fpm/docker-php-ext-apcu-cli.ini | 1 + tests/Test/BlackBoxPushGatewayTest.php | 36 ++++++++++++++++++++++++++ tests/Test/BlackBoxTest.php | 2 +- 6 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 php-fpm/docker-php-ext-apcu-cli.ini create mode 100644 tests/Test/BlackBoxPushGatewayTest.php diff --git a/README.md b/README.md index ba705f7..a8bb52a 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,6 @@ docker-compose up Pick the adapter you want to test. ``` -ADAPTER=redis vendor/bin/phpunit tests/Test/BlackBoxTest.php -ADAPTER=apc vendor/bin/phpunit tests/Test/BlackBoxTest.php +docker-compose run phpunit env ADAPTER=apc vendor/bin/phpunit tests/Test/ +docker-compose run phpunit env ADAPTER=redis vendor/bin/phpunit tests/Test/ ``` diff --git a/docker-compose.yml b/docker-compose.yml index 00dab20..43447ab 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,7 @@ php-fpm: - .:/var/www/html links: - redis + - pushgateway environment: - REDIS_HOST=redis @@ -18,3 +19,19 @@ redis: image: redis ports: - 6379:6379 + +pushgateway: + image: prom/pushgateway + ports: + - 9091:9091 + +phpunit: + build: php-fpm/ + volumes: + - .:/var/www/html + links: + - redis + - pushgateway + - nginx + environment: + - REDIS_HOST=redis diff --git a/php-fpm/Dockerfile b/php-fpm/Dockerfile index 0fbe56c..fc34512 100644 --- a/php-fpm/Dockerfile +++ b/php-fpm/Dockerfile @@ -4,3 +4,4 @@ RUN pecl install redis-2.2.8 && docker-php-ext-enable redis RUN pecl install apcu-4.0.11 && docker-php-ext-enable apcu COPY www.conf /usr/local/etc/php-fpm.d/ +COPY docker-php-ext-apcu-cli.ini /usr/local/etc/php/conf.d/ diff --git a/php-fpm/docker-php-ext-apcu-cli.ini b/php-fpm/docker-php-ext-apcu-cli.ini new file mode 100644 index 0000000..c376be0 --- /dev/null +++ b/php-fpm/docker-php-ext-apcu-cli.ini @@ -0,0 +1 @@ +apc.enable_cli = On diff --git a/tests/Test/BlackBoxPushGatewayTest.php b/tests/Test/BlackBoxPushGatewayTest.php new file mode 100644 index 0000000..cbe81cf --- /dev/null +++ b/tests/Test/BlackBoxPushGatewayTest.php @@ -0,0 +1,36 @@ +registerCounter('test', 'some_counter', 'it increases', ['type']); + $counter->incBy(6, ['blue']); + + $pushGateway = new PushGateway('pushgateway:9091'); + $pushGateway->push($registry, 'my_job', array('instance' => 'foo')); + + $httpClient = new Client(); + $metrics = $httpClient->get("http://pushgateway:9091/metrics")->getBody()->getContents(); + $this->assertContains( + '# HELP test_some_counter it increases +# TYPE test_some_counter counter +test_some_counter{instance="foo",job="my_job",type="blue"} 6', + $metrics + ); + } +} diff --git a/tests/Test/BlackBoxTest.php b/tests/Test/BlackBoxTest.php index daff9dd..d57f3a3 100644 --- a/tests/Test/BlackBoxTest.php +++ b/tests/Test/BlackBoxTest.php @@ -20,7 +20,7 @@ class BlackBoxTest extends PHPUnit_Framework_TestCase public function setUp() { $this->adapter = getenv('ADAPTER'); - $this->client = new Client(['base_uri' => 'http://192.168.59.100:8080/']); + $this->client = new Client(['base_uri' => 'http://nginx:80/']); $this->client->get('/examples/flush_adapter.php?adapter=' . $this->adapter); } From a186dd7d45587f59823a6c152faf298749dab228 Mon Sep 17 00:00:00 2001 From: Jan Brauer Date: Tue, 11 Oct 2016 08:58:04 +0200 Subject: [PATCH 6/7] Add pushAdd method --- src/Prometheus/PushGateway.php | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/Prometheus/PushGateway.php b/src/Prometheus/PushGateway.php index 6fb6a01..f957943 100644 --- a/src/Prometheus/PushGateway.php +++ b/src/Prometheus/PushGateway.php @@ -21,11 +21,35 @@ public function __construct($address) /** * Pushes all metrics in a Collector, replacing all those with the same job. + * Uses HTTP PUT. * @param CollectorRegistry $collectorRegistry * @param $job * @param $groupingKey */ public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = null) + { + $this->doPush($collectorRegistry, $job, $groupingKey, 'put'); + } + + /** + * Pushes all metrics in a Collector, replacing only previously pushed metrics of the same name and job. + * Uses HTTP POST. + * @param CollectorRegistry $collectorRegistry + * @param $job + * @param $groupingKey + */ + public function pushAdd(CollectorRegistry $collectorRegistry, $job, $groupingKey = null) + { + $this->doPush($collectorRegistry, $job, $groupingKey, 'post'); + } + + /** + * @param CollectorRegistry $collectorRegistry + * @param $job + * @param $groupingKey + * @param $method + */ + private function doPush(CollectorRegistry $collectorRegistry, $job, $groupingKey, $method) { $url = "http://" . $this->address . "/metrics/job/" . $job; if (!empty($groupingKey)) { @@ -36,7 +60,7 @@ public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = $renderer = new RenderTextFormat(); $textData = $renderer->render($collectorRegistry->getMetricFamilySamples()); $client = new Client(); - $response = $client->post($url, array( + $response = $client->request($method, $url, array( 'headers' => array( 'Content-Type' => RenderTextFormat::MIME_TYPE ), From 88fb86bec80829e2fe97829ac3cdf3a0cebac363 Mon Sep 17 00:00:00 2001 From: Jan Brauer Date: Tue, 11 Oct 2016 09:30:04 +0200 Subject: [PATCH 7/7] Implement delete method for Pushgateway --- src/Prometheus/PushGateway.php | 29 +++++++++++++++++++------- tests/Test/BlackBoxPushGatewayTest.php | 11 ++++++++++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/src/Prometheus/PushGateway.php b/src/Prometheus/PushGateway.php index f957943..a4a3fd2 100644 --- a/src/Prometheus/PushGateway.php +++ b/src/Prometheus/PushGateway.php @@ -28,7 +28,7 @@ public function __construct($address) */ public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = null) { - $this->doPush($collectorRegistry, $job, $groupingKey, 'put'); + $this->doRequest($collectorRegistry, $job, $groupingKey, 'put'); } /** @@ -40,7 +40,18 @@ public function push(CollectorRegistry $collectorRegistry, $job, $groupingKey = */ public function pushAdd(CollectorRegistry $collectorRegistry, $job, $groupingKey = null) { - $this->doPush($collectorRegistry, $job, $groupingKey, 'post'); + $this->doRequest($collectorRegistry, $job, $groupingKey, 'post'); + } + + /** + * Deletes metrics from the Pushgateway. + * Uses HTTP POST. + * @param $job + * @param $groupingKey + */ + public function delete($job, $groupingKey = null) + { + $this->doRequest(null, $job, $groupingKey, 'delete'); } /** @@ -49,7 +60,7 @@ public function pushAdd(CollectorRegistry $collectorRegistry, $job, $groupingKey * @param $groupingKey * @param $method */ - private function doPush(CollectorRegistry $collectorRegistry, $job, $groupingKey, $method) + private function doRequest(CollectorRegistry $collectorRegistry, $job, $groupingKey, $method) { $url = "http://" . $this->address . "/metrics/job/" . $job; if (!empty($groupingKey)) { @@ -57,17 +68,19 @@ private function doPush(CollectorRegistry $collectorRegistry, $job, $groupingKey $url .= "/" . $label . "/" . $value; } } - $renderer = new RenderTextFormat(); - $textData = $renderer->render($collectorRegistry->getMetricFamilySamples()); $client = new Client(); - $response = $client->request($method, $url, array( + $requestOptions = array( 'headers' => array( 'Content-Type' => RenderTextFormat::MIME_TYPE ), - 'body' => $textData, 'connect_timeout' => 10, 'timeout' => 20, - )); + ); + if ($method != 'delete') { + $renderer = new RenderTextFormat(); + $requestOptions['body'] = $renderer->render($collectorRegistry->getMetricFamilySamples()); + } + $response = $client->request($method, $url, $requestOptions); $statusCode = $response->getStatusCode(); if ($statusCode != 202) { $msg = "Unexpected status code " . $statusCode . " received from pushgateway " . $this->address . ": " . $response->getBody(); diff --git a/tests/Test/BlackBoxPushGatewayTest.php b/tests/Test/BlackBoxPushGatewayTest.php index cbe81cf..26490c6 100644 --- a/tests/Test/BlackBoxPushGatewayTest.php +++ b/tests/Test/BlackBoxPushGatewayTest.php @@ -29,6 +29,17 @@ public function pushGatewayShouldWork() $this->assertContains( '# HELP test_some_counter it increases # TYPE test_some_counter counter +test_some_counter{instance="foo",job="my_job",type="blue"} 6', + $metrics + ); + + $pushGateway->delete('my_job', array('instance' => 'foo')); + + $httpClient = new Client(); + $metrics = $httpClient->get("http://pushgateway:9091/metrics")->getBody()->getContents(); + $this->assertNotContains( + '# HELP test_some_counter it increases +# TYPE test_some_counter counter test_some_counter{instance="foo",job="my_job",type="blue"} 6', $metrics );