diff --git a/web/frontend/src/Node.root.svelte b/web/frontend/src/Node.root.svelte index c78139a..8d0e749 100644 --- a/web/frontend/src/Node.root.svelte +++ b/web/frontend/src/Node.root.svelte @@ -44,7 +44,7 @@ if (from == null || to == null) { to = new Date(Date.now()); from = new Date(to.getTime()); - from.setHours(from.getHours() - 12); + from.setHours(from.getHours() - 4); } const initialized = getContext("initialized") @@ -153,18 +153,20 @@ {#if $nodeJobsData.fetching} {:else if $nodeJobsData.data} - - - Activity - - - Show List - - + + + Activity + + + Show List + + {:else} - - No currently running jobs. - + + + Activity + + {/if} diff --git a/web/frontend/src/Systems.root.svelte b/web/frontend/src/Systems.root.svelte index 8ff25c8..f2ef4ea 100644 --- a/web/frontend/src/Systems.root.svelte +++ b/web/frontend/src/Systems.root.svelte @@ -45,7 +45,7 @@ if (from == null || to == null) { to = new Date(Date.now()); from = new Date(to.getTime()); - from.setHours(from.getHours() - 12); + from.setHours(from.getHours() - 4); } const initialized = getContext("initialized"); @@ -53,12 +53,15 @@ const globalMetrics = getContext("globalMetrics"); const displayNodeOverview = (displayType === 'OVERVIEW') - let nodeList; let hostnameFilter = ""; let selectedMetric = ccconfig.system_view_selectedMetric || ""; - let selectedMetrics = ccconfig.node_list_selectedMetrics || ['cpu_load', 'mem_bw', 'acc_utilization', 'net_bytes_in', 'net_bytes_out']; + let selectedMetrics = ccconfig[`node_list_selectedMetrics:${cluster}`] || [ccconfig.system_view_selectedMetric]; let isMetricsSelectionOpen = false; + // Todo: Add Idle State Filter (== No allocated Jobs) + // Todo: NodeList: Mindestens Accelerator Scope ... "Show Detail" Switch? + // Todo: Review performance // observed high client-side load frequency + const client = getContextClient(); const nodeQuery = gql` query ($cluster: String!, $metrics: [String!], $from: Time!, $to: Time!) { @@ -139,7 +142,7 @@ mappedData = rawData.map((h) => ({ host: h.host, subCluster: h.subCluster, - data: h.metrics.find( + data: h.metrics.filter( (m) => selectedMetrics.includes(m.name) && m.scope == "node", ), disabled: checkMetricsDisabled( @@ -157,24 +160,23 @@ h.host.includes(hostnameFilter) ) } - - + {#if $initq.data} {#if !displayNodeOverview} - Metrics + Metrics @@ -187,7 +189,6 @@ @@ -247,21 +248,19 @@ {:else if $initialized && $nodesQuery?.data} {#if displayNodeOverview} - - + {:else} - - - - - - - - + + {/if} {/if} + + { + selectedMetrics = [...detail] + }} +/> diff --git a/web/frontend/src/generic/select/MetricSelection.svelte b/web/frontend/src/generic/select/MetricSelection.svelte index 2b1151e..b65b407 100644 --- a/web/frontend/src/generic/select/MetricSelection.svelte +++ b/web/frontend/src/generic/select/MetricSelection.svelte @@ -12,7 +12,7 @@ --> diff --git a/web/frontend/src/systems/NodeList.svelte b/web/frontend/src/systems/NodeList.svelte index 935a068..54f7530 100644 --- a/web/frontend/src/systems/NodeList.svelte +++ b/web/frontend/src/systems/NodeList.svelte @@ -5,86 +5,22 @@ - `cluster String`: The cluster to show status information for - `from Date?`: Custom Time Range selection 'from' [Default: null] - `to Date?`: Custom Time Range selection 'to' [Default: null] - - Properties: - - `sorting Object?`: Currently active sorting [Default: {field: "startTime", type: "col", order: "DESC"}] - - `matchedJobs Number?`: Number of matched jobs for selected filters [Default: 0] - - `metrics [String]?`: The currently selected metrics [Default: User-Configured Selection] - - `showFootprint Bool`: If to display the jobFootprint component - - Functions: - - `refreshJobs()`: Load jobs data with unchanged parameters and 'network-only' keyword - - `refreshAllMetrics()`: Trigger downstream refresh of all running jobs' metric data - - `queryJobs(filters?: [JobFilter])`: Load jobs data with new filters, starts from page 1 --> -
-

- {job.jobId} - ({job.cluster}) - {#if job.metaData?.jobName} -
- {#if job.metaData?.jobName.length <= 25} -

{job.metaData.jobName}
- {:else} -
- {job.metaData.jobName} -
- {/if} + + +
+
+ Node + + {hostname} + +
+
+
+
+ {cluster} {subCluster} +
+
+
+ + {#if $nodeJobsData.fetching} + + {:else if $nodeJobsData.data} +

+ {#if $nodeJobsData.data.jobs.count > 0} + + + + + + Status + + + + {:else} + + + + + + Status + + + + {/if} +

+
+

+ {#if $nodeJobsData.data.jobs.count > 0} + + + + + + Activity + + + + + Show List + + + {:else} + + + + + + Activity + + + + {/if} +

+

+ + + + + + Users on Node + + + + Show List + + +

+

+ + + + + + Projects on Node + + + + Show List + + +

{/if} - {#if job.arrayJobId} - Array Job: #{job.arrayJobId} - {/if} -

+
+
-

- - - {scrambleNames ? scramble(job.user) : job.user} - - {#if job.userData && job.userData.name} - ({scrambleNames ? scramble(job.userData.name) : job.userData.name}) - {/if} - {#if job.project && job.project != "no project"} -
- - - {scrambleNames ? scramble(job.project) : job.project} - - {/if} -

- -

- {#if job.numNodes == 1} - {job.resources[0].hostname} - {:else} - {job.numNodes} - {/if} - - {#if job.exclusive != 1} - (shared) - {/if} - {#if job.numAcc > 0} - , {job.numAcc} - {/if} - {#if job.numHWThreads > 0} - , {job.numHWThreads} - {/if} -
- {job.subCluster} -

- -

- Start: {new Date(job.startTime).toLocaleString()} -
- Duration: {formatDuration(job.duration)} - {job.state} - {#if job.walltime} -
- Walltime: {formatDuration(job.walltime)} - {/if} -

- - {#if showTagedit} -
-

- : - {#if jobTags?.length > 0} - {#each jobTags as tag} - - {/each} - {:else} - No Tags - {/if} -

- {:else} -

- {#each jobTags as tag} - - {/each} -

- {/if} -
- - diff --git a/web/frontend/src/systems/nodelist/NodeListRow.svelte b/web/frontend/src/systems/nodelist/NodeListRow.svelte index 3feac5c..5e9a31b 100644 --- a/web/frontend/src/systems/nodelist/NodeListRow.svelte +++ b/web/frontend/src/systems/nodelist/NodeListRow.svelte @@ -5,203 +5,52 @@ - `job Object`: The job object (GraphQL.Job) - `metrics [String]`: Currently selected metrics - `plotWidth Number`: Width of the sub-components - - `plotHeight Number?`: Height of the sub-components [Default: 275] - - `showFootprint Bool`: Display of footprint component for job - - `triggerMetricRefresh Bool?`: If changed to true from upstream, will trigger metric query --> - + - {#if job.monitoringStatus == 0 || job.monitoringStatus == 2} - - Not monitored or archiving failed - - {:else if $metricsQuery.fetching} - - - - {:else if $metricsQuery.error} - - - {$metricsQuery.error.message.length > 500 - ? $metricsQuery.error.message.substring(0, 499) + "..." - : $metricsQuery.error.message} - - - {:else} - {#if showFootprint} - - - - {/if} - {#each sortAndSelectScope($metricsQuery.data.jobMetrics) as metric, i (metric || i)} - - - {#if metric.disabled == false && metric.data} - { handleZoom(detail, metric.data.name) }} - height={plotHeight} - timestep={metric.data.metric.timestep} - scope={metric.data.scope} - series={metric.data.metric.series} - statisticsSeries={metric.data.metric.statisticsSeries} - metric={metric.data.name} - {cluster} - subCluster={job.subCluster} - isShared={job.exclusive != 1} - numhwthreads={job.numHWThreads} - numaccs={job.numAcc} - zoomState={zoomStates[metric.data.name] || null} - /> - {:else if metric.disabled == true && metric.data} - + {#if metricData} + {#if nodeData?.disabled[metricData.name]} + Metric disabled for subcluster {metric.data.name}:{job.subCluster}{metricData.name}:{nodeData.subCluster} {:else} - No dataset returned + {/if} - - {/each} - {/if} + {:else} + No dataset returned for {metricData.name} + {/if} + + {/each}