170 lines
5.3 KiB
Vue
170 lines
5.3 KiB
Vue
<script>
|
|
import { sprintf, s__ } from '~/locale';
|
|
import statusCodes from '../../lib/utils/http_status';
|
|
import { bytesToMiB } from '../../lib/utils/number_utils';
|
|
import { backOff } from '../../lib/utils/common_utils';
|
|
import MemoryGraph from '../../vue_shared/components/memory_graph.vue';
|
|
import MRWidgetService from '../services/mr_widget_service';
|
|
|
|
export default {
|
|
name: 'MemoryUsage',
|
|
components: {
|
|
MemoryGraph,
|
|
},
|
|
props: {
|
|
metricsUrl: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
metricsMonitoringUrl: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
memoryFrom: 0,
|
|
memoryTo: 0,
|
|
memoryMetrics: [],
|
|
deploymentTime: 0,
|
|
hasMetrics: false,
|
|
loadFailed: false,
|
|
loadingMetrics: true,
|
|
backOffRequestCounter: 0,
|
|
};
|
|
},
|
|
computed: {
|
|
shouldShowLoading() {
|
|
return this.loadingMetrics && !this.hasMetrics && !this.loadFailed;
|
|
},
|
|
shouldShowMemoryGraph() {
|
|
return !this.loadingMetrics && this.hasMetrics && !this.loadFailed;
|
|
},
|
|
shouldShowLoadFailure() {
|
|
return !this.loadingMetrics && !this.hasMetrics && this.loadFailed;
|
|
},
|
|
shouldShowMetricsUnavailable() {
|
|
return !this.loadingMetrics && !this.hasMetrics && !this.loadFailed;
|
|
},
|
|
memoryChangeMessage() {
|
|
const messageProps = {
|
|
memoryFrom: this.memoryFrom,
|
|
memoryTo: this.memoryTo,
|
|
metricsLinkStart: `<a href="${this.metricsMonitoringUrl}">`,
|
|
metricsLinkEnd: '</a>',
|
|
emphasisStart: '<b>',
|
|
emphasisEnd: '</b>',
|
|
};
|
|
const memoryTo = Number(this.memoryTo);
|
|
const memoryFrom = Number(this.memoryFrom);
|
|
let memoryUsageMsg = '';
|
|
|
|
if (memoryTo > memoryFrom) {
|
|
memoryUsageMsg = sprintf(s__('mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} increased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB'), messageProps, false);
|
|
} else if (memoryTo < memoryFrom) {
|
|
memoryUsageMsg = sprintf(s__('mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB'), messageProps, false);
|
|
} else {
|
|
memoryUsageMsg = sprintf(s__('mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage is %{emphasisStart} unchanged %{emphasisEnd} at %{memoryFrom}MB'), messageProps, false);
|
|
}
|
|
|
|
return memoryUsageMsg;
|
|
},
|
|
},
|
|
mounted() {
|
|
this.loadingMetrics = true;
|
|
this.loadMetrics();
|
|
},
|
|
methods: {
|
|
getMegabytes(bytesString) {
|
|
const valueInBytes = Number(bytesString).toFixed(2);
|
|
return (bytesToMiB(valueInBytes)).toFixed(2);
|
|
},
|
|
computeGraphData(metrics, deploymentTime) {
|
|
this.loadingMetrics = false;
|
|
const { memory_before, memory_after, memory_values } = metrics;
|
|
|
|
// Both `memory_before` and `memory_after` objects
|
|
// have peculiar structure where accessing only a specific
|
|
// index yeilds correct value that we can use to show memory delta.
|
|
if (memory_before.length > 0) {
|
|
this.memoryFrom = this.getMegabytes(memory_before[0].value[1]);
|
|
}
|
|
|
|
if (memory_after.length > 0) {
|
|
this.memoryTo = this.getMegabytes(memory_after[0].value[1]);
|
|
}
|
|
|
|
if (memory_values.length > 0) {
|
|
this.hasMetrics = true;
|
|
this.memoryMetrics = memory_values[0].values;
|
|
this.deploymentTime = deploymentTime;
|
|
}
|
|
},
|
|
loadMetrics() {
|
|
backOff((next, stop) => {
|
|
MRWidgetService.fetchMetrics(this.metricsUrl)
|
|
.then((res) => {
|
|
if (res.status === statusCodes.NO_CONTENT) {
|
|
this.backOffRequestCounter += 1;
|
|
/* eslint-disable no-unused-expressions */
|
|
this.backOffRequestCounter < 3 ? next() : stop(res);
|
|
} else {
|
|
stop(res);
|
|
}
|
|
})
|
|
.catch(stop);
|
|
})
|
|
.then((res) => {
|
|
if (res.status === statusCodes.NO_CONTENT) {
|
|
return res;
|
|
}
|
|
|
|
return res.data;
|
|
})
|
|
.then((data) => {
|
|
this.computeGraphData(data.metrics, data.deployment_time);
|
|
return data;
|
|
})
|
|
.catch(() => {
|
|
this.loadFailed = true;
|
|
this.loadingMetrics = false;
|
|
});
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="mr-info-list clearfix mr-memory-usage js-mr-memory-usage">
|
|
<p
|
|
v-if="shouldShowLoading"
|
|
class="usage-info js-usage-info usage-info-loading">
|
|
<i
|
|
class="fa fa-spinner fa-spin usage-info-load-spinner"
|
|
aria-hidden="true">
|
|
</i>{{ s__('mrWidget|Loading deployment statistics') }}
|
|
</p>
|
|
<p
|
|
v-if="shouldShowMemoryGraph"
|
|
class="usage-info js-usage-info"
|
|
v-html="memoryChangeMessage">
|
|
</p>
|
|
<p
|
|
v-if="shouldShowLoadFailure"
|
|
class="usage-info js-usage-info usage-info-failed">
|
|
{{ s__('mrWidget|Failed to load deployment statistics') }}
|
|
</p>
|
|
<p
|
|
v-if="shouldShowMetricsUnavailable"
|
|
class="usage-info js-usage-info usage-info-unavailable">
|
|
{{ s__('mrWidget|Deployment statistics are not available currently') }}
|
|
</p>
|
|
<memory-graph
|
|
v-if="shouldShowMemoryGraph"
|
|
:metrics="memoryMetrics"
|
|
:deployment-time="deploymentTime"
|
|
height="25"
|
|
width="100"
|
|
/>
|
|
</div>
|
|
</template>
|