Migrate JobSummary and subcomponents

This commit is contained in:
Christoph Kluge 2025-06-13 15:49:51 +02:00
parent b7823cec16
commit 6dde2a1e59
3 changed files with 96 additions and 81 deletions

View File

@ -18,9 +18,12 @@
import JobFootprintPolar from "./jobsummary/JobFootprintPolar.svelte"; import JobFootprintPolar from "./jobsummary/JobFootprintPolar.svelte";
export let job; /* Svelte 5 Props */
export let width = "auto"; let {
export let height = "400px"; job,
width = "auto",
height = "400px",
} = $props();
const showFootprintTab = !!getContext("cc-config")[`job_view_showFootprint`]; const showFootprintTab = !!getContext("cc-config")[`job_view_showFootprint`];
</script> </script>

View File

@ -17,79 +17,88 @@
} from "@sveltestrap/sveltestrap"; } from "@sveltestrap/sveltestrap";
import { findJobFootprintThresholds } from "../../generic/utils.js"; import { findJobFootprintThresholds } from "../../generic/utils.js";
export let job; /* Svelte 5 Props */
let {job} = $props();
/* Derived */
// Prepare Job Footprint Data Based On Values Saved In Database // Prepare Job Footprint Data Based On Values Saved In Database
const jobFootprintData = job?.footprint?.map((jf) => { const jobFootprintData = $derived(buildFootprint(job?.footprint));
const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
if (fmc) {
// Unit
const unit = (fmc?.unit?.prefix ? fmc.unit.prefix : "") + (fmc?.unit?.base ? fmc.unit.base : "")
// Threshold / -Differences /* Functions */
const fmt = findJobFootprintThresholds(job, jf.stat, fmc); function buildFootprint(input) {
let result = input?.map((jf) => {
const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
if (fmc) {
// Unit
const unit = (fmc?.unit?.prefix ? fmc.unit.prefix : "") + (fmc?.unit?.base ? fmc.unit.base : "")
// Define basic data -> Value: Use as Provided // Threshold / -Differences
const fmBase = { const fmt = findJobFootprintThresholds(job, jf.stat, fmc);
name: jf.name,
stat: jf.stat,
value: jf.value,
unit: unit,
peak: fmt.peak,
dir: fmc.lowerIsBetter
};
if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "alert")) { // Define basic data -> Value: Use as Provided
return { const fmBase = {
...fmBase, name: jf.name,
color: "danger", stat: jf.stat,
message: `Footprint value way ${fmc.lowerIsBetter ? "above" : "below"} expected normal threshold.`, value: jf.value,
impact: 3 unit: unit,
peak: fmt.peak,
dir: fmc.lowerIsBetter
}; };
} else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "caution")) {
if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "alert")) {
return {
...fmBase,
color: "danger",
message: `Footprint value way ${fmc.lowerIsBetter ? "above" : "below"} expected normal threshold.`,
impact: 3
};
} else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "caution")) {
return {
...fmBase,
color: "warning",
message: `Footprint value ${fmc.lowerIsBetter ? "above" : "below"} expected normal threshold.`,
impact: 2,
};
} else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "normal")) {
return {
...fmBase,
color: "success",
message: "Footprint value within expected thresholds.",
impact: 1,
};
} else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "peak")) {
return {
...fmBase,
color: "info",
message:
"Footprint value above expected normal threshold: Check for artifacts recommended.",
impact: 0,
};
} else {
return {
...fmBase,
color: "secondary",
message:
"Footprint value above expected peak threshold: Check for artifacts!",
impact: -1,
};
}
} else { // No matching metric config: display as single value
return { return {
...fmBase, name: jf.name,
color: "warning", stat: jf.stat,
message: `Footprint value ${fmc.lowerIsBetter ? "above" : "below"} expected normal threshold.`, value: jf.value,
impact: 2,
};
} else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "normal")) {
return {
...fmBase,
color: "success",
message: "Footprint value within expected thresholds.",
impact: 1,
};
} else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "peak")) {
return {
...fmBase,
color: "info",
message: message:
"Footprint value above expected normal threshold: Check for artifacts recommended.", `No config for metric ${jf.name} found.`,
impact: 0, impact: 4,
};
} else {
return {
...fmBase,
color: "secondary",
message:
"Footprint value above expected peak threshold: Check for artifacts!",
impact: -1,
}; };
} }
} else { // No matching metric config: display as single value }).sort(function (a, b) { // Sort by impact value primarily, within impact sort name alphabetically
return { return a.impact - b.impact || ((a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
name: jf.name, });;
stat: jf.stat,
value: jf.value, return result
message: };
`No config for metric ${jf.name} found.`,
impact: 4,
};
}
}).sort(function (a, b) { // Sort by impact value primarily, within impact sort name alphabetically
return a.impact - b.impact || ((a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
});;
function evalFootprint(value, thresholds, lowerIsBetter, level) { function evalFootprint(value, thresholds, lowerIsBetter, level) {
// Handle Metrics in which less value is better // Handle Metrics in which less value is better
@ -161,7 +170,7 @@
>{fpd.message}</Tooltip >{fpd.message}</Tooltip
> >
</div> </div>
<Row cols={12} class="{(jobFootprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}"> <Row cols={12} class={(jobFootprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}>
{#if fpd.dir} {#if fpd.dir}
<Col xs="1"> <Col xs="1">
<Icon name="caret-left-fill" /> <Icon name="caret-left-fill" />

View File

@ -20,8 +20,10 @@
import Polar from "../../generic/plots/Polar.svelte"; import Polar from "../../generic/plots/Polar.svelte";
import { findJobFootprintThresholds } from "../../generic/utils.js"; import { findJobFootprintThresholds } from "../../generic/utils.js";
export let job; /* Svelte 5 Props */
let { job } = $props();
/* Const Init */
// Metric Names Configured To Be Footprints For (sub)Cluster // Metric Names Configured To Be Footprints For (sub)Cluster
const clusterFootprintMetrics = getContext("clusters") const clusterFootprintMetrics = getContext("clusters")
.find((c) => c.name == job.cluster)?.subClusters .find((c) => c.name == job.cluster)?.subClusters
@ -39,23 +41,24 @@
// Pull All Series For Footprint Metrics Statistics Only On Node Scope // Pull All Series For Footprint Metrics Statistics Only On Node Scope
const client = getContextClient(); const client = getContextClient();
const polarQuery = gql` const polarQuery = gql`
query ($dbid: ID!, $selectedMetrics: [String!]!) { query ($dbid: ID!, $selectedMetrics: [String!]!) {
jobStats(id: $dbid, metrics: $selectedMetrics) { jobStats(id: $dbid, metrics: $selectedMetrics) {
name name
data { data {
min min
avg avg
max max
}
} }
} }
}
`; `;
$: polarData = queryStore({ /* Derived */
const polarData = $derived(queryStore({
client: client, client: client,
query: polarQuery, query: polarQuery,
variables:{ dbid: job.id, selectedMetrics: clusterFootprintMetrics }, variables:{ dbid: job.id, selectedMetrics: clusterFootprintMetrics },
}); }));
</script> </script>
<CardBody> <CardBody>