mirror of
				https://github.com/ClusterCockpit/cc-backend
				synced 2025-11-03 17:15:06 +01:00 
			
		
		
		
	fix: add compatibility for footprint metrics without config
This commit is contained in:
		@@ -67,62 +67,74 @@
 | 
				
			|||||||
  export let height = "310px";
 | 
					  export let height = "310px";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const footprintData = job?.footprint?.map((jf) => {
 | 
					  const footprintData = job?.footprint?.map((jf) => {
 | 
				
			||||||
    // Unit
 | 
					 | 
				
			||||||
    const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
 | 
					    const fmc = getContext("getMetricConfig")(job.cluster, job.subCluster, jf.name);
 | 
				
			||||||
    const unit = (fmc?.unit?.prefix ? fmc.unit.prefix : "") + (fmc?.unit?.base ? fmc.unit.base : "")
 | 
					    if (fmc) {
 | 
				
			||||||
 | 
					      // Unit
 | 
				
			||||||
 | 
					      const unit = (fmc?.unit?.prefix ? fmc.unit.prefix : "") + (fmc?.unit?.base ? fmc.unit.base : "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Threshold / -Differences
 | 
					      // Threshold / -Differences
 | 
				
			||||||
    const fmt = findJobThresholds(job, fmc);
 | 
					      const fmt = findJobThresholds(job, fmc);
 | 
				
			||||||
    if (jf.name === "flops_any") fmt.peak = round(fmt.peak * 0.85, 0);
 | 
					      if (jf.name === "flops_any") fmt.peak = round(fmt.peak * 0.85, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Define basic data -> Value: Use as Provided
 | 
					      // Define basic data -> Value: Use as Provided
 | 
				
			||||||
    const fmBase = {
 | 
					      const fmBase = {
 | 
				
			||||||
      name: jf.name + ' (' + jf.stat + ')',
 | 
					        name: jf.name + ' (' + jf.stat + ')',
 | 
				
			||||||
      avg: jf.value,
 | 
					        avg: jf.value,
 | 
				
			||||||
      unit: unit,
 | 
					        unit: unit,
 | 
				
			||||||
      max: fmt.peak,
 | 
					        max: fmt.peak,
 | 
				
			||||||
      dir: fmc.lowerIsBetter
 | 
					        dir: fmc.lowerIsBetter
 | 
				
			||||||
    };
 | 
					      };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "alert")) {
 | 
					      if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "alert")) {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          ...fmBase,
 | 
				
			||||||
 | 
					          color: "danger",
 | 
				
			||||||
 | 
					          message: `Metric average way ${fmc.lowerIsBetter ? "above" : "below"} expected normal thresholds.`,
 | 
				
			||||||
 | 
					          impact: 3
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      } else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "caution")) {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          ...fmBase,
 | 
				
			||||||
 | 
					          color: "warning",
 | 
				
			||||||
 | 
					          message: `Metric average ${fmc.lowerIsBetter ? "above" : "below"} expected normal thresholds.`,
 | 
				
			||||||
 | 
					          impact: 2,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      } else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "normal")) {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          ...fmBase,
 | 
				
			||||||
 | 
					          color: "success",
 | 
				
			||||||
 | 
					          message: "Metric average within expected thresholds.",
 | 
				
			||||||
 | 
					          impact: 1,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      } else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "peak")) {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          ...fmBase,
 | 
				
			||||||
 | 
					          color: "info",
 | 
				
			||||||
 | 
					          message:
 | 
				
			||||||
 | 
					            "Metric average above expected normal thresholds: Check for artifacts recommended.",
 | 
				
			||||||
 | 
					          impact: 0,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          ...fmBase,
 | 
				
			||||||
 | 
					          color: "secondary",
 | 
				
			||||||
 | 
					          message:
 | 
				
			||||||
 | 
					            "Metric average above expected peak threshold: Check for artifacts!",
 | 
				
			||||||
 | 
					          impact: -1,
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else { // No matching metric config: display as single value
 | 
				
			||||||
      return {
 | 
					      return {
 | 
				
			||||||
        ...fmBase,
 | 
					        name: jf.name + ' (' + jf.stat + ')',
 | 
				
			||||||
        color: "danger",
 | 
					        avg: jf.value,
 | 
				
			||||||
        message: `Metric average way ${fmc.lowerIsBetter ? "above" : "below"} expected normal thresholds.`,
 | 
					 | 
				
			||||||
        impact: 3
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    } else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "caution")) {
 | 
					 | 
				
			||||||
      return {
 | 
					 | 
				
			||||||
        ...fmBase,
 | 
					 | 
				
			||||||
        color: "warning",
 | 
					 | 
				
			||||||
        message: `Metric average ${fmc.lowerIsBetter ? "above" : "below"} expected normal thresholds.`,
 | 
					 | 
				
			||||||
        impact: 2,
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    } else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "normal")) {
 | 
					 | 
				
			||||||
      return {
 | 
					 | 
				
			||||||
        ...fmBase,
 | 
					 | 
				
			||||||
        color: "success",
 | 
					 | 
				
			||||||
        message: "Metric average within expected thresholds.",
 | 
					 | 
				
			||||||
        impact: 1,
 | 
					 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    } else if (evalFootprint(jf.value, fmt, fmc.lowerIsBetter, "peak")) {
 | 
					 | 
				
			||||||
      return {
 | 
					 | 
				
			||||||
        ...fmBase,
 | 
					 | 
				
			||||||
        color: "info",
 | 
					 | 
				
			||||||
        message:
 | 
					        message:
 | 
				
			||||||
          "Metric average above expected normal thresholds: Check for artifacts recommended.",
 | 
					          `No config for metric ${jf.name} found.`,
 | 
				
			||||||
        impact: 0,
 | 
					        impact: 4,
 | 
				
			||||||
      };
 | 
					 | 
				
			||||||
    } else {
 | 
					 | 
				
			||||||
      return {
 | 
					 | 
				
			||||||
        ...fmBase,
 | 
					 | 
				
			||||||
        color: "secondary",
 | 
					 | 
				
			||||||
        message:
 | 
					 | 
				
			||||||
          "Metric average above expected peak threshold: Check for artifacts!",
 | 
					 | 
				
			||||||
        impact: -1,
 | 
					 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  }).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(mean, thresholds, lowerIsBetter, level) {
 | 
					  function evalFootprint(mean, thresholds, lowerIsBetter, level) {
 | 
				
			||||||
    // Handle Metrics in which less value is better
 | 
					    // Handle Metrics in which less value is better
 | 
				
			||||||
@@ -159,37 +171,76 @@
 | 
				
			|||||||
  {/if}
 | 
					  {/if}
 | 
				
			||||||
  <CardBody>
 | 
					  <CardBody>
 | 
				
			||||||
    {#each footprintData as fpd, index}
 | 
					    {#each footprintData as fpd, index}
 | 
				
			||||||
      <div class="mb-1 d-flex justify-content-between">
 | 
					      {#if fpd.impact !== 4}
 | 
				
			||||||
        <div> <b>{fpd.name}</b></div>
 | 
					        <div class="mb-1 d-flex justify-content-between">
 | 
				
			||||||
        <!-- For symmetry, see below ...-->
 | 
					          <div> <b>{fpd.name}</b></div>
 | 
				
			||||||
        <div
 | 
					          <!-- For symmetry, see below ...-->
 | 
				
			||||||
          class="cursor-help d-inline-flex"
 | 
					          <div
 | 
				
			||||||
          id={`footprint-${job.jobId}-${index}`}
 | 
					            class="cursor-help d-inline-flex"
 | 
				
			||||||
        >
 | 
					            id={`footprint-${job.jobId}-${index}`}
 | 
				
			||||||
          <div class="mx-1">
 | 
					          >
 | 
				
			||||||
            <!-- Alerts Only -->
 | 
					            <div class="mx-1">
 | 
				
			||||||
            {#if fpd.impact === 3 || fpd.impact === -1}
 | 
					              <!-- Alerts Only -->
 | 
				
			||||||
              <Icon name="exclamation-triangle-fill" class="text-danger" />
 | 
					              {#if fpd.impact === 3 || fpd.impact === -1}
 | 
				
			||||||
            {:else if fpd.impact === 2}
 | 
					                <Icon name="exclamation-triangle-fill" class="text-danger" />
 | 
				
			||||||
              <Icon name="exclamation-triangle" class="text-warning" />
 | 
					              {:else if fpd.impact === 2}
 | 
				
			||||||
            {/if}
 | 
					                <Icon name="exclamation-triangle" class="text-warning" />
 | 
				
			||||||
            <!-- Emoji for all states-->
 | 
					              {/if}
 | 
				
			||||||
            {#if fpd.impact === 3}
 | 
					              <!-- Emoji for all states-->
 | 
				
			||||||
              <Icon name="emoji-frown" class="text-danger" />
 | 
					              {#if fpd.impact === 3}
 | 
				
			||||||
            {:else if fpd.impact === 2}
 | 
					                <Icon name="emoji-frown" class="text-danger" />
 | 
				
			||||||
              <Icon name="emoji-neutral" class="text-warning" />
 | 
					              {:else if fpd.impact === 2}
 | 
				
			||||||
            {:else if fpd.impact === 1}
 | 
					                <Icon name="emoji-neutral" class="text-warning" />
 | 
				
			||||||
              <Icon name="emoji-smile" class="text-success" />
 | 
					              {:else if fpd.impact === 1}
 | 
				
			||||||
            {:else if fpd.impact === 0}
 | 
					                <Icon name="emoji-smile" class="text-success" />
 | 
				
			||||||
              <Icon name="emoji-laughing" class="text-info" />
 | 
					              {:else if fpd.impact === 0}
 | 
				
			||||||
            {:else if fpd.impact === -1}
 | 
					                <Icon name="emoji-laughing" class="text-info" />
 | 
				
			||||||
              <Icon name="emoji-dizzy" class="text-danger" />
 | 
					              {:else if fpd.impact === -1}
 | 
				
			||||||
            {/if}
 | 
					                <Icon name="emoji-dizzy" class="text-danger" />
 | 
				
			||||||
 | 
					              {/if}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              <!-- Print Values -->
 | 
				
			||||||
 | 
					              {fpd.avg} / {fpd.max}
 | 
				
			||||||
 | 
					              {fpd.unit}   <!-- To increase margin to tooltip: No other way manageable ... -->
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					          <Tooltip
 | 
				
			||||||
 | 
					            target={`footprint-${job.jobId}-${index}`}
 | 
				
			||||||
 | 
					            placement="right"
 | 
				
			||||||
 | 
					            offset={[0, 20]}>{fpd.message}</Tooltip
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <Row cols={12} class="{(footprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}">
 | 
				
			||||||
 | 
					          {#if fpd.dir}
 | 
				
			||||||
 | 
					            <Col xs="1">
 | 
				
			||||||
 | 
					              <Icon name="caret-left-fill" />
 | 
				
			||||||
 | 
					            </Col>
 | 
				
			||||||
 | 
					          {/if}
 | 
				
			||||||
 | 
					          <Col xs="11" class="align-content-center">
 | 
				
			||||||
 | 
					            <Progress value={fpd.avg} max={fpd.max} color={fpd.color} />
 | 
				
			||||||
 | 
					          </Col>
 | 
				
			||||||
 | 
					          {#if !fpd.dir}
 | 
				
			||||||
 | 
					          <Col xs="1">
 | 
				
			||||||
 | 
					            <Icon name="caret-right-fill" />
 | 
				
			||||||
 | 
					          </Col>
 | 
				
			||||||
 | 
					          {/if}
 | 
				
			||||||
 | 
					        </Row>
 | 
				
			||||||
 | 
					      {:else}
 | 
				
			||||||
 | 
					        <div class="mb-1 d-flex justify-content-between">
 | 
				
			||||||
          <div>
 | 
					          <div>
 | 
				
			||||||
            <!-- Print Values -->
 | 
					             <b>{fpd.name}</b>
 | 
				
			||||||
            {fpd.avg} / {fpd.max}
 | 
					          </div>
 | 
				
			||||||
            {fpd.unit}   <!-- To increase margin to tooltip: No other way manageable ... -->
 | 
					          <div
 | 
				
			||||||
 | 
					            class="cursor-help d-inline-flex"
 | 
				
			||||||
 | 
					            id={`footprint-${job.jobId}-${index}`}
 | 
				
			||||||
 | 
					          >
 | 
				
			||||||
 | 
					            <div class="mx-1">
 | 
				
			||||||
 | 
					              <Icon name="info-circle"/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					              {fpd.avg} 
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <Tooltip
 | 
					        <Tooltip
 | 
				
			||||||
@@ -197,22 +248,7 @@
 | 
				
			|||||||
          placement="right"
 | 
					          placement="right"
 | 
				
			||||||
          offset={[0, 20]}>{fpd.message}</Tooltip
 | 
					          offset={[0, 20]}>{fpd.message}</Tooltip
 | 
				
			||||||
        >
 | 
					        >
 | 
				
			||||||
      </div>
 | 
					      {/if}
 | 
				
			||||||
      <Row cols={12} class="{(footprintData.length == (index + 1)) ? 'mb-0' : 'mb-2'}">
 | 
					 | 
				
			||||||
        {#if fpd.dir}
 | 
					 | 
				
			||||||
          <Col xs="1">
 | 
					 | 
				
			||||||
            <Icon name="caret-left-fill" />
 | 
					 | 
				
			||||||
          </Col>
 | 
					 | 
				
			||||||
        {/if}
 | 
					 | 
				
			||||||
        <Col xs="11" class="align-content-center">
 | 
					 | 
				
			||||||
          <Progress value={fpd.avg} max={fpd.max} color={fpd.color} />
 | 
					 | 
				
			||||||
        </Col>
 | 
					 | 
				
			||||||
        {#if !fpd.dir}
 | 
					 | 
				
			||||||
        <Col xs="1">
 | 
					 | 
				
			||||||
          <Icon name="caret-right-fill" />
 | 
					 | 
				
			||||||
        </Col>
 | 
					 | 
				
			||||||
        {/if}
 | 
					 | 
				
			||||||
      </Row>
 | 
					 | 
				
			||||||
    {/each}
 | 
					    {/each}
 | 
				
			||||||
    {#if job?.metaData?.message}
 | 
					    {#if job?.metaData?.message}
 | 
				
			||||||
      <hr class="mt-1 mb-2" />
 | 
					      <hr class="mt-1 mb-2" />
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user