From adc1d94e3f76f0cfd8a844f3e4219785092eab50 Mon Sep 17 00:00:00 2001 From: Christoph Kluge Date: Fri, 31 Mar 2023 17:18:16 +0200 Subject: [PATCH] subcluster in metricSelect, add infobox to systems - Default: Show Clusters next to Metrics - New: If Cluster filter activem show subclusters instead (reactive) - add note to analysis view - systems view now with info boxes if metric is removed for subcluster --- internal/graph/schema.resolvers.go | 2 +- web/frontend/src/Analysis.root.svelte | 2 ++ web/frontend/src/Jobs.root.svelte | 13 +++++++-- web/frontend/src/MetricSelection.svelte | 23 +++++++++++++-- web/frontend/src/Systems.root.svelte | 38 ++++++++++++++++++------- web/frontend/src/User.root.svelte | 21 ++++++++++---- 6 files changed, 77 insertions(+), 22 deletions(-) diff --git a/internal/graph/schema.resolvers.go b/internal/graph/schema.resolvers.go index bdac26e..959853a 100644 --- a/internal/graph/schema.resolvers.go +++ b/internal/graph/schema.resolvers.go @@ -269,7 +269,7 @@ func (r *queryResolver) NodeMetrics(ctx context.Context, cluster string, nodes [ for _, scopedMetric := range scopedMetrics { host.Metrics = append(host.Metrics, &model.JobMetricWithName{ Name: metric, - Scope: schema.MetricScopeNode, // NodeMetrics allow fixed scope? + Scope: schema.MetricScopeNode, Metric: scopedMetric, }) } diff --git a/web/frontend/src/Analysis.root.svelte b/web/frontend/src/Analysis.root.svelte index 4d446a5..f40aca9 100644 --- a/web/frontend/src/Analysis.root.svelte +++ b/web/frontend/src/Analysis.root.svelte @@ -216,6 +216,7 @@ These histograms show the distribution of the averages of all jobs matching the filters. Each job/average is weighted by its node hours. + Note that some metrics could be disabled for specific subclusters as per metriConfig and thus could affect shown average values.
@@ -247,6 +248,7 @@ Each circle represents one job. The size of a circle is proportional to its node hours. Darker circles mean multiple jobs have the same averages for the respective metrics. + Note that some metrics could be disabled for specific subclusters as per metriConfig and thus could affect shown average values.
diff --git a/web/frontend/src/Jobs.root.svelte b/web/frontend/src/Jobs.root.svelte index 9ecaafa..478f63a 100644 --- a/web/frontend/src/Jobs.root.svelte +++ b/web/frontend/src/Jobs.root.svelte @@ -15,11 +15,15 @@ export let filterPresets = {} - let filters, jobList, matchedJobs = null + let filters = [] + let jobList, matchedJobs = null let sorting = { field: 'startTime', order: 'DESC' }, isSortingOpen = false, isMetricsSelectionOpen = false let metrics = filterPresets.cluster ? ccconfig[`plot_list_selectedMetrics:${filterPresets.cluster}`] || ccconfig.plot_list_selectedMetrics : ccconfig.plot_list_selectedMetrics + let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null + + $: selectedCluster = filters[0]?.cluster ? filters[0].cluster.eq : null // The filterPresets are handled by the Filters component, // so we need to wait for it to be ready before we can start a query. @@ -56,7 +60,10 @@ jobList.update(detail.filters)} /> + on:update={({ detail }) => { + filters = detail.filters + jobList.update(detail.filters)} + } /> @@ -82,7 +89,7 @@ bind:isOpen={isSortingOpen} /> diff --git a/web/frontend/src/MetricSelection.svelte b/web/frontend/src/MetricSelection.svelte index 85afe65..2985b62 100644 --- a/web/frontend/src/MetricSelection.svelte +++ b/web/frontend/src/MetricSelection.svelte @@ -95,7 +95,7 @@ (isOpen = !isOpen)}> - Configure columns + Configure columns (Metric availability shown) @@ -113,9 +113,26 @@ {/if} {metric} - {cluster == null ? clusters + {cluster == null ? + clusters // No single cluster specified: List Clusters with Metric .filter(cluster => cluster.metricConfig.find(m => m.name == metric) != null) - .map(cluster => cluster.name).join(', ') : ''} + .map(cluster => cluster.name).join(', ') : + clusters // Single cluster requested: List Subclusters with do not have metric remove flag + .filter(cluster => cluster.metricConfig.find(m => m.name == metric) != null) + .map(function(cluster) { + let scNames = cluster.subClusters.map(sc => sc.name) + scNames.forEach(function(scName){ + let met = cluster.metricConfig.find(m => m.name == metric) + let msc = met.subClusters.find(msc => msc.name == scName) + if (msc != null) { + if (msc.remove == true) { + scNames = scNames.filter(scn => scn != msc.name) + } + } + }) + return scNames + }) + .join(', ')} {/each} diff --git a/web/frontend/src/Systems.root.svelte b/web/frontend/src/Systems.root.svelte index 7058da2..93fa2f4 100644 --- a/web/frontend/src/Systems.root.svelte +++ b/web/frontend/src/Systems.root.svelte @@ -21,6 +21,7 @@ const clusters = getContext('clusters') const ccconfig = getContext('cc-config') + const metricConfig = getContext('metrics') let plotHeight = 300 let hostnameFilter = '' @@ -112,18 +113,35 @@ itemsPerRow={ccconfig.plot_view_plotsPerRow} items={$nodesQuery.data.nodeMetrics .filter(h => h.host.includes(hostnameFilter) && h.metrics.some(m => m.name == selectedMetric && m.scope == 'node')) - .map(h => ({ host: h.host, subCluster: h.subCluster, data: h.metrics.find(m => m.name == selectedMetric && m.scope == 'node') })) + .map(function (h) { + let thisConfig = metricConfig(cluster, selectedMetric) + let thisSCIndex = thisConfig.subClusters.findIndex(sc => sc.name == h.subCluster) + // Metric remove == true + if (thisSCIndex >= 0) { + if (thisConfig.subClusters[thisSCIndex].remove == true) { + return { host: h.host, subCluster: h.subCluster, data: null, removed: true } + } + } + // Else + return { host: h.host, subCluster: h.subCluster, data: h.metrics.find(m => m.name == selectedMetric && m.scope == 'node'), removed: false } + }) .sort((a, b) => a.host.localeCompare(b.host))}> -

{item.host} ({item.subCluster})

- c.name == cluster)} - subCluster={item.subCluster} /> +

{item.host} ({item.subCluster})

+ {#if item.removed == false && item.data != null} + c.name == cluster)} + subCluster={item.subCluster} /> + {:else if item.removed == true && item.data == null} + Metric '{ selectedMetric }' disabled for subcluster '{ item.subCluster }' + {:else} + Missing Data + {/if} {/if} diff --git a/web/frontend/src/User.root.svelte b/web/frontend/src/User.root.svelte index 652db6d..5021017 100644 --- a/web/frontend/src/User.root.svelte +++ b/web/frontend/src/User.root.svelte @@ -18,10 +18,12 @@ export let user export let filterPresets - let filters, jobList + let filters = [] + let jobList let sorting = { field: 'startTime', order: 'DESC' }, isSortingOpen = false let metrics = ccconfig.plot_list_selectedMetrics, isMetricsSelectionOpen = false let w1, w2, histogramHeight = 250 + let selectedCluster = filterPresets?.cluster ? filterPresets.cluster : null const stats = operationStore(` query($filter: [JobFilter!]!) { @@ -40,6 +42,12 @@ pause: true }) + // filters[filters.findIndex(filter => filter.cluster != null)] ? + // filters[filters.findIndex(filter => filter.cluster != null)].cluster.eq : + // null + // Cluster filter has to be alwas @ first index, above will throw error + $: selectedCluster = filters[0]?.cluster ? filters[0].cluster.eq : null + query(stats) onMount(() => filters.update()) @@ -75,11 +83,12 @@ startTimeQuickSelect={true} bind:this={filters} on:update={({ detail }) => { - let filters = [...detail.filters, { user: { eq: user.username } }] - $stats.variables = { filter: filters } + let jobFilters = [...detail.filters, { user: { eq: user.username } }] + $stats.variables = { filter: jobFilters } $stats.context.pause = false $stats.reexecute() - jobList.update(filters) + filters = jobFilters + jobList.update(jobFilters) }} /> @@ -171,6 +180,8 @@ bind:sorting={sorting} bind:isOpen={isSortingOpen} /> - \ No newline at end of file