diff --git a/src/main/cluster.ts b/src/main/cluster.ts index 043e4c5b99..d57919fbba 100644 --- a/src/main/cluster.ts +++ b/src/main/cluster.ts @@ -503,13 +503,22 @@ export class Cluster implements ClusterModel, ClusterState { return url; } - protected k8sRequest(url: URL, options: OptionsOfJSONResponseBody = {}): Promise { + protected async k8sRequest(url: URL, options: OptionsOfJSONResponseBody = {}): Promise { options.timeout ??= 5000; options.headers ??= {}; options.headers["content-type"] ??= "application/json"; options.headers.host ??= `${this.id}.${this.kubeProxyUrl.host}`; // required in ClusterManager.getClusterForRequest() - return got(url, options).json(); + try { + console.log(url, options); + const res = await got(url, options); + + return JSON.parse(String(res.body)); + } catch (error) { + logger.error(`[REQUEST]: failed to get ${url}`, { error }); + + throw error; + } } getMetrics(prometheusPath: string, searchParams: Record) { @@ -517,7 +526,7 @@ export class Cluster implements ClusterModel, ClusterState { const metricsPath = `/api/v1/namespaces/${prometheusPath}/proxy${prometheusPrefix}/api/v1/query_range`; return this.k8sRequest(this.getUrlTo(metricsPath), { - timeout: 0, + timeout: 10000, method: "POST", form: searchParams, }); diff --git a/src/main/routes/metrics-route.ts b/src/main/routes/metrics-route.ts index b5d90d183e..cc660b0f48 100644 --- a/src/main/routes/metrics-route.ts +++ b/src/main/routes/metrics-route.ts @@ -1,45 +1,23 @@ -import _ from "lodash"; import { LensApiRequest } from "../router"; import { LensApi } from "../lens-api"; import { Cluster, ClusterMetadataKey } from "../cluster"; import { ClusterPrometheusMetadata } from "../../common/cluster-store"; -import logger from "../logger"; import { PrometheusQueryKey } from "../prometheus/provider-registry"; +import logger from "../logger"; export interface MetricsQuery { [metricName: string]: string; } -function delay(ms: number) { - return new Promise(resolve => setTimeout(resolve, ms)); -} - -// This is used for backoff retry tracking. -const MAX_ATTEMPTS = 5; -const ATTEMPTS = [...(_.fill(Array(MAX_ATTEMPTS - 1), false)), true]; - // prometheus metrics loader async function loadMetrics(promQueries: string[], cluster: Cluster, prometheusPath: string, queryParams: Record): Promise { const queries = promQueries.map(p => p.trim()); const loaders = new Map>(); async function loadMetric(query: string): Promise { - async function loadMetricHelper(): Promise { - for (const [attempt, lastAttempt] of ATTEMPTS.entries()) { // retry - try { - return await cluster.getMetrics(prometheusPath, { query, ...queryParams }); - } catch (error) { - if (lastAttempt || (error?.statusCode >= 400 && error?.statusCode < 500)) { - logger.error("[Metrics]: metrics not available", { error }); - throw new Error("Metrics not available"); - } + const searchParams = { query, ...queryParams }; - await delay((attempt + 1) * 1000); // add delay before repeating request - } - } - } - - return loaders.get(query) ?? loaders.set(query, loadMetricHelper()).get(query); + return loaders.get(query) ?? loaders.set(query, cluster.getMetrics(prometheusPath, { searchParams, retry: 5 })).get(query); } return Promise.all(queries.map(loadMetric)); @@ -90,7 +68,9 @@ class MetricsRoute extends LensApi { this.respondJson(response, data); } prometheusMetadata.success = true; - } catch { + } catch (error) { + logger.error("[METRICS]: failed to load metrics", { error }); + prometheusMetadata.success = false; this.respondJson(response, {}); } finally {