provide a way to override the apiPrefix in codemirror prom client + cleanup readme (#9384)

Signed-off-by: Augustin Husson <husson.augustin@gmail.com>
This commit is contained in:
Augustin Husson 2021-09-24 07:52:50 +02:00 committed by GitHub
parent acee8c8a88
commit 7bcca77340
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 29 deletions

View file

@ -172,6 +172,16 @@ You can change it to use the HTTP method `GET` if you prefer.
const promQL = new PromQLExtension().setComplete({ remote: { httpMethod: 'GET' } })
```
###### Override the API Prefix
The default Prometheus Client, when building the query to get data from Prometheus, is using an API prefix which is by default `/api/v1`.
You can override this value like this:
```typescript
const promql = new PromQLExtension().setComplete({ remote: { apiPrefix: '/my/api/prefix' } })
```
###### Cache
The default client has an embedded cache that is used to store the different metrics and labels retrieved from a remote
@ -232,7 +242,6 @@ Note: In case this parameter is provided, then the rest of the configuration is
### Example
* The development [app](./src/app) can give you an example of how to use it with no TS Framework.
* [ReactJS example](https://github.com/prometheus/prometheus/blob/431ea75a11ca165dad9dd5d629b3cf975f4c186b/web/ui/react-app/src/pages/graph/CMExpressionInput.tsx)
* [Angular example](https://github.com/perses/perses/blob/28b3bdac88b0ed7a4602f9c91106442eafcb6c34/internal/api/front/perses/src/app/project/prometheusrule/promql-editor/promql-editor.component.ts)
@ -242,24 +251,6 @@ Any contribution or suggestion would be really appreciated. Feel free
to [file an issue](https://github.com/prometheus-community/codemirror-promql/issues)
or [send a pull request](https://github.com/prometheus-community/codemirror-promql/pulls).
## Development
In case you want to contribute and change the code by yourself, run the following commands:
To install all dependencies:
```
npm install
```
To start the web server:
```
npm start
```
This should create a tab in your browser with the development app that contains CodeMirror Next with the PromQL plugin.
## License
[MIT](./LICENSE)

View file

@ -16,12 +16,6 @@ import { Matcher } from '../types';
import { labelMatchersToString } from '../parser';
import LRUCache from 'lru-cache';
const apiPrefix = '/api/v1';
const labelsEndpoint = apiPrefix + '/labels';
const labelValuesEndpoint = apiPrefix + '/label/:name/values';
const seriesEndpoint = apiPrefix + '/series';
const metricMetadataEndpoint = apiPrefix + '/metadata';
export interface MetricMetadata {
type: string;
help: string;
@ -61,6 +55,7 @@ export interface PrometheusConfig {
// cache will allow user to change the configuration of the cached Prometheus client (which is used by default)
cache?: CacheConfig;
httpMethod?: 'POST' | 'GET';
apiPrefix?: string;
}
interface APIResponse<T> {
@ -83,6 +78,7 @@ export class HTTPPrometheusClient implements PrometheusClient {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
private readonly errorHandler?: (error: any) => void;
private readonly httpMethod: 'POST' | 'GET' = 'POST';
private readonly apiPrefix: string = '/api/v1';
// For some reason, just assigning via "= fetch" here does not end up executing fetch correctly
// when calling it, thus the indirection via another function wrapper.
private readonly fetchFn: FetchFn = (input: RequestInfo, init?: RequestInit): Promise<Response> => fetch(input, init);
@ -99,6 +95,9 @@ export class HTTPPrometheusClient implements PrometheusClient {
if (config.httpMethod) {
this.httpMethod = config.httpMethod;
}
if (config.apiPrefix) {
this.apiPrefix = config.apiPrefix;
}
}
labelNames(metricName?: string): Promise<string[]> {
@ -106,7 +105,7 @@ export class HTTPPrometheusClient implements PrometheusClient {
const start = new Date(end.getTime() - this.lookbackInterval);
if (metricName === undefined || metricName === '') {
const request = this.buildRequest(
labelsEndpoint,
this.labelsEndpoint(),
new URLSearchParams({
start: start.toISOString(),
end: end.toISOString(),
@ -150,7 +149,7 @@ export class HTTPPrometheusClient implements PrometheusClient {
end: end.toISOString(),
});
// See https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values
return this.fetchAPI<string[]>(`${labelValuesEndpoint.replace(/:name/gi, labelName)}?${params}`).catch((error) => {
return this.fetchAPI<string[]>(`${this.labelValuesEndpoint().replace(/:name/gi, labelName)}?${params}`).catch((error) => {
if (this.errorHandler) {
this.errorHandler(error);
}
@ -175,7 +174,7 @@ export class HTTPPrometheusClient implements PrometheusClient {
}
metricMetadata(): Promise<Record<string, MetricMetadata[]>> {
return this.fetchAPI<Record<string, MetricMetadata[]>>(metricMetadataEndpoint).catch((error) => {
return this.fetchAPI<Record<string, MetricMetadata[]>>(this.metricMetadataEndpoint()).catch((error) => {
if (this.errorHandler) {
this.errorHandler(error);
}
@ -187,7 +186,7 @@ export class HTTPPrometheusClient implements PrometheusClient {
const end = new Date();
const start = new Date(end.getTime() - this.lookbackInterval);
const request = this.buildRequest(
seriesEndpoint,
this.seriesEndpoint(),
new URLSearchParams({
start: start.toISOString(),
end: end.toISOString(),
@ -239,6 +238,19 @@ export class HTTPPrometheusClient implements PrometheusClient {
}
return { uri, body };
}
private labelsEndpoint(): string {
return `${this.apiPrefix}/labels`;
}
private labelValuesEndpoint(): string {
return `${this.apiPrefix}/label/:name/values`;
}
private seriesEndpoint(): string {
return `${this.apiPrefix}/series`;
}
private metricMetadataEndpoint(): string {
return `${this.apiPrefix}/metadata`;
}
}
class Cache {