memory_usage.vue 5.3 KB
Newer Older
1
<script>
2
/* eslint-disable vue/no-v-html */
3
import { sprintf, s__ } from '~/locale';
4 5 6 7 8
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';
F
Fatih Acet 已提交
9 10 11

export default {
  name: 'MemoryUsage',
12 13 14
  components: {
    MemoryGraph,
  },
F
Fatih Acet 已提交
15
  props: {
16 17 18 19 20 21 22 23
    metricsUrl: {
      type: String,
      required: true,
    },
    metricsMonitoringUrl: {
      type: String,
      required: true,
    },
F
Fatih Acet 已提交
24 25 26
  },
  data() {
    return {
27 28
      memoryFrom: 0,
      memoryTo: 0,
F
Fatih Acet 已提交
29
      memoryMetrics: [],
30
      deploymentTime: 0,
F
Fatih Acet 已提交
31 32 33 34 35 36
      hasMetrics: false,
      loadFailed: false,
      loadingMetrics: true,
      backOffRequestCounter: 0,
    };
  },
37 38 39 40 41 42 43 44 45 46 47 48 49
  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;
    },
50 51 52 53 54 55 56 57 58
    memoryChangeMessage() {
      const messageProps = {
        memoryFrom: this.memoryFrom,
        memoryTo: this.memoryTo,
        metricsLinkStart: `<a href="${this.metricsMonitoringUrl}">`,
        metricsLinkEnd: '</a>',
        emphasisStart: '<b>',
        emphasisEnd: '</b>',
      };
59 60
      const memoryTo = Number(this.memoryTo);
      const memoryFrom = Number(this.memoryFrom);
61
      let memoryUsageMsg = '';
62 63

      if (memoryTo > memoryFrom) {
64 65 66 67 68 69 70
        memoryUsageMsg = sprintf(
          s__(
            'mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} increased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB',
          ),
          messageProps,
          false,
        );
71
      } else if (memoryTo < memoryFrom) {
72 73 74 75 76 77 78
        memoryUsageMsg = sprintf(
          s__(
            'mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage %{emphasisStart} decreased %{emphasisEnd} from %{memoryFrom}MB to %{memoryTo}MB',
          ),
          messageProps,
          false,
        );
79
      } else {
80 81 82 83 84 85 86
        memoryUsageMsg = sprintf(
          s__(
            'mrWidget|%{metricsLinkStart} Memory %{metricsLinkEnd} usage is %{emphasisStart} unchanged %{emphasisEnd} at %{memoryFrom}MB',
          ),
          messageProps,
          false,
        );
87 88
      }

89
      return memoryUsageMsg;
90
    },
91
  },
92 93 94 95
  mounted() {
    this.loadingMetrics = true;
    this.loadMetrics();
  },
F
Fatih Acet 已提交
96
  methods: {
97 98
    getMegabytes(bytesString) {
      const valueInBytes = Number(bytesString).toFixed(2);
99
      return bytesToMiB(valueInBytes).toFixed(2);
100
    },
101
    computeGraphData(metrics, deploymentTime) {
F
Fatih Acet 已提交
102
      this.loadingMetrics = false;
103 104 105 106 107 108 109 110 111 112 113 114
      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]);
      }
F
Fatih Acet 已提交
115 116 117 118

      if (memory_values.length > 0) {
        this.hasMetrics = true;
        this.memoryMetrics = memory_values[0].values;
119
        this.deploymentTime = deploymentTime;
F
Fatih Acet 已提交
120 121
      }
    },
122
    loadMetrics() {
F
Filipa Lacerda 已提交
123
      backOff((next, stop) => {
124
        MRWidgetService.fetchMetrics(this.metricsUrl)
125
          .then(res => {
126
            if (res.status === statusCodes.NO_CONTENT) {
G
gfyoung 已提交
127
              this.backOffRequestCounter += 1;
128 129
              /* eslint-disable no-unused-expressions */
              this.backOffRequestCounter < 3 ? next() : stop(res);
F
Fatih Acet 已提交
130 131 132
            } else {
              stop(res);
            }
133 134 135
          })
          .catch(stop);
      })
136
        .then(res => {
137 138
          if (res.status === statusCodes.NO_CONTENT) {
            return res;
F
Fatih Acet 已提交
139 140
          }

141
          return res.data;
142
        })
143
        .then(data => {
144 145
          this.computeGraphData(data.metrics, data.deployment_time);
          return data;
146 147 148 149 150 151 152
        })
        .catch(() => {
          this.loadFailed = true;
          this.loadingMetrics = false;
        });
    },
  },
F
Fatih Acet 已提交
153
};
154 155 156 157
</script>

<template>
  <div class="mr-info-list clearfix mr-memory-usage js-mr-memory-usage">
M
Mike Greiling 已提交
158 159 160
    <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') }}
161 162 163
    </p>
    <p
      v-if="shouldShowMemoryGraph"
164
      class="usage-info js-usage-info"
M
Mike Greiling 已提交
165 166 167
      v-html="memoryChangeMessage"
    ></p>
    <p v-if="shouldShowLoadFailure" class="usage-info js-usage-info usage-info-failed">
168
      {{ s__('mrWidget|Failed to load deployment statistics') }}
169
    </p>
M
Mike Greiling 已提交
170
    <p v-if="shouldShowMetricsUnavailable" class="usage-info js-usage-info usage-info-unavailable">
171
      {{ s__('mrWidget|Deployment statistics are not available currently') }}
172
    </p>
173
    <memory-graph v-if="shouldShowMemoryGraph" :metrics="memoryMetrics" :height="25" :width="110" />
174 175
  </div>
</template>