From 545ae6a9980ad7bf1890c4db0051515418b88d45 Mon Sep 17 00:00:00 2001 From: Antoine Pultier <45740+fungiboletus@users.noreply.github.com> Date: Wed, 28 Jun 2023 19:44:08 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=8C=88=20Implement=20all=20the=20promethe?= =?UTF-8?q?us=20resolvers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../prometheus/query-prometheus-resolver.ts | 46 ++++++++++++ controller/src/server/resolvers.ts | 73 +++++++++++-------- controller/src/server/schema.graphql | 2 - controller/src/server/schema.ts | 20 ----- 4 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 controller/src/prometheus/query-prometheus-resolver.ts diff --git a/controller/src/prometheus/query-prometheus-resolver.ts b/controller/src/prometheus/query-prometheus-resolver.ts new file mode 100644 index 00000000..a593b01d --- /dev/null +++ b/controller/src/prometheus/query-prometheus-resolver.ts @@ -0,0 +1,46 @@ +import queryPrometheus from './prometheus.js'; +import type { DryRunNodeMetrics, DryRunNodePod } from '../server/schema.js'; + +type QueryPrometheusArguments = { + end?: number | null; + start?: number | null; + step?: number | null; +}; + +type DryRunNodeMetricsWithoutTypeName = Omit; +export default async function queryPrometheusResolver< + M extends keyof DryRunNodeMetricsWithoutTypeName, +>( + metric: string, + dryRunNodeMetrics: DryRunNodeMetrics & { dryRunNode: DryRunNodePod }, + _arguments: QueryPrometheusArguments, +): Promise { + const { dryRunNode } = dryRunNodeMetrics; + let { step } = _arguments; + const { startedAt, finishedAt, podName } = dryRunNode; + if (!startedAt) { + return undefined; + } + + // We have a 10s offset to avoid most clock drifts. + const startTimestamp = new Date(startedAt).getTime() / 1000 - 10; + + const endTimestamp = finishedAt + ? new Date(finishedAt).getTime() / 1000 + 10 + : Date.now() / 1000 + 10; + + if (!step) { + step = Math.ceil((endTimestamp - startTimestamp) / 1000); + } + + const data = await queryPrometheus(metric, { + container_name: 'main', + pod_name: podName, + }, startTimestamp, endTimestamp, step); + + return data.flatMap(({ values }) => values) + .map(([timestamp, value]) => ({ + timestamp, + value, + })); +} diff --git a/controller/src/server/resolvers.ts b/controller/src/server/resolvers.ts index 902e2a33..0f8fcf61 100644 --- a/controller/src/server/resolvers.ts +++ b/controller/src/server/resolvers.ts @@ -19,7 +19,7 @@ import { createProject, deleteProject, getProject, projects, renameProject, } from '../k8s/projects.js'; import { computePresignedPutUrl } from '../minio/minio.js'; -import queryPrometheus from '../prometheus/prometheus.js'; +import queryPrometheusResolver from '../prometheus/query-prometheus-resolver.js'; import { PingError } from './apollo-errors.js'; import type { ArgoWorkflow } from '../argo/argo-client.js'; import type ArgoWorkflowClient from '../argo/argo-client.js'; @@ -393,39 +393,54 @@ const resolvers = { }, }, DryRunNodeMetrics: { + /* Verbose way of doing the resolver. */ async cpuSystemSecondsTotal( dryRunNodeMetrics: DryRunNodeMetrics & { dryRunNode: DryRunNodePod }, _arguments: DryRunNodeMetricsCpuSystemSecondsTotalArguments, ): Promise { - const { dryRunNode } = dryRunNodeMetrics; - let { step } = _arguments; - const { startedAt, finishedAt, podName } = dryRunNode; - if (!startedAt) { - return []; - } - - // We have a 10s offset to avoid most clock drifts. - const startTimestamp = new Date(startedAt).getTime() / 1000 - 10; - - const endTimestamp = finishedAt - ? new Date(finishedAt).getTime() / 1000 + 10 - : Date.now() / 1000 + 10; - - if (!step) { - step = Math.ceil((endTimestamp - startTimestamp) / 1000); - } - - const data = await queryPrometheus('simpipe_cpu_system_seconds_total', { - container_name: 'main', - pod_name: podName, - }, startTimestamp, endTimestamp, step); - - return data.flatMap(({ values }) => values) - .map(([timestamp, value]) => ({ - timestamp, - value, - })); + return await queryPrometheusResolver<'cpuSystemSecondsTotal'>('simpipe_cpu_system_seconds_total', dryRunNodeMetrics, _arguments); }, + /* More concise way. The previous way is to explain what we are doing. */ + cpuUsageSecondsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_cpu_usage_seconds_total'), + cpuUserSecondsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_cpu_user_seconds_total'), + fileDescriptors: queryPrometheusResolver.bind(undefined, 'simpipe_file_descriptors'), + fsInodesFree: queryPrometheusResolver.bind(undefined, 'simpipe_fs_inodes_free'), + fsInodesTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_inodes_total'), + fsIoCurrent: queryPrometheusResolver.bind(undefined, 'simpipe_fs_io_current'), + fsIoTimeSecondsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_io_time_seconds_total'), + fsIoTimeWeightedSecondsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_io_time_weighted_seconds_total'), + fsLimitBytes: queryPrometheusResolver.bind(undefined, 'simpipe_fs_limit_bytes'), + fsReadSecondsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_read_seconds_total'), + fsReadsMergedTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_reads_merged_total'), + fsReadsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_reads_total'), + fsSectorReadsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_sector_reads_total'), + fsSectorWritesTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_sector_writes_total'), + fsUsageBytes: queryPrometheusResolver.bind(undefined, 'simpipe_fs_usage_bytes'), + fsWriteSecondsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_write_seconds_total'), + fsWritesMergedTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_writes_merged_total'), + fsWritesTotal: queryPrometheusResolver.bind(undefined, 'simpipe_fs_writes_total'), + memoryCache: queryPrometheusResolver.bind(undefined, 'simpipe_memory_cache'), + memoryFailcnt: queryPrometheusResolver.bind(undefined, 'simpipe_memory_failcnt'), + memoryFailuresTotal: queryPrometheusResolver.bind(undefined, 'simpipe_memory_failures_total'), + memoryMappedFile: queryPrometheusResolver.bind(undefined, 'simpipe_memory_mapped_file'), + memoryMaxUsageBytes: queryPrometheusResolver.bind(undefined, 'simpipe_memory_max_usage_bytes'), + memoryRss: queryPrometheusResolver.bind(undefined, 'simpipe_memory_rss'), + memorySwap: queryPrometheusResolver.bind(undefined, 'simpipe_memory_swap'), + memoryUsageBytes: queryPrometheusResolver.bind(undefined, 'simpipe_memory_usage_bytes'), + memoryWorkingSetBytes: queryPrometheusResolver.bind(undefined, 'simpipe_memory_working_set_bytes'), + networkReceiveBytesTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_receive_bytes_total'), + networkReceiveErrorsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_receive_errors_total'), + networkReceivePacketsDroppedTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_receive_packets_dropped_total'), + networkReceivePacketsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_receive_packets_total'), + networkTransmitBytesTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_transmit_bytes_total'), + networkTransmitErrorsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_transmit_errors_total'), + networkTransmitPacketsDroppedTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_transmit_packets_dropped_total'), + networkTransmitPacketsTotal: queryPrometheusResolver.bind(undefined, 'simpipe_network_transmit_packets_total'), + processes: queryPrometheusResolver.bind(undefined, 'simpipe_processes'), + sockets: queryPrometheusResolver.bind(undefined, 'simpipe_sockets'), + threads: queryPrometheusResolver.bind(undefined, 'simpipe_threads'), + threadsMax: queryPrometheusResolver.bind(undefined, 'simpipe_threads_max'), + ulimitsSoft: queryPrometheusResolver.bind(undefined, 'simpipe_ulimits_soft'), }, }; diff --git a/controller/src/server/schema.graphql b/controller/src/server/schema.graphql index 84880cc9..38c7587c 100644 --- a/controller/src/server/schema.graphql +++ b/controller/src/server/schema.graphql @@ -260,8 +260,6 @@ type DryRunNodeMetrics { networkTransmitPacketsTotal(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] processes(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] sockets(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] - specCpuPeriod(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] - specCpuShares(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] threads(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] threadsMax(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] ulimitsSoft(start: TimeStamp, end: TimeStamp, step: Int): [PrometheusSample!] diff --git a/controller/src/server/schema.ts b/controller/src/server/schema.ts index 05dbe2b1..7a8f7b7b 100644 --- a/controller/src/server/schema.ts +++ b/controller/src/server/schema.ts @@ -176,8 +176,6 @@ export type DryRunNodeMetrics = { networkTransmitPacketsTotal?: Maybe>; processes?: Maybe>; sockets?: Maybe>; - specCpuPeriod?: Maybe>; - specCpuShares?: Maybe>; threads?: Maybe>; threadsMax?: Maybe>; ulimitsSoft?: Maybe>; @@ -488,22 +486,6 @@ export type DryRunNodeMetricsSocketsArgs = { }; -/** Prometheus metrics for the node. */ -export type DryRunNodeMetricsSpecCpuPeriodArgs = { - end?: InputMaybe; - start?: InputMaybe; - step?: InputMaybe; -}; - - -/** Prometheus metrics for the node. */ -export type DryRunNodeMetricsSpecCpuSharesArgs = { - end?: InputMaybe; - start?: InputMaybe; - step?: InputMaybe; -}; - - /** Prometheus metrics for the node. */ export type DryRunNodeMetricsThreadsArgs = { end?: InputMaybe; @@ -1008,8 +990,6 @@ export type DryRunNodeMetricsResolvers>, ParentType, ContextType, Partial>; processes?: Resolver>, ParentType, ContextType, Partial>; sockets?: Resolver>, ParentType, ContextType, Partial>; - specCpuPeriod?: Resolver>, ParentType, ContextType, Partial>; - specCpuShares?: Resolver>, ParentType, ContextType, Partial>; threads?: Resolver>, ParentType, ContextType, Partial>; threadsMax?: Resolver>, ParentType, ContextType, Partial>; ulimitsSoft?: Resolver>, ParentType, ContextType, Partial>;