✨ Built system load and load history widgets
This commit is contained in:
@@ -4,13 +4,13 @@
|
||||
<p class="disk-name">{{ disk.name }}</p>
|
||||
<!-- Read Data -->
|
||||
<div class="io-data read" v-tooltip="disk.readC ? `Count: ${disk.readC}` : ''">
|
||||
<span class="lbl">Read:</span>
|
||||
<span class="lbl">{{ $t('widgets.glances.disk-io-read') }}:</span>
|
||||
<span class="val">{{ disk.readB | formatSize }}</span>
|
||||
<span :class="`direction ${disk.readD}`">{{ disk.readD | getArrow }}</span>
|
||||
</div>
|
||||
<!-- Write Data -->
|
||||
<div class="io-data write" v-tooltip="disk.writeC ? `Count: ${disk.writeC}` : ''">
|
||||
<span class="lbl">Write:</span>
|
||||
<span class="lbl">{{ $t('widgets.glances.disk-io-write') }}:</span>
|
||||
<span class="val">{{ disk.writeB | formatSize }}</span>
|
||||
<span :class="`direction ${disk.writeD}`">{{ disk.writeD | getArrow }}</span>
|
||||
</div>
|
||||
|
||||
95
src/components/Widgets/GlLoadHistory.vue
Normal file
95
src/components/Widgets/GlLoadHistory.vue
Normal file
@@ -0,0 +1,95 @@
|
||||
<template>
|
||||
<div class="glances-load-history-wrapper">
|
||||
<div class="gl-history-chart" :id="chartId"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import ChartingMixin from '@/mixins/ChartingMixin';
|
||||
import { timestampToTime, getTimeAgo } from '@/utils/MiscHelpers';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin, ChartingMixin],
|
||||
components: {},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
hostname() {
|
||||
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
|
||||
return this.options.hostname;
|
||||
},
|
||||
limit() {
|
||||
return this.options.limit || 500;
|
||||
},
|
||||
endpoint() {
|
||||
return `${this.hostname}/api/3/load/history/${this.limit}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.makeRequest(this.endpoint).then(this.processData);
|
||||
},
|
||||
processData(loadData) {
|
||||
const labels = [];
|
||||
const min1 = [];
|
||||
const min5 = [];
|
||||
const min15 = [];
|
||||
loadData.min1.forEach((dataPoint) => {
|
||||
labels.push(timestampToTime(dataPoint[0]));
|
||||
min1.push(dataPoint[1]);
|
||||
});
|
||||
loadData.min5.forEach((dataPoint) => {
|
||||
min5.push(dataPoint[1]);
|
||||
});
|
||||
loadData.min15.forEach((dataPoint) => {
|
||||
min15.push(dataPoint[1]);
|
||||
});
|
||||
|
||||
const chartTitle = this.makeTitle(loadData.min1);
|
||||
const datasets = [
|
||||
{ name: '1 Minute', type: 'bar', values: min1 },
|
||||
{ name: '5 Minutes', type: 'bar', values: min5 },
|
||||
{ name: '15 Minutes', type: 'bar', values: min15 },
|
||||
];
|
||||
this.generateChart({ labels, datasets }, chartTitle);
|
||||
},
|
||||
makeTitle(system) {
|
||||
return `System Load over past ${getTimeAgo(system[0][0]).replace('ago', '')}`;
|
||||
},
|
||||
generateChart(timeChartData, chartTitle) {
|
||||
return new this.Chart(`#${this.chartId}`, {
|
||||
title: chartTitle,
|
||||
data: timeChartData,
|
||||
type: 'axis-mixed',
|
||||
height: this.chartHeight,
|
||||
colors: this.chartColors,
|
||||
truncateLegends: true,
|
||||
lineOptions: {
|
||||
regionFill: 1,
|
||||
hideDots: 1,
|
||||
},
|
||||
axisOptions: {
|
||||
xIsSeries: true,
|
||||
xAxisMode: 'tick',
|
||||
},
|
||||
tooltipOptions: {
|
||||
formatTooltipY: d => `${d} Processes`,
|
||||
// formatTooltipX: d => timestampToTime(d),
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
},
|
||||
created() {
|
||||
this.overrideUpdateInterval = 20;
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.glances-load-history-wrapper {
|
||||
.gl-history-chart {}
|
||||
}
|
||||
</style>
|
||||
68
src/components/Widgets/GlSystemLoad.vue
Normal file
68
src/components/Widgets/GlSystemLoad.vue
Normal file
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="glances-load-wrapper">
|
||||
<div
|
||||
:id="`load-${chartId}`" class="load-chart"
|
||||
v-tooltip="$t('widgets.glances.system-load-desc')"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetMixin from '@/mixins/WidgetMixin';
|
||||
import ChartingMixin from '@/mixins/ChartingMixin';
|
||||
|
||||
export default {
|
||||
mixins: [WidgetMixin, ChartingMixin],
|
||||
computed: {
|
||||
hostname() {
|
||||
if (!this.options.hostname) this.error('You must specify a \'hostname\' for Glaces');
|
||||
return this.options.hostname;
|
||||
},
|
||||
endpoint() {
|
||||
return `${this.hostname}/api/3/load`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
fetchData() {
|
||||
this.makeRequest(this.endpoint).then(this.processData);
|
||||
},
|
||||
processData(loadData) {
|
||||
const chartData = {
|
||||
labels: ['1 Min', '5 Mins', '15 Mins'],
|
||||
datasets: [
|
||||
{ values: [loadData.min1, loadData.min5, loadData.min15] },
|
||||
],
|
||||
};
|
||||
const chartTitle = `Load Averages over ${loadData.cpucore} Cores`;
|
||||
this.renderChart(chartData, chartTitle);
|
||||
},
|
||||
renderChart(loadBarChartData, chartTitle) {
|
||||
return new this.Chart(`#load-${this.chartId}`, {
|
||||
title: chartTitle,
|
||||
data: loadBarChartData,
|
||||
type: 'bar',
|
||||
height: 180,
|
||||
colors: ['#04e4f4'],
|
||||
barOptions: {
|
||||
spaceRatio: 0.2,
|
||||
},
|
||||
tooltipOptions: {
|
||||
formatTooltipY: d => `${d} Tasks`,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.glances-load-wrapper {
|
||||
p.desc {
|
||||
color: var(--widget-text-color);
|
||||
opacity: var(--dimming-factor);
|
||||
font-size: 0.8rem;
|
||||
margin: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
&:hover p.desc { visibility: visible; }
|
||||
}
|
||||
</style>
|
||||
@@ -144,6 +144,13 @@
|
||||
@error="handleError"
|
||||
:ref="widgetRef"
|
||||
/>
|
||||
<GlLoadHistory
|
||||
v-else-if="widgetType === 'gl-load-history'"
|
||||
:options="widgetOptions"
|
||||
@loading="setLoaderState"
|
||||
@error="handleError"
|
||||
:ref="widgetRef"
|
||||
/>
|
||||
<GlMemGauge
|
||||
v-else-if="widgetType === 'gl-current-mem'"
|
||||
:options="widgetOptions"
|
||||
@@ -158,6 +165,13 @@
|
||||
@error="handleError"
|
||||
:ref="widgetRef"
|
||||
/>
|
||||
<GlSystemLoad
|
||||
v-else-if="widgetType === 'gl-system-load'"
|
||||
:options="widgetOptions"
|
||||
@loading="setLoaderState"
|
||||
@error="handleError"
|
||||
:ref="widgetRef"
|
||||
/>
|
||||
<HealthChecks
|
||||
v-else-if="widgetType === 'health-checks'"
|
||||
:options="widgetOptions"
|
||||
@@ -353,8 +367,10 @@ export default {
|
||||
GlCpuHistory: () => import('@/components/Widgets/GlCpuHistory.vue'),
|
||||
GlDiskIo: () => import('@/components/Widgets/GlDiskIo.vue'),
|
||||
GlDiskSpace: () => import('@/components/Widgets/GlDiskSpace.vue'),
|
||||
GlLoadHistory: () => import('@/components/Widgets/GlLoadHistory.vue'),
|
||||
GlMemGauge: () => import('@/components/Widgets/GlMemGauge.vue'),
|
||||
GlMemHistory: () => import('@/components/Widgets/GlMemHistory.vue'),
|
||||
GlSystemLoad: () => import('@/components/Widgets/GlSystemLoad.vue'),
|
||||
HealthChecks: () => import('@/components/Widgets/HealthChecks.vue'),
|
||||
IframeWidget: () => import('@/components/Widgets/IframeWidget.vue'),
|
||||
Jokes: () => import('@/components/Widgets/Jokes.vue'),
|
||||
|
||||
Reference in New Issue
Block a user