Skip to content
This repository was archived by the owner on Mar 19, 2020. It is now read-only.

Commit 921b656

Browse files
author
Jan Klat
committed
Merge branch 'prom-2.1' into 'master'
add 2.1 api endpoints See merge request klatys/papi!2
2 parents 9431f2a + c8b033a commit 921b656

File tree

11 files changed

+198
-40
lines changed

11 files changed

+198
-40
lines changed

README.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33

44
Targets to provide simple means for obtaining data from Prometheus API.
55

6-
Stable for [Prometheus 1.x and <= v2.0 api spec](https://prometheus.io/docs/prometheus/2.0/querying/api/)
6+
Stable for [Prometheus 1.x and <= v2.1 api spec](https://prometheus.io/docs/prometheus/2.1/querying/api/)
7+
NOTICE: some endpoints are only available in newer versions of Prometheus. For detailed list see [table of available calls](#available-calls) below.
78

89
## Instalation
910
Use composer to add PApi as dependency:
@@ -43,15 +44,15 @@ Use composer to add PApi as dependency:
4344

4445
### Available calls
4546
PApi currently has methods for all available endpoints provided by Prometheus.
46-
#### Query
47-
$client->getQuery('up', new \DateTimeImmutable('now');
48-
#### QueryRange
49-
$client->getQueryRange('up', new \DateTimeImmutable('today'), new \DateTimeImmutable('now'), '12h');
50-
#### Series
51-
$client->getSeries(['up'], new \DateTimeImmutable('-1 minute'), new \DateTimeImmutable('now'));
52-
#### Label Values
53-
$client->getLabelValues('job');
54-
#### Targets (active only)
55-
$client->getTargets();
56-
#### Alert Managers
57-
$client->getAlertManagers();
47+
48+
| Call | Code | Prometheus compatibility | Official doc |
49+
| --------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------------------ |
50+
| Query | `$client->getQuery('up', new \DateTimeImmutable('now');` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#instant-queries) |
51+
| QueryRange | `$client->getQueryRange('up', new \DateTimeImmutable('today'), new \DateTimeImmutable('now'), '12h');` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#range-queries) |
52+
| Series | `$client->getSeries(['up'], new \DateTimeImmutable('-1 minute'), new \DateTimeImmutable('now');` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#finding-series-by-label-matchers) |
53+
| Label Values | `$client->getLabelValues('job');` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#querying-label-values) |
54+
| Targets (active only) | `$client->getTargets();` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#targets) |
55+
| Alert Managers | `$client->getAlertManagers();` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#alertmanagers) |
56+
| Create snapshot | `$client->createSnapshot();` | >=2.1 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#snapshot) |
57+
| Delete series | `$client->deleteSeries(['up'], new DateTimeImmutable('today'), new DateTimeImmutable('now');` | >=2.1 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#delete-series) |
58+
| Clean tombstones | `$client->cleanTombstones();` | >=2.1 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#clean-tombstones) |

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
},
1313
"require-dev": {
1414
"cdn77/coding-standard": "^0.5",
15+
"guzzlehttp/guzzle": "^6.3",
1516
"phpstan/phpstan": "^0.9",
1617
"phpstan/phpstan-strict-rules": "^0.9",
1718
"phpunit/phpunit": "^6.3",

src/Client.php

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,18 @@ public function connect() : void
4848

4949
public function getAlertManagers() : DataResponse
5050
{
51-
return DataResponseMeta::fromJson($this->connection->execute('alertmanagers'));
51+
return DataResponseMeta::fromJson($this->connection->executeGet('alertmanagers'));
5252
}
5353

5454
public function getTargets() : DataResponse
5555
{
56-
return DataResponseMeta::fromJson($this->connection->execute('targets'));
56+
return DataResponseMeta::fromJson($this->connection->executeGet('targets'));
5757
}
5858

5959
public function getLabelValues(string $label) : ArrayValuesResponse
6060
{
6161
return ArrayValuesResponseMeta::fromJson(
62-
$this->connection->execute('label/' . urlencode($label) . '/values')
62+
$this->connection->executeGet('label/' . urlencode($label) . '/values')
6363
);
6464
}
6565

@@ -69,7 +69,7 @@ public function getLabelValues(string $label) : ArrayValuesResponse
6969
public function getSeries(array $match, \DateTimeInterface $start, \DateTimeInterface $end) : ArrayValuesResponse
7070
{
7171
return ArrayValuesResponseMeta::fromJson(
72-
$this->connection->execute('series', [
72+
$this->connection->executeGet('series', [
7373
'match' => array_values($match),
7474
'start' => $start->format(self::DATETIME_FORMAT),
7575
'end' => $end->format(self::DATETIME_FORMAT),
@@ -89,7 +89,7 @@ public function getQueryRange(
8989
}
9090

9191
return DataResponseMeta::fromJson(
92-
$this->connection->execute('query_range', [
92+
$this->connection->executeGet('query_range', [
9393
'query' => $query,
9494
'start' => $start->format(self::DATETIME_FORMAT),
9595
'end' => $end->format(self::DATETIME_FORMAT),
@@ -109,11 +109,42 @@ public function getQuery(
109109
}
110110

111111
return DataResponseMeta::fromJson(
112-
$this->connection->execute('query', [
112+
$this->connection->executeGet('query', [
113113
'query' => $query,
114114
'time' => $time->format(self::DATETIME_FORMAT),
115115
'timeout' => $timeout,
116116
])
117117
);
118118
}
119+
120+
/**
121+
* Make sure to enable admin APIs via `--web.enable-admin-api`
122+
*/
123+
public function createSnapshot() : DataResponse
124+
{
125+
return DataResponseMeta::fromJson($this->connection->executePost('admin/tsdb/snapshot'));
126+
}
127+
128+
/**
129+
* Make sure to enable admin APIs via `--web.enable-admin-api`
130+
* @param string[] $match
131+
*/
132+
public function deleteSeries(array $match, \DateTimeInterface $start, \DateTimeInterface $end) : bool
133+
{
134+
$this->connection->executePost('admin/tsdb/delete_series', [
135+
'match' => array_values($match),
136+
'start' => $start->format(self::DATETIME_FORMAT),
137+
'end' => $end->format(self::DATETIME_FORMAT),
138+
]);
139+
return true;
140+
}
141+
142+
/**
143+
* Make sure to enable admin APIs via `--web.enable-admin-api`
144+
*/
145+
public function cleanTombstones() : bool
146+
{
147+
$this->connection->executePost('admin/tsdb/clean_tombstones');
148+
return true;
149+
}
119150
}

src/Connection/ConnectionInterface.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,10 @@ public function create(array $config) : self;
1919
/**
2020
* @param mixed[] $query
2121
*/
22-
public function execute(string $endPoint, array $query = []) : string;
22+
public function executeGet(string $endPoint, array $query = []) : string;
23+
24+
/**
25+
* @param mixed[] $query
26+
*/
27+
public function executePost(string $endPoint, array $query = []) : string;
2328
}

src/Connection/CurlConnection.php

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,38 @@ public function create(array $config) : ConnectionInterface
3434
/**
3535
* @param mixed[] $query
3636
*/
37-
public function execute(string $endPoint, array $query = []) : string
37+
public function executeGet(string $endPoint, array $query = []) : string
3838
{
3939
if ($this->connection === null) {
4040
$this->connect();
4141
}
42-
curl_reset($this->connection);
42+
$url = $this->prepareConnection($endPoint, $query);
4343

44-
$queryParameters = http_build_query($query);
45-
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);
46-
$uriParts = $this->getBaseUriParts();
47-
$uriParts['path'] .= $endPoint;
48-
$uriParts['query'] = $queryString;
49-
$url = $this->buildUrl($uriParts);
44+
$response = curl_exec($this->connection);
45+
if ($response === false) {
46+
throw new ConnectionException(
47+
sprintf(
48+
'Request GET %s returned with code %d and message `%s`',
49+
$url,
50+
curl_getinfo($this->connection, CURLINFO_RESPONSE_CODE),
51+
curl_error($this->connection)
52+
)
53+
);
54+
}
5055

51-
curl_setopt($this->connection, CURLOPT_URL, $url);
52-
curl_setopt($this->connection, CURLOPT_TIMEOUT, $this->config['timeout']);
53-
curl_setopt($this->connection, CURLOPT_RETURNTRANSFER, true);
54-
$curlHeaders = array_map(function ($key, $value) {
55-
return $key . ':' . $value;
56-
}, $this->config['connectionHeaders']);
57-
curl_setopt($this->connection, CURLOPT_HTTPHEADER, $curlHeaders);
56+
return $response;
57+
}
58+
59+
/**
60+
* @param mixed[] $query
61+
*/
62+
public function executePost(string $endPoint, array $query = []) : string
63+
{
64+
if ($this->connection === null) {
65+
$this->connect();
66+
}
67+
$url = $this->prepareConnection($endPoint, $query);
68+
curl_setopt($this->connection, CURLOPT_POST, 1);
5869

5970
$response = curl_exec($this->connection);
6071
if ($response === false) {
@@ -117,4 +128,30 @@ private function getBaseUriParts() : array
117128
'pass' => $this->config['password'],
118129
];
119130
}
131+
132+
/**
133+
* @param mixed[] $query
134+
*/
135+
protected function prepareConnection(string $endPoint, array $query = []) : string
136+
{
137+
curl_reset($this->connection);
138+
139+
$uriParts = $this->getBaseUriParts();
140+
$uriParts['path'] .= $endPoint;
141+
if (!empty($query)) {
142+
$queryParameters = http_build_query($query);
143+
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);
144+
$uriParts['query'] = $queryString;
145+
}
146+
$url = $this->buildUrl($uriParts);
147+
148+
curl_setopt($this->connection, CURLOPT_URL, $url);
149+
curl_setopt($this->connection, CURLOPT_TIMEOUT, $this->config['timeout']);
150+
curl_setopt($this->connection, CURLOPT_RETURNTRANSFER, true);
151+
$curlHeaders = array_map(function ($key, $value) {
152+
return $key . ':' . $value;
153+
}, $this->config['connectionHeaders']);
154+
curl_setopt($this->connection, CURLOPT_HTTPHEADER, $curlHeaders);
155+
return $url;
156+
}
120157
}

src/Connection/GuzzleConnection.php

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,23 @@ public function create(array $config) : ConnectionInterface
4949
/**
5050
* @param mixed[] $query
5151
*/
52-
public function execute(string $endPoint, array $query = []) : string
52+
public function executeGet(string $endPoint, array $query = []) : string
53+
{
54+
return $this->executeRequest('GET', $endPoint, $query);
55+
}
56+
57+
/**
58+
* @param mixed[] $query
59+
*/
60+
public function executePost(string $endPoint, array $query = []) : string
61+
{
62+
return $this->executeRequest('POST', $endPoint, $query);
63+
}
64+
65+
/**
66+
* @param mixed[] $query
67+
*/
68+
private function executeRequest(string $method, string $endPoint, array $query = []) : string
5369
{
5470
if ($this->client === null) {
5571
$this->connect();
@@ -60,21 +76,22 @@ public function execute(string $endPoint, array $query = []) : string
6076
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);
6177

6278
$response = $this->client->request(
63-
'GET',
79+
$method,
6480
$endPoint,
6581
[
6682
'query' => $queryString,
6783
]
6884
);
6985

70-
if ($response->getStatusCode() !== 200) {
86+
if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 204) {
7187
$parts = parse_url($this->getBaseUri());
7288
$parts['path'] = $parts['path'] . $endPoint;
7389
$parts['query'] = http_build_query($query);
7490
$uri = Uri::fromParts($parts);
7591
throw new ConnectionException(
7692
sprintf(
77-
'Request GET `%s` returned with code %d and message `%s`',
93+
'Request %s `%s` returned with code %d and message `%s`',
94+
$method,
7895
(string) $uri,
7996
$response->getStatusCode(),
8097
$response->getBody()->getContents()

src/PApiMetaSpec.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ protected function configure() : void
1919
$jsonModule = new JsonModule();
2020

2121
$phpModule->addPropertySerializer(new DateTimeFormattingSerializer(
22-
'Y-m-d\TH:i:s.uP',
22+
'Y-m-d\TH:i:s.u???P',
2323
\DateTimeImmutable::class,
2424
'0001-01-01T00:00:00Z'
2525
));

src/Response/Meta/ResponseDataMeta.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class ResponseDataMeta extends ResponseData implements MetaInterface, PhpMetaInt
2525
const RESULT = 'result';
2626
const ACTIVE_TARGETS = 'activeTargets';
2727
const ACTIVE_ALERTMANAGERS = 'activeAlertmanagers';
28+
const NAME = 'name';
2829

2930
/** @var ResponseDataMeta */
3031
private static $instance;
@@ -113,6 +114,7 @@ public static function reset($object)
113114
$object->result = NULL;
114115
$object->activeTargets = NULL;
115116
$object->activeAlertmanagers = NULL;
117+
$object->name = NULL;
116118
}
117119

118120

@@ -159,6 +161,11 @@ public static function hash($object, $algoOrCtx = 'md5', $raw = false)
159161
}
160162
}
161163

164+
if (isset($object->name)) {
165+
hash_update($ctx, 'name');
166+
hash_update($ctx, (string)$object->name);
167+
}
168+
162169
if (is_string($algoOrCtx)) {
163170
return hash_final($ctx, $raw);
164171
} else {
@@ -266,6 +273,17 @@ public static function fromArray($input, $group = null, $object = null)
266273
$object->activeAlertmanagers = null;
267274
}
268275

276+
if (($id & 1) > 0 && isset($input['name'])) {
277+
$object->name = $input['name'];
278+
} elseif (($id & 1) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
279+
$object->name = null;
280+
}
281+
if (($id & 2) > 0 && isset($input['name'])) {
282+
$object->name = $input['name'];
283+
} elseif (($id & 2) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
284+
$object->name = null;
285+
}
286+
269287
return $object;
270288
}
271289

@@ -367,6 +385,13 @@ public static function toArray($object, $group = null, $filter = null)
367385
}
368386
}
369387

388+
if (($id & 1) > 0 && ($filter === null || isset($filter['name']))) {
389+
$output['name'] = $object->name;
390+
}
391+
if (($id & 2) > 0 && ((isset($object->name) && $filter === null) || isset($filter['name']))) {
392+
$output['name'] = $object->name;
393+
}
394+
370395
} catch (\Exception $e) {
371396
Stack::$objects->detach($object);
372397
throw $e;
@@ -478,6 +503,17 @@ public static function fromObject($input, $group = null, $object = null)
478503
$object->activeAlertmanagers = null;
479504
}
480505

506+
if (($id & 1) > 0 && isset($input['name'])) {
507+
$object->name = $input['name'];
508+
} elseif (($id & 1) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
509+
$object->name = null;
510+
}
511+
if (($id & 2) > 0 && isset($input['name'])) {
512+
$object->name = $input['name'];
513+
} elseif (($id & 2) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
514+
$object->name = null;
515+
}
516+
481517
return $object;
482518
}
483519

@@ -579,6 +615,13 @@ public static function toObject($object, $group = null, $filter = null)
579615
}
580616
}
581617

618+
if (($id & 1) > 0 && ($filter === null || isset($filter['name']))) {
619+
$output['name'] = $object->name;
620+
}
621+
if (($id & 2) > 0 && ((isset($object->name) && $filter === null) || isset($filter['name']))) {
622+
$output['name'] = $object->name;
623+
}
624+
582625
} catch (\Exception $e) {
583626
Stack::$objects->detach($object);
584627
throw $e;

src/Response/ResponseData.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ class ResponseData
2323
/** @var AlertManager[] */
2424
protected $activeAlertmanagers;
2525

26+
/** @var string */
27+
protected $name;
28+
2629
public function getResultType() : string
2730
{
2831
return $this->resultType;
@@ -49,4 +52,9 @@ public function getActiveAlertmanagers() : array
4952
{
5053
return $this->activeAlertmanagers;
5154
}
55+
56+
public function getName() : string
57+
{
58+
return $this->name;
59+
}
5260
}

0 commit comments

Comments
 (0)