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

Commit

Permalink
add 2.1 api endpoints
Browse files Browse the repository at this point in the history
Signed-off-by: Jan Klat <[email protected]>
  • Loading branch information
klatys committed May 31, 2018
1 parent 9431f2a commit c8b033a
Show file tree
Hide file tree
Showing 11 changed files with 198 additions and 40 deletions.
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@

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

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

## Instalation
Use composer to add PApi as dependency:
Expand Down Expand Up @@ -43,15 +44,15 @@ Use composer to add PApi as dependency:

### Available calls
PApi currently has methods for all available endpoints provided by Prometheus.
#### Query
$client->getQuery('up', new \DateTimeImmutable('now');
#### QueryRange
$client->getQueryRange('up', new \DateTimeImmutable('today'), new \DateTimeImmutable('now'), '12h');
#### Series
$client->getSeries(['up'], new \DateTimeImmutable('-1 minute'), new \DateTimeImmutable('now'));
#### Label Values
$client->getLabelValues('job');
#### Targets (active only)
$client->getTargets();
#### Alert Managers
$client->getAlertManagers();

| Call | Code | Prometheus compatibility | Official doc |
| --------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------------------ |
| Query | `$client->getQuery('up', new \DateTimeImmutable('now');` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#instant-queries) |
| 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) |
| 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) |
| Label Values | `$client->getLabelValues('job');` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#querying-label-values) |
| Targets (active only) | `$client->getTargets();` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#targets) |
| Alert Managers | `$client->getAlertManagers();` | >=1.0 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#alertmanagers) |
| Create snapshot | `$client->createSnapshot();` | >=2.1 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#snapshot) |
| 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) |
| Clean tombstones | `$client->cleanTombstones();` | >=2.1 | [doc](https://prometheus.io/docs/prometheus/2.1/querying/api/#clean-tombstones) |
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
},
"require-dev": {
"cdn77/coding-standard": "^0.5",
"guzzlehttp/guzzle": "^6.3",
"phpstan/phpstan": "^0.9",
"phpstan/phpstan-strict-rules": "^0.9",
"phpunit/phpunit": "^6.3",
Expand Down
43 changes: 37 additions & 6 deletions src/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ public function connect() : void

public function getAlertManagers() : DataResponse
{
return DataResponseMeta::fromJson($this->connection->execute('alertmanagers'));
return DataResponseMeta::fromJson($this->connection->executeGet('alertmanagers'));
}

public function getTargets() : DataResponse
{
return DataResponseMeta::fromJson($this->connection->execute('targets'));
return DataResponseMeta::fromJson($this->connection->executeGet('targets'));
}

public function getLabelValues(string $label) : ArrayValuesResponse
{
return ArrayValuesResponseMeta::fromJson(
$this->connection->execute('label/' . urlencode($label) . '/values')
$this->connection->executeGet('label/' . urlencode($label) . '/values')
);
}

Expand All @@ -69,7 +69,7 @@ public function getLabelValues(string $label) : ArrayValuesResponse
public function getSeries(array $match, \DateTimeInterface $start, \DateTimeInterface $end) : ArrayValuesResponse
{
return ArrayValuesResponseMeta::fromJson(
$this->connection->execute('series', [
$this->connection->executeGet('series', [
'match' => array_values($match),
'start' => $start->format(self::DATETIME_FORMAT),
'end' => $end->format(self::DATETIME_FORMAT),
Expand All @@ -89,7 +89,7 @@ public function getQueryRange(
}

return DataResponseMeta::fromJson(
$this->connection->execute('query_range', [
$this->connection->executeGet('query_range', [
'query' => $query,
'start' => $start->format(self::DATETIME_FORMAT),
'end' => $end->format(self::DATETIME_FORMAT),
Expand All @@ -109,11 +109,42 @@ public function getQuery(
}

return DataResponseMeta::fromJson(
$this->connection->execute('query', [
$this->connection->executeGet('query', [
'query' => $query,
'time' => $time->format(self::DATETIME_FORMAT),
'timeout' => $timeout,
])
);
}

/**
* Make sure to enable admin APIs via `--web.enable-admin-api`
*/
public function createSnapshot() : DataResponse
{
return DataResponseMeta::fromJson($this->connection->executePost('admin/tsdb/snapshot'));
}

/**
* Make sure to enable admin APIs via `--web.enable-admin-api`
* @param string[] $match
*/
public function deleteSeries(array $match, \DateTimeInterface $start, \DateTimeInterface $end) : bool
{
$this->connection->executePost('admin/tsdb/delete_series', [
'match' => array_values($match),
'start' => $start->format(self::DATETIME_FORMAT),
'end' => $end->format(self::DATETIME_FORMAT),
]);
return true;
}

/**
* Make sure to enable admin APIs via `--web.enable-admin-api`
*/
public function cleanTombstones() : bool
{
$this->connection->executePost('admin/tsdb/clean_tombstones');
return true;
}
}
7 changes: 6 additions & 1 deletion src/Connection/ConnectionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ public function create(array $config) : self;
/**
* @param mixed[] $query
*/
public function execute(string $endPoint, array $query = []) : string;
public function executeGet(string $endPoint, array $query = []) : string;

/**
* @param mixed[] $query
*/
public function executePost(string $endPoint, array $query = []) : string;
}
67 changes: 52 additions & 15 deletions src/Connection/CurlConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,38 @@ public function create(array $config) : ConnectionInterface
/**
* @param mixed[] $query
*/
public function execute(string $endPoint, array $query = []) : string
public function executeGet(string $endPoint, array $query = []) : string
{
if ($this->connection === null) {
$this->connect();
}
curl_reset($this->connection);
$url = $this->prepareConnection($endPoint, $query);

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

curl_setopt($this->connection, CURLOPT_URL, $url);
curl_setopt($this->connection, CURLOPT_TIMEOUT, $this->config['timeout']);
curl_setopt($this->connection, CURLOPT_RETURNTRANSFER, true);
$curlHeaders = array_map(function ($key, $value) {
return $key . ':' . $value;
}, $this->config['connectionHeaders']);
curl_setopt($this->connection, CURLOPT_HTTPHEADER, $curlHeaders);
return $response;
}

/**
* @param mixed[] $query
*/
public function executePost(string $endPoint, array $query = []) : string
{
if ($this->connection === null) {
$this->connect();
}
$url = $this->prepareConnection($endPoint, $query);
curl_setopt($this->connection, CURLOPT_POST, 1);

$response = curl_exec($this->connection);
if ($response === false) {
Expand Down Expand Up @@ -117,4 +128,30 @@ private function getBaseUriParts() : array
'pass' => $this->config['password'],
];
}

/**
* @param mixed[] $query
*/
protected function prepareConnection(string $endPoint, array $query = []) : string
{
curl_reset($this->connection);

$uriParts = $this->getBaseUriParts();
$uriParts['path'] .= $endPoint;
if (!empty($query)) {
$queryParameters = http_build_query($query);
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);
$uriParts['query'] = $queryString;
}
$url = $this->buildUrl($uriParts);

curl_setopt($this->connection, CURLOPT_URL, $url);
curl_setopt($this->connection, CURLOPT_TIMEOUT, $this->config['timeout']);
curl_setopt($this->connection, CURLOPT_RETURNTRANSFER, true);
$curlHeaders = array_map(function ($key, $value) {
return $key . ':' . $value;
}, $this->config['connectionHeaders']);
curl_setopt($this->connection, CURLOPT_HTTPHEADER, $curlHeaders);
return $url;
}
}
25 changes: 21 additions & 4 deletions src/Connection/GuzzleConnection.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,23 @@ public function create(array $config) : ConnectionInterface
/**
* @param mixed[] $query
*/
public function execute(string $endPoint, array $query = []) : string
public function executeGet(string $endPoint, array $query = []) : string
{
return $this->executeRequest('GET', $endPoint, $query);
}

/**
* @param mixed[] $query
*/
public function executePost(string $endPoint, array $query = []) : string
{
return $this->executeRequest('POST', $endPoint, $query);
}

/**
* @param mixed[] $query
*/
private function executeRequest(string $method, string $endPoint, array $query = []) : string
{
if ($this->client === null) {
$this->connect();
Expand All @@ -60,21 +76,22 @@ public function execute(string $endPoint, array $query = []) : string
$queryString = preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '%5B%5D=', $queryParameters);

$response = $this->client->request(
'GET',
$method,
$endPoint,
[
'query' => $queryString,
]
);

if ($response->getStatusCode() !== 200) {
if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 204) {
$parts = parse_url($this->getBaseUri());
$parts['path'] = $parts['path'] . $endPoint;
$parts['query'] = http_build_query($query);
$uri = Uri::fromParts($parts);
throw new ConnectionException(
sprintf(
'Request GET `%s` returned with code %d and message `%s`',
'Request %s `%s` returned with code %d and message `%s`',
$method,
(string) $uri,
$response->getStatusCode(),
$response->getBody()->getContents()
Expand Down
2 changes: 1 addition & 1 deletion src/PApiMetaSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ protected function configure() : void
$jsonModule = new JsonModule();

$phpModule->addPropertySerializer(new DateTimeFormattingSerializer(
'Y-m-d\TH:i:s.uP',
'Y-m-d\TH:i:s.u???P',
\DateTimeImmutable::class,
'0001-01-01T00:00:00Z'
));
Expand Down
43 changes: 43 additions & 0 deletions src/Response/Meta/ResponseDataMeta.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class ResponseDataMeta extends ResponseData implements MetaInterface, PhpMetaInt
const RESULT = 'result';
const ACTIVE_TARGETS = 'activeTargets';
const ACTIVE_ALERTMANAGERS = 'activeAlertmanagers';
const NAME = 'name';

/** @var ResponseDataMeta */
private static $instance;
Expand Down Expand Up @@ -113,6 +114,7 @@ public static function reset($object)
$object->result = NULL;
$object->activeTargets = NULL;
$object->activeAlertmanagers = NULL;
$object->name = NULL;
}


Expand Down Expand Up @@ -159,6 +161,11 @@ public static function hash($object, $algoOrCtx = 'md5', $raw = false)
}
}

if (isset($object->name)) {
hash_update($ctx, 'name');
hash_update($ctx, (string)$object->name);
}

if (is_string($algoOrCtx)) {
return hash_final($ctx, $raw);
} else {
Expand Down Expand Up @@ -266,6 +273,17 @@ public static function fromArray($input, $group = null, $object = null)
$object->activeAlertmanagers = null;
}

if (($id & 1) > 0 && isset($input['name'])) {
$object->name = $input['name'];
} elseif (($id & 1) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
$object->name = null;
}
if (($id & 2) > 0 && isset($input['name'])) {
$object->name = $input['name'];
} elseif (($id & 2) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
$object->name = null;
}

return $object;
}

Expand Down Expand Up @@ -367,6 +385,13 @@ public static function toArray($object, $group = null, $filter = null)
}
}

if (($id & 1) > 0 && ($filter === null || isset($filter['name']))) {
$output['name'] = $object->name;
}
if (($id & 2) > 0 && ((isset($object->name) && $filter === null) || isset($filter['name']))) {
$output['name'] = $object->name;
}

} catch (\Exception $e) {
Stack::$objects->detach($object);
throw $e;
Expand Down Expand Up @@ -478,6 +503,17 @@ public static function fromObject($input, $group = null, $object = null)
$object->activeAlertmanagers = null;
}

if (($id & 1) > 0 && isset($input['name'])) {
$object->name = $input['name'];
} elseif (($id & 1) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
$object->name = null;
}
if (($id & 2) > 0 && isset($input['name'])) {
$object->name = $input['name'];
} elseif (($id & 2) > 0 && array_key_exists('name', $input) && $input['name'] === null) {
$object->name = null;
}

return $object;
}

Expand Down Expand Up @@ -579,6 +615,13 @@ public static function toObject($object, $group = null, $filter = null)
}
}

if (($id & 1) > 0 && ($filter === null || isset($filter['name']))) {
$output['name'] = $object->name;
}
if (($id & 2) > 0 && ((isset($object->name) && $filter === null) || isset($filter['name']))) {
$output['name'] = $object->name;
}

} catch (\Exception $e) {
Stack::$objects->detach($object);
throw $e;
Expand Down
8 changes: 8 additions & 0 deletions src/Response/ResponseData.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ class ResponseData
/** @var AlertManager[] */
protected $activeAlertmanagers;

/** @var string */
protected $name;

public function getResultType() : string
{
return $this->resultType;
Expand All @@ -49,4 +52,9 @@ public function getActiveAlertmanagers() : array
{
return $this->activeAlertmanagers;
}

public function getName() : string
{
return $this->name;
}
}
Loading

0 comments on commit c8b033a

Please sign in to comment.