|
|
|
|
@ -36,6 +36,8 @@ export interface PrometheusClient { |
|
|
|
|
// Note that the returned list can be a superset of those suggestions for the prefix (i.e., including ones without the
|
|
|
|
|
// prefix), as codemirror will filter these out when displaying suggestions to the user.
|
|
|
|
|
metricNames(prefix?: string): Promise<string[]>; |
|
|
|
|
// flags returns flag values that prometheus was configured with.
|
|
|
|
|
flags(): Promise<Record<string, string>>; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export interface CacheConfig { |
|
|
|
|
@ -209,6 +211,15 @@ export class HTTPPrometheusClient implements PrometheusClient { |
|
|
|
|
return this.labelValues('__name__'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
flags(): Promise<Record<string, string>> { |
|
|
|
|
return this.fetchAPI<Record<string, string>>(this.flagsEndpoint()).catch((error) => { |
|
|
|
|
if (this.errorHandler) { |
|
|
|
|
this.errorHandler(error); |
|
|
|
|
} |
|
|
|
|
return {}; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private fetchAPI<T>(resource: string, init?: RequestInit): Promise<T> { |
|
|
|
|
return this.fetchFn(this.url + resource, init) |
|
|
|
|
.then((res) => { |
|
|
|
|
@ -254,6 +265,10 @@ export class HTTPPrometheusClient implements PrometheusClient { |
|
|
|
|
private metricMetadataEndpoint(): string { |
|
|
|
|
return `${this.apiPrefix}/metadata`; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private flagsEndpoint(): string { |
|
|
|
|
return `${this.apiPrefix}/status/flags`; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
class Cache { |
|
|
|
|
@ -263,6 +278,7 @@ class Cache { |
|
|
|
|
private metricMetadata: Record<string, MetricMetadata[]>; |
|
|
|
|
private labelValues: LRUCache<string, string[]>; |
|
|
|
|
private labelNames: string[]; |
|
|
|
|
private flags: Record<string, string>; |
|
|
|
|
|
|
|
|
|
constructor(config?: CacheConfig) { |
|
|
|
|
const maxAge = config && config.maxAge ? config.maxAge : 5 * 60 * 1000; |
|
|
|
|
@ -270,6 +286,7 @@ class Cache { |
|
|
|
|
this.metricMetadata = {}; |
|
|
|
|
this.labelValues = new LRUCache<string, string[]>(maxAge); |
|
|
|
|
this.labelNames = []; |
|
|
|
|
this.flags = {}; |
|
|
|
|
if (config?.initialMetricList) { |
|
|
|
|
this.setLabelValues('__name__', config.initialMetricList); |
|
|
|
|
} |
|
|
|
|
@ -297,6 +314,14 @@ class Cache { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setFlags(flags: Record<string, string>): void { |
|
|
|
|
this.flags = flags; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getFlags(): Record<string, string> { |
|
|
|
|
return this.flags; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
setMetricMetadata(metadata: Record<string, MetricMetadata[]>): void { |
|
|
|
|
this.metricMetadata = metadata; |
|
|
|
|
} |
|
|
|
|
@ -388,7 +413,7 @@ export class CachedPrometheusClient implements PrometheusClient { |
|
|
|
|
|
|
|
|
|
return this.client.metricMetadata().then((metadata) => { |
|
|
|
|
this.cache.setMetricMetadata(metadata); |
|
|
|
|
return this.cache.getMetricMetadata(); |
|
|
|
|
return metadata; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -402,4 +427,16 @@ export class CachedPrometheusClient implements PrometheusClient { |
|
|
|
|
metricNames(): Promise<string[]> { |
|
|
|
|
return this.labelValues('__name__'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
flags(): Promise<Record<string, string>> { |
|
|
|
|
const cachedFlags = this.cache.getFlags(); |
|
|
|
|
if (cachedFlags && Object.keys(cachedFlags).length > 0) { |
|
|
|
|
return Promise.resolve(cachedFlags); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return this.client.flags().then((flags) => { |
|
|
|
|
this.cache.setFlags(flags); |
|
|
|
|
return flags; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|