diff --git a/configs/tagger/apps/vasp.txt b/configs/tagger/apps/vasp.txt
index 9f9b9d5d..79014e1d 100644
--- a/configs/tagger/apps/vasp.txt
+++ b/configs/tagger/apps/vasp.txt
@@ -1,2 +1,3 @@
-vasp
-VASP
+vasp_gam
+vasp_ncl
+vasp_std
diff --git a/internal/api/node.go b/internal/api/node.go
index 37a8576c..930deb50 100644
--- a/internal/api/node.go
+++ b/internal/api/node.go
@@ -15,6 +15,7 @@ import (
"github.com/ClusterCockpit/cc-backend/internal/repository"
"github.com/ClusterCockpit/cc-backend/pkg/archive"
"github.com/ClusterCockpit/cc-backend/pkg/metricstore"
+ cclog "github.com/ClusterCockpit/cc-lib/v2/ccLogger"
"github.com/ClusterCockpit/cc-lib/v2/schema"
)
@@ -81,6 +82,8 @@ func (api *RestAPI) updateNodeStates(rw http.ResponseWriter, r *http.Request) {
m := make(map[string][]string)
healthStates := make(map[string]schema.MonitoringState)
+ startMs := time.Now()
+
for _, node := range req.Nodes {
if sc, err := archive.GetSubClusterByNode(req.Cluster, node.Hostname); err == nil {
m[sc] = append(m[sc], node.Hostname)
@@ -97,6 +100,9 @@ func (api *RestAPI) updateNodeStates(rw http.ResponseWriter, r *http.Request) {
}
}
+ cclog.Infof("Timer updateNodeStates, MemStore HealthCheck: %s", time.Since(startMs))
+ startDb := time.Now()
+
for _, node := range req.Nodes {
state := determineState(node.States)
healthState := schema.MonitoringStateFailed
@@ -115,4 +121,6 @@ func (api *RestAPI) updateNodeStates(rw http.ResponseWriter, r *http.Request) {
repo.UpdateNodeState(node.Hostname, req.Cluster, &nodeState)
}
+
+ cclog.Infof("Timer updateNodeStates, SQLite Inserts: %s", time.Since(startDb))
}
diff --git a/internal/api/rest.go b/internal/api/rest.go
index 3f6d9609..00ed1f55 100644
--- a/internal/api/rest.go
+++ b/internal/api/rest.go
@@ -81,7 +81,7 @@ func (api *RestAPI) MountAPIRoutes(r *mux.Router) {
// Cluster List
r.HandleFunc("/clusters/", api.getClusters).Methods(http.MethodGet)
// Slurm node state
- r.HandleFunc("/nodestates/", api.updateNodeStates).Methods(http.MethodPost, http.MethodPut)
+ r.HandleFunc("/nodestate/", api.updateNodeStates).Methods(http.MethodPost, http.MethodPut)
// Job Handler
if config.Keys.APISubjects == nil {
cclog.Info("Enabling REST start/stop job API")
diff --git a/internal/repository/node.go b/internal/repository/node.go
index 3fa041f6..2a22e8c4 100644
--- a/internal/repository/node.go
+++ b/internal/repository/node.go
@@ -198,7 +198,6 @@ func (r *NodeRepository) UpdateNodeState(hostname string, cluster string, nodeSt
}
cclog.Debugf("Added node '%s' to database", hostname)
- return nil
} else {
cclog.Warnf("Error while querying node '%v' from database", id)
return err
diff --git a/pkg/metricstore/healthcheck.go b/pkg/metricstore/healthcheck.go
index f390749d..59c84f79 100644
--- a/pkg/metricstore/healthcheck.go
+++ b/pkg/metricstore/healthcheck.go
@@ -11,6 +11,7 @@ import (
"slices"
"time"
+ cclog "github.com/ClusterCockpit/cc-lib/v2/ccLogger"
"github.com/ClusterCockpit/cc-lib/v2/schema"
)
@@ -244,7 +245,16 @@ func (m *MemoryStore) HealthCheck(cluster string,
missingCount = len(missingList)
degradedCount = len(degradedList)
- healthyCount = len(expectedMetrics) - (missingCount + degradedCount)
+ uniqueList := mergeList(missingList, degradedList)
+ healthyCount = len(expectedMetrics) - len(uniqueList)
+
+ // Debug log missing and degraded metrics
+ if missingCount > 0 {
+ cclog.ComponentDebug("metricstore", "HealthCheck: node", hostname, "missing metrics:", missingList)
+ }
+ if degradedCount > 0 {
+ cclog.ComponentDebug("metricstore", "HealthCheck: node", hostname, "degraded metrics:", degradedList)
+ }
// Determine overall health status
if missingCount > 0 || degradedCount > 0 {
diff --git a/web/frontend/src/List.root.svelte b/web/frontend/src/List.root.svelte
index 6bc1cd8f..239bf5f1 100644
--- a/web/frontend/src/List.root.svelte
+++ b/web/frontend/src/List.root.svelte
@@ -319,11 +319,11 @@
|
{#if type == "USER"}
- {scrambleNames ? scramble(row.id) : row.id}
{:else if type == "PROJECT"}
- {scrambleNames ? scramble(row.id) : row.id}
{:else}
diff --git a/web/frontend/src/User.root.svelte b/web/frontend/src/User.root.svelte
index 669ca8bb..bb83ef91 100644
--- a/web/frontend/src/User.root.svelte
+++ b/web/frontend/src/User.root.svelte
@@ -19,7 +19,8 @@
Spinner,
Input,
InputGroup,
- InputGroupText
+ InputGroupText,
+ Tooltip
} from "@sveltestrap/sveltestrap";
import {
queryStore,
@@ -32,6 +33,10 @@
scramble,
scrambleNames,
} from "./generic/utils.js";
+ import {
+ formatNumber,
+ formatDurationTime
+ } from "./generic/units.js";
import JobList from "./generic/JobList.svelte";
import JobCompare from "./generic/JobCompare.svelte";
import Filters from "./generic/Filters.svelte";
@@ -56,6 +61,7 @@
const durationBinOptions = ["1m","10m","1h","6h","12h"];
const metricBinOptions = [10, 20, 50, 100];
const matchedJobCompareLimit = 500;
+ const shortDuration = ccconfig.jobList_hideShortRunningJobs; // Always configured
/* State Init */
// List & Control Vars
@@ -108,6 +114,7 @@
shortJobs
totalWalltime
totalCoreHours
+ totalAccHours
histDuration {
count
value
@@ -133,6 +140,7 @@
variables: { jobFilters, selectedHistograms, numDurationBins, numMetricBins },
})
);
+ const hasAccHours = $derived($stats?.data?.jobsStatistics[0]?.totalAccHours != 0);
/* Functions */
function resetJobSelection() {
@@ -290,20 +298,54 @@
{/if}
|
| Total Jobs |
- {$stats.data.jobsStatistics[0].totalJobs} |
+
+
+ {formatNumber($stats.data.jobsStatistics[0].totalJobs)} Jobs
+
+ |
- | Short Jobs |
- {$stats.data.jobsStatistics[0].shortJobs} |
+
+
+ Short Jobs
+
+
+
+ Job duration less than {formatDurationTime(shortDuration)}
+
+ |
+
+
+ {formatNumber($stats.data.jobsStatistics[0].shortJobs)} Jobs
+
+ |
| Total Walltime |
- {$stats.data.jobsStatistics[0].totalWalltime} |
+
+
+ {formatNumber($stats.data.jobsStatistics[0].totalWalltime)} Hours
+
+ |
| Total Core Hours |
- {$stats.data.jobsStatistics[0].totalCoreHours} |
+
+
+ {formatNumber($stats.data.jobsStatistics[0].totalCoreHours)} Hours
+
+ |
+ {#if hasAccHours}
+
+ | Total Accelerator Hours |
+
+
+ {formatNumber($stats.data.jobsStatistics[0].totalAccHours)} Hours
+
+ |
+
+ {/if}
@@ -316,6 +358,7 @@
xunit="Runtime"
ylabel="Number of Jobs"
yunit="Jobs"
+ height={hasAccHours ? 290 : 250}
usesBins
xtime
/>
@@ -330,6 +373,7 @@
xunit="Nodes"
ylabel="Number of Jobs"
yunit="Jobs"
+ height={hasAccHours ? 290 : 250}
/>
{/key}
diff --git a/web/frontend/src/generic/joblist/JobListRow.svelte b/web/frontend/src/generic/joblist/JobListRow.svelte
index 9502a2f8..93fa496b 100644
--- a/web/frontend/src/generic/joblist/JobListRow.svelte
+++ b/web/frontend/src/generic/joblist/JobListRow.svelte
@@ -79,7 +79,6 @@
/* Derived */
const jobId = $derived(job?.id);
- const refinedData = $derived($metricsQuery?.data?.jobMetrics ? sortAndSelectScope($metricsQuery.data.jobMetrics) : []);
const scopes = $derived.by(() => {
if (job.numNodes == 1) {
if (job.numAcc >= 1) return ["core", "accelerator"];
@@ -95,6 +94,7 @@
variables: { id: jobId, metrics, scopes, selectedResolution },
})
);
+ const refinedData = $derived($metricsQuery?.data?.jobMetrics ? sortAndSelectScope($metricsQuery.data.jobMetrics) : []);
/* Effects */
$effect(() => {
diff --git a/web/frontend/src/generic/units.js b/web/frontend/src/generic/units.js
index 540a1a32..951ecbe8 100644
--- a/web/frontend/src/generic/units.js
+++ b/web/frontend/src/generic/units.js
@@ -32,10 +32,6 @@ export function scaleNumber(x, p = '') {
}
}
-export function roundTwoDigits(x) {
- return Math.round(x * 100) / 100
-}
-
export function scaleNumbers(x, y, p = '') {
const oldPower = power[prefix.indexOf(p)]
const rawXValue = x * oldPower
@@ -77,6 +73,10 @@ export function formatUnixTime(t, withDate = false) {
}
}
+export function roundTwoDigits(x) {
+ return Math.round(x * 100) / 100
+}
+
// const equalsCheck = (a, b) => {
// return JSON.stringify(a) === JSON.stringify(b);
// }