Store prometheus cluster metadata based on metrics request responses (#1438)

* Store prometheus metadata for clusters based on metrics requests

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Use ClusterMetadataKey.PROMETEHUS as key

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Update metadata only if it is changed

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Use structural comparer as default for store sync reaction

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* No need to compare metadata as json anymore

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Use structural comparer only in cluster-store

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Refactoring

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* React only prometeheus preference changes to re-initialise prometheus connection

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Add missing semicolons

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Fix imports

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Report metrics status in cluster-report (#1443)

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Apply suggestions from code review

Co-authored-by: Sebastian Malton <sebastian@malton.name>
Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

* Fix logger reference

Signed-off-by: Lauri Nevala <lauri.nevala@gmail.com>

Co-authored-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Lauri NevalaandSebastian Malton authored and GitHub committed 2020-11-26 09:41:47 +02:00
1 parent 4e02e086a9
commit badabff90e
5 files changed
+60 -29

No files matched your search

+19 -9
View File
@@ -1,7 +1,9 @@
import _ from "lodash";
import { LensApiRequest } from "../router";
import { LensApi } from "../lens-api";
import { Cluster } from "../cluster";
import _ from "lodash";
import { Cluster, ClusterMetadataKey } from "../cluster";
import { ClusterPrometheusMetadata } from "../../common/cluster-store";
import logger from "../logger";
export type IMetricsQuery = string | string[] | {
[metricName: string]: string;
@@ -22,11 +24,9 @@ async function loadMetrics(promQueries: string[], cluster: Cluster, prometheusPa
try {
return await cluster.getMetrics(prometheusPath, { query, ...queryParams });
} catch (error) {
if (lastAttempt || error?.statusCode === 404) {
return {
status: error.toString(),
data: { result: [] },
};
if (lastAttempt || (error?.statusCode >= 400 && error?.statusCode < 500)) {
logger.error("[Metrics]: metrics not available", { error });
throw new Error("Metrics not available");
}
await new Promise(resolve => setTimeout(resolve, (attempt + 1) * 1000)); // add delay before repeating request
@@ -43,13 +43,19 @@ async function loadMetrics(promQueries: string[], cluster: Cluster, prometheusPa
class MetricsRoute extends LensApi {
async routeMetrics({ response, cluster, payload, query }: LensApiRequest) {
const queryParams: IMetricsQuery = Object.fromEntries(query.entries());
const prometheusMetadata: ClusterPrometheusMetadata = {};
try {
const [prometheusPath, prometheusProvider] = await Promise.all([
cluster.contextHandler.getPrometheusPath(),
cluster.contextHandler.getPrometheusProvider()
]);
prometheusMetadata.provider = prometheusProvider?.id;
prometheusMetadata.autoDetected = !cluster.preferences.prometheusProvider?.type;
if (!prometheusPath) {
prometheusMetadata.success = false;
this.respondJson(response, {});
return;
}
// return data in same structure as query
if (typeof payload === "string") {
const [data] = await loadMetrics([payload], cluster, prometheusPath, queryParams);
@@ -65,8 +71,12 @@ class MetricsRoute extends LensApi {
const data = Object.fromEntries(Object.keys(payload).map((metricName, i) => [metricName, result[i]]));
this.respondJson(response, data);
}
prometheusMetadata.success = true;
} catch {
prometheusMetadata.success = false;
this.respondJson(response, {});
} finally {
cluster.metadata[ClusterMetadataKey.PROMETHEUS] = prometheusMetadata;
}
}
}