2022-06-22 11:20:57 +02:00
|
|
|
<script>
|
2023-06-19 16:11:16 +02:00
|
|
|
import { init, checkMetricDisabled } from './utils.js'
|
2022-06-22 11:20:57 +02:00
|
|
|
import { Row, Col, InputGroup, InputGroupText, Icon, Spinner, Card } from 'sveltestrap'
|
2023-05-03 16:41:17 +02:00
|
|
|
import { queryStore, gql, getContextClient } from '@urql/svelte'
|
2022-06-22 11:20:57 +02:00
|
|
|
import TimeSelection from './filters/TimeSelection.svelte'
|
|
|
|
import PlotTable from './PlotTable.svelte'
|
|
|
|
import MetricPlot from './plots/MetricPlot.svelte'
|
|
|
|
import { getContext } from 'svelte'
|
|
|
|
|
|
|
|
export let cluster
|
|
|
|
export let hostname
|
|
|
|
export let from = null
|
|
|
|
export let to = null
|
|
|
|
|
|
|
|
const { query: initq } = init()
|
|
|
|
|
|
|
|
if (from == null || to == null) {
|
|
|
|
to = new Date(Date.now())
|
|
|
|
from = new Date(to.getTime())
|
|
|
|
from.setMinutes(from.getMinutes() - 30)
|
|
|
|
}
|
|
|
|
|
2023-03-30 15:21:35 +02:00
|
|
|
const ccconfig = getContext('cc-config')
|
|
|
|
const clusters = getContext('clusters')
|
2023-05-10 16:35:21 +02:00
|
|
|
const client = getContextClient();
|
2023-06-30 12:01:27 +02:00
|
|
|
const nodeMetricsQuery = gql`query($cluster: String!, $nodes: [String!], $from: Time!, $to: Time!) {
|
2022-06-22 11:20:57 +02:00
|
|
|
nodeMetrics(cluster: $cluster, nodes: $nodes, from: $from, to: $to) {
|
2023-03-30 15:21:35 +02:00
|
|
|
host
|
|
|
|
subCluster
|
2022-06-22 11:20:57 +02:00
|
|
|
metrics {
|
2023-03-30 15:21:35 +02:00
|
|
|
name
|
|
|
|
scope
|
2022-06-22 11:20:57 +02:00
|
|
|
metric {
|
|
|
|
timestep
|
2023-03-30 15:21:35 +02:00
|
|
|
unit { base, prefix }
|
2022-06-22 11:20:57 +02:00
|
|
|
series {
|
|
|
|
statistics { min, avg, max }
|
|
|
|
data
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-05-10 16:35:21 +02:00
|
|
|
}`;
|
2022-06-22 11:20:57 +02:00
|
|
|
|
2023-06-30 12:01:27 +02:00
|
|
|
$: nodeMetricsData = queryStore({
|
2023-05-10 16:35:21 +02:00
|
|
|
client: client,
|
2023-06-30 12:01:27 +02:00
|
|
|
query: nodeMetricsQuery,
|
2023-05-10 16:35:21 +02:00
|
|
|
variables: {
|
|
|
|
cluster: cluster,
|
|
|
|
nodes: [hostname],
|
|
|
|
from: from.toISOString(),
|
|
|
|
to: to.toISOString(),
|
|
|
|
}
|
|
|
|
});
|
2022-06-22 11:20:57 +02:00
|
|
|
|
2023-06-30 12:01:27 +02:00
|
|
|
let itemsPerPage = ccconfig.plot_list_jobsPerPage;
|
|
|
|
let page = 1;
|
|
|
|
let paging = { itemsPerPage, page };
|
|
|
|
let sorting = { field: "startTime", order: "DESC" };
|
|
|
|
$: filter = [
|
|
|
|
{cluster: { eq: cluster }},
|
|
|
|
{node: { eq: hostname }},
|
2023-06-30 15:04:01 +02:00
|
|
|
{state: 'running'}
|
|
|
|
// {startTime: {
|
|
|
|
// from: from.toISOString(),
|
|
|
|
// to: to.toISOString()
|
|
|
|
// }}
|
2023-06-30 12:01:27 +02:00
|
|
|
];
|
|
|
|
|
|
|
|
const nodeJobsQuery = gql`
|
|
|
|
query (
|
|
|
|
$filter: [JobFilter!]!
|
|
|
|
$sorting: OrderByInput!
|
|
|
|
$paging: PageRequest!
|
|
|
|
) {
|
|
|
|
jobs(filter: $filter, order: $sorting, page: $paging) {
|
|
|
|
# items {
|
|
|
|
# id
|
|
|
|
# jobId
|
|
|
|
# }
|
|
|
|
count
|
|
|
|
}
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
$: nodeJobsData = queryStore({
|
|
|
|
client: client,
|
|
|
|
query: nodeJobsQuery,
|
|
|
|
variables: { paging, sorting, filter }
|
|
|
|
});
|
|
|
|
|
2023-03-30 15:21:35 +02:00
|
|
|
let metricUnits = {}
|
2023-06-30 12:01:27 +02:00
|
|
|
$: if ($nodeMetricsData.data) {
|
2023-06-14 15:32:35 +02:00
|
|
|
let thisCluster = clusters.find(c => c.name == cluster)
|
|
|
|
if (thisCluster) {
|
|
|
|
for (let metric of thisCluster.metricConfig) {
|
|
|
|
if (metric.unit.prefix || metric.unit.base) {
|
|
|
|
metricUnits[metric.name] = '(' + (metric.unit.prefix ? metric.unit.prefix : '') + (metric.unit.base ? metric.unit.base : '') + ')'
|
|
|
|
} else { // If no unit defined: Omit Unit Display
|
|
|
|
metricUnits[metric.name] = ''
|
|
|
|
}
|
2023-03-30 15:21:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-06-14 15:32:35 +02:00
|
|
|
|
2023-06-30 12:01:27 +02:00
|
|
|
const dateToUnixEpoch = rfc3339 => Math.floor(Date.parse(rfc3339) / 1000)
|
2022-06-22 11:20:57 +02:00
|
|
|
</script>
|
|
|
|
|
|
|
|
<Row>
|
|
|
|
{#if $initq.error}
|
|
|
|
<Card body color="danger">{$initq.error.message}</Card>
|
|
|
|
{:else if $initq.fetching}
|
|
|
|
<Spinner/>
|
|
|
|
{:else}
|
|
|
|
<Col>
|
|
|
|
<InputGroup>
|
|
|
|
<InputGroupText><Icon name="hdd"/></InputGroupText>
|
|
|
|
<InputGroupText>{hostname} ({cluster})</InputGroupText>
|
|
|
|
</InputGroup>
|
|
|
|
</Col>
|
2023-06-30 12:01:27 +02:00
|
|
|
<Col>
|
|
|
|
{#if $nodeJobsData.fetching }
|
|
|
|
<Spinner/>
|
|
|
|
{:else}
|
|
|
|
{#if $nodeJobsData.data}
|
|
|
|
Currently running jobs on this node: { $nodeJobsData.data.jobs.count }
|
2023-06-30 15:06:26 +02:00
|
|
|
[ <a href="/monitoring/jobs/?cluster={cluster}&state=running&node={hostname}" target="_blank">View in Job List</a> ]
|
2023-06-30 12:01:27 +02:00
|
|
|
{:else}
|
|
|
|
No currently running jobs.
|
|
|
|
{/if}
|
|
|
|
{/if}
|
|
|
|
</Col>
|
2022-06-22 11:20:57 +02:00
|
|
|
<Col>
|
|
|
|
<TimeSelection
|
|
|
|
bind:from={from}
|
|
|
|
bind:to={to} />
|
|
|
|
</Col>
|
|
|
|
{/if}
|
|
|
|
</Row>
|
|
|
|
<br/>
|
|
|
|
<Row>
|
|
|
|
<Col>
|
2023-06-30 12:01:27 +02:00
|
|
|
{#if $nodeMetricsData.error}
|
|
|
|
<Card body color="danger">{$nodeMetricsData.error.message}</Card>
|
|
|
|
{:else if $nodeMetricsData.fetching || $initq.fetching}
|
2022-06-22 11:20:57 +02:00
|
|
|
<Spinner/>
|
|
|
|
{:else}
|
|
|
|
<PlotTable
|
|
|
|
let:item
|
|
|
|
let:width
|
2023-06-19 16:11:16 +02:00
|
|
|
renderFor="node"
|
2022-06-22 11:20:57 +02:00
|
|
|
itemsPerRow={ccconfig.plot_view_plotsPerRow}
|
2023-06-30 12:01:27 +02:00
|
|
|
items={$nodeMetricsData.data.nodeMetrics[0].metrics
|
|
|
|
.map(m => ({ ...m, disabled: checkMetricDisabled(m.name, cluster, $nodeMetricsData.data.nodeMetrics[0].subCluster)}))
|
2023-06-19 16:11:16 +02:00
|
|
|
.sort((a, b) => a.name.localeCompare(b.name))}>
|
|
|
|
|
2023-06-14 15:32:35 +02:00
|
|
|
<h4 style="text-align: center; padding-top:15px;">{item.name} {metricUnits[item.name]}</h4>
|
2023-06-19 16:11:16 +02:00
|
|
|
{#if item.disabled === false && item.metric}
|
|
|
|
<MetricPlot
|
|
|
|
width={width} height={300} metric={item.name} timestep={item.metric.timestep}
|
2023-06-30 12:01:27 +02:00
|
|
|
cluster={clusters.find(c => c.name == cluster)} subCluster={$nodeMetricsData.data.nodeMetrics[0].subCluster}
|
2023-06-19 16:11:16 +02:00
|
|
|
series={item.metric.series} />
|
|
|
|
{:else if item.disabled === true && item.metric}
|
2023-06-30 12:01:27 +02:00
|
|
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="info">Metric disabled for subcluster <code>{item.name}:{$nodeMetricsData.data.nodeMetrics[0].subCluster}</code></Card>
|
2023-06-19 16:11:16 +02:00
|
|
|
{:else}
|
|
|
|
<Card style="margin-left: 2rem;margin-right: 2rem;" body color="warning">No dataset returned for <code>{item.name}</code></Card>
|
|
|
|
{/if}
|
2022-06-22 11:20:57 +02:00
|
|
|
</PlotTable>
|
|
|
|
{/if}
|
|
|
|
</Col>
|
|
|
|
</Row>
|