diff options
Diffstat (limited to 'app/assets/javascripts/monitoring/components')
-rw-r--r-- | app/assets/javascripts/monitoring/components/dashboard.vue | 80 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/components/empty_state.vue | 62 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/components/graph.vue | 69 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/components/graph/deployment.vue | 14 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/components/graph/flag.vue | 5 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/components/graph/legend.vue | 15 | ||||
-rw-r--r-- | app/assets/javascripts/monitoring/components/graph/path.vue (renamed from app/assets/javascripts/monitoring/components/monitoring_paths.vue) | 0 |
7 files changed, 129 insertions, 116 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index b596c4f383f..cbe24c0915b 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -1,13 +1,13 @@ <script> - /* global Flash */ import _ from 'underscore'; - import statusCodes from '../../lib/utils/http_status'; + import Flash from '../../flash'; import MonitoringService from '../services/monitoring_service'; import GraphGroup from './graph_group.vue'; import Graph from './graph.vue'; import EmptyState from './empty_state.vue'; import MonitoringStore from '../stores/monitoring_store'; import eventHub from '../event_hub'; + import { convertPermissionToBoolean } from '../../lib/utils/common_utils'; export default { @@ -18,15 +18,18 @@ return { store, state: 'gettingStarted', - hasMetrics: gl.utils.convertPermissionToBoolean(metricsData.hasMetrics), + hasMetrics: convertPermissionToBoolean(metricsData.hasMetrics), documentationPath: metricsData.documentationPath, settingsPath: metricsData.settingsPath, - endpoint: metricsData.additionalMetrics, + metricsEndpoint: metricsData.additionalMetrics, deploymentEndpoint: metricsData.deploymentEndpoint, + emptyGettingStartedSvgPath: metricsData.emptyGettingStartedSvgPath, + emptyLoadingSvgPath: metricsData.emptyLoadingSvgPath, + emptyUnableToConnectSvgPath: metricsData.emptyUnableToConnectSvgPath, showEmptyState: true, - backOffRequestCounter: 0, updateAspectRatio: false, updatedAspectRatios: 0, + hoverData: {}, resizeThrottled: {}, }; }, @@ -39,50 +42,16 @@ methods: { getGraphsData() { - const maxNumberOfRequests = 3; this.state = 'loading'; - gl.utils.backOff((next, stop) => { - this.service.get().then((resp) => { - if (resp.status === statusCodes.NO_CONTENT) { - this.backOffRequestCounter = this.backOffRequestCounter += 1; - if (this.backOffRequestCounter < maxNumberOfRequests) { - next(); - } else { - stop(new Error('Failed to connect to the prometheus server')); - } - } else { - stop(resp); - } - }).catch(stop); - }) - .then((resp) => { - if (resp.status === statusCodes.NO_CONTENT) { - this.state = 'unableToConnect'; - return false; - } - return resp.json(); - }) - .then((metricGroupsData) => { - if (!metricGroupsData) return false; - this.store.storeMetrics(metricGroupsData.data); - return this.getDeploymentData(); - }) - .then((deploymentData) => { - if (deploymentData !== false) { - this.store.storeDeploymentData(deploymentData.deployments); - this.showEmptyState = false; - } - return {}; - }) - .catch(() => { - this.state = 'unableToConnect'; - }); - }, - - getDeploymentData() { - return this.service.getDeploymentData(this.deploymentEndpoint) - .then(resp => resp.json()) - .catch(() => new Flash('Error getting deployment information.')); + Promise.all([ + this.service.getGraphsData() + .then(data => this.store.storeMetrics(data)), + this.service.getDeploymentData() + .then(data => this.store.storeDeploymentData(data)) + .catch(() => new Flash('Error getting deployment information.')), + ]) + .then(() => { this.showEmptyState = false; }) + .catch(() => { this.state = 'unableToConnect'; }); }, resize() { @@ -96,15 +65,24 @@ this.updatedAspectRatios = 0; } }, + + hoverChanged(data) { + this.hoverData = data; + }, }, created() { - this.service = new MonitoringService(this.endpoint); + this.service = new MonitoringService({ + metricsEndpoint: this.metricsEndpoint, + deploymentEndpoint: this.deploymentEndpoint, + }); eventHub.$on('toggleAspectRatio', this.toggleAspectRatio); + eventHub.$on('hoverChanged', this.hoverChanged); }, beforeDestroy() { eventHub.$off('toggleAspectRatio', this.toggleAspectRatio); + eventHub.$off('hoverChanged', this.hoverChanged); window.removeEventListener('resize', this.resizeThrottled, false); }, @@ -131,6 +109,7 @@ v-for="(graphData, index) in groupData.metrics" :key="index" :graph-data="graphData" + :hover-data="hoverData" :update-aspect-ratio="updateAspectRatio" :deployment-data="store.deploymentData" /> @@ -141,5 +120,8 @@ :selected-state="state" :documentation-path="documentationPath" :settings-path="settingsPath" + :empty-getting-started-svg-path="emptyGettingStartedSvgPath" + :empty-loading-svg-path="emptyLoadingSvgPath" + :empty-unable-to-connect-svg-path="emptyUnableToConnectSvgPath" /> </template> diff --git a/app/assets/javascripts/monitoring/components/empty_state.vue b/app/assets/javascripts/monitoring/components/empty_state.vue index a8708be76de..a18164482a2 100644 --- a/app/assets/javascripts/monitoring/components/empty_state.vue +++ b/app/assets/javascripts/monitoring/components/empty_state.vue @@ -1,8 +1,4 @@ <script> - import gettingStartedSvg from 'empty_states/monitoring/_getting_started.svg'; - import loadingSvg from 'empty_states/monitoring/_loading.svg'; - import unableToConnectSvg from 'empty_states/monitoring/_unable_to_connect.svg'; - export default { props: { documentationPath: { @@ -18,24 +14,36 @@ type: String, required: true, }, + emptyGettingStartedSvgPath: { + type: String, + required: true, + }, + emptyLoadingSvgPath: { + type: String, + required: true, + }, + emptyUnableToConnectSvgPath: { + type: String, + required: true, + }, }, data() { return { states: { gettingStarted: { - svg: gettingStartedSvg, + svgUrl: this.emptyGettingStartedSvgPath, title: 'Get started with performance monitoring', description: 'Stay updated about the performance and health of your environment by configuring Prometheus to monitor your deployments.', buttonText: 'Configure Prometheus', }, loading: { - svg: loadingSvg, + svgUrl: this.emptyLoadingSvgPath, title: 'Waiting for performance data', description: 'Creating graphs uses the data from the Prometheus server. If this takes a long time, ensure that data is available.', buttonText: 'View documentation', }, unableToConnect: { - svg: unableToConnectSvg, + svgUrl: this.emptyUnableToConnectSvgPath, title: 'Unable to connect to Prometheus server', description: 'Ensure connectivity is available from the GitLab server to the ', buttonText: 'View documentation', @@ -65,32 +73,22 @@ <template> <div class="prometheus-state"> - <div class="row"> - <div class="col-md-4 col-md-offset-4 state-svg" v-html="currentState.svg"></div> - </div> - <div class="row"> - <div class="col-md-6 col-md-offset-3"> - <h4 class="text-center state-title"> - {{currentState.title}} - </h4> - </div> - </div> - <div class="row"> - <div class="col-md-6 col-md-offset-3"> - <div class="description-text text-center state-description"> - {{currentState.description}} - <a v-if="showButtonDescription" :href="settingsPath"> - Prometheus server - </a> - </div> - </div> + <div class="state-svg svg-content"> + <img :src="currentState.svgUrl"/> </div> - <div class="row state-button-section"> - <div class="col-md-4 col-md-offset-4 text-center state-button"> - <a class="btn btn-success" :href="buttonPath"> - {{currentState.buttonText}} - </a> - </div> + <h4 class="state-title"> + {{currentState.title}} + </h4> + <p class="state-description"> + {{currentState.description}} + <a v-if="showButtonDescription" :href="settingsPath"> + Prometheus server + </a> + </p> + <div class="state-button"> + <a class="btn btn-success" :href="buttonPath"> + {{currentState.buttonText}} + </a> </div> </div> </template> diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index cde2ff7ca2a..5aa3865f96a 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -3,16 +3,14 @@ import GraphLegend from './graph/legend.vue'; import GraphFlag from './graph/flag.vue'; import GraphDeployment from './graph/deployment.vue'; - import monitoringPaths from './monitoring_paths.vue'; + import GraphPath from './graph/path.vue'; import MonitoringMixin from '../mixins/monitoring_mixins'; import eventHub from '../event_hub'; import measurements from '../utils/measurements'; - import { timeScaleFormat } from '../utils/date_time_formatters'; + import { timeScaleFormat, bisectDate } from '../utils/date_time_formatters'; import createTimeSeries from '../utils/multiple_time_series'; import bp from '../../breakpoints'; - const bisectDate = d3.bisector(d => d.time).left; - export default { props: { graphData: { @@ -27,6 +25,11 @@ type: Array, required: true, }, + hoverData: { + type: Object, + required: false, + default: () => ({}), + }, }, mixins: [MonitoringMixin], @@ -40,8 +43,6 @@ graphHeightOffset: 120, margin: {}, unitOfDisplay: '', - areaColorRgb: '#8fbce8', - lineColorRgb: '#1f78d1', yAxisLabel: '', legendTitle: '', reducedDeploymentData: [], @@ -54,6 +55,7 @@ currentXCoordinate: 0, currentFlagPosition: 0, showFlag: false, + showFlagContent: false, showDeployInfo: true, timeSeries: [], }; @@ -63,11 +65,11 @@ GraphLegend, GraphFlag, GraphDeployment, - monitoringPaths, + GraphPath, }, computed: { - outterViewBox() { + outerViewBox() { return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`; }, @@ -124,36 +126,30 @@ const d1 = firstTimeSeries.values[overlayIndex]; if (d0 === undefined || d1 === undefined) return; const evalTime = timeValueOverlay - d0[0] > d1[0] - timeValueOverlay; - this.currentData = evalTime ? d1 : d0; - this.currentDataIndex = evalTime ? overlayIndex : (overlayIndex - 1); - this.currentXCoordinate = Math.floor(firstTimeSeries.timeSeriesScaleX(this.currentData.time)); + const hoveredDataIndex = evalTime ? overlayIndex : (overlayIndex - 1); + const hoveredDate = firstTimeSeries.values[hoveredDataIndex].time; const currentDeployXPos = this.mouseOverDeployInfo(point.x); - if (this.currentXCoordinate > (this.graphWidth - 200)) { - this.currentFlagPosition = this.currentXCoordinate - 103; - } else { - this.currentFlagPosition = this.currentXCoordinate; - } - - if (currentDeployXPos) { - this.showFlag = false; - } else { - this.showFlag = true; - } + eventHub.$emit('hoverChanged', { + hoveredDate, + currentDeployXPos, + }); }, renderAxesPaths() { - this.timeSeries = createTimeSeries(this.graphData.queries[0].result, - this.graphWidth, - this.graphHeight, - this.graphHeightOffset); + this.timeSeries = createTimeSeries( + this.graphData.queries[0], + this.graphWidth, + this.graphHeight, + this.graphHeightOffset, + ); if (this.timeSeries.length > 3) { this.baseGraphHeight = this.baseGraphHeight += (this.timeSeries.length - 3) * 20; } const axisXScale = d3.time.scale() - .range([0, this.graphWidth]); + .range([0, this.graphWidth - 70]); const axisYScale = d3.scale.linear() .range([this.graphHeight - this.graphHeightOffset, 0]); @@ -162,7 +158,7 @@ const xAxis = d3.svg.axis() .scale(axisXScale) - .ticks(measurements.xTicks) + .ticks(d3.time.minute, 60) .tickFormat(timeScaleFormat) .orient('bottom'); @@ -196,6 +192,10 @@ eventHub.$emit('toggleAspectRatio'); } }, + + hoverData() { + this.positionFlag(); + }, }, mounted() { @@ -205,7 +205,10 @@ </script> <template> - <div class="prometheus-graph"> + <div + class="prometheus-graph" + @mouseover="showFlagContent = true" + @mouseleave="showFlagContent = false"> <h5 class="text-center graph-title"> {{graphData.title}} </h5> @@ -213,7 +216,7 @@ class="prometheus-svg-container" :style="paddingBottomRootSvg"> <svg - :viewBox="outterViewBox" + :viewBox="outerViewBox" ref="baseSvg"> <g class="x-axis" @@ -238,7 +241,7 @@ class="graph-data" :viewBox="innerViewBox" ref="graphData"> - <monitoring-paths + <graph-path v-for="(path, index) in timeSeries" :key="index" :generated-line-path="path.linePath" @@ -246,9 +249,10 @@ :line-color="path.lineColor" :area-color="path.areaColor" /> - <monitoring-deployment + <graph-deployment :show-deploy-info="showDeployInfo" :deployment-data="reducedDeploymentData" + :graph-width="graphWidth" :graph-height="graphHeight" :graph-height-offset="graphHeightOffset" /> @@ -259,6 +263,7 @@ :current-flag-position="currentFlagPosition" :graph-height="graphHeight" :graph-height-offset="graphHeightOffset" + :show-flag-content="showFlagContent" /> <rect class="prometheus-graph-overlay" diff --git a/app/assets/javascripts/monitoring/components/graph/deployment.vue b/app/assets/javascripts/monitoring/components/graph/deployment.vue index 3623d2ed946..e3b8be0c7fb 100644 --- a/app/assets/javascripts/monitoring/components/graph/deployment.vue +++ b/app/assets/javascripts/monitoring/components/graph/deployment.vue @@ -19,6 +19,10 @@ type: Number, required: true, }, + graphWidth: { + type: Number, + required: true, + }, }, computed: { @@ -47,6 +51,14 @@ transformDeploymentGroup(deployment) { return `translate(${Math.floor(deployment.xPos) + 1}, 20)`; }, + + positionFlag(deployment) { + let xPosition = 3; + if (deployment.xPos > (this.graphWidth - 200)) { + xPosition = -97; + } + return xPosition; + }, }, }; </script> @@ -77,7 +89,7 @@ <svg v-if="deployment.showDeploymentFlag" class="js-deploy-info-box" - x="3" + :x="positionFlag(deployment)" y="0" width="92" height="60"> diff --git a/app/assets/javascripts/monitoring/components/graph/flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue index a98e3d06c18..10fb7ff6803 100644 --- a/app/assets/javascripts/monitoring/components/graph/flag.vue +++ b/app/assets/javascripts/monitoring/components/graph/flag.vue @@ -23,6 +23,10 @@ type: Number, required: true, }, + showFlagContent: { + type: Boolean, + required: true, + }, }, data() { @@ -57,6 +61,7 @@ transform="translate(-5, 20)"> </line> <svg + v-if="showFlagContent" class="rect-text-metric" :x="currentFlagPosition" y="0"> diff --git a/app/assets/javascripts/monitoring/components/graph/legend.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue index a43dad8e601..85b6d7f4cbe 100644 --- a/app/assets/javascripts/monitoring/components/graph/legend.vue +++ b/app/assets/javascripts/monitoring/components/graph/legend.vue @@ -79,7 +79,18 @@ }, formatMetricUsage(series) { - return `${formatRelevantDigits(series.values[this.currentDataIndex].value)} ${this.unitOfDisplay}`; + const value = series.values[this.currentDataIndex].value; + if (isNaN(value)) { + return '-'; + } + return `${formatRelevantDigits(value)} ${this.unitOfDisplay}`; + }, + + createSeriesString(index, series) { + if (series.metricTag) { + return `${series.metricTag} ${this.formatMetricUsage(series)}`; + } + return `${this.legendTitle} series ${index + 1} ${this.formatMetricUsage(series)}`; }, }, mounted() { @@ -164,7 +175,7 @@ ref="legendTitleSvg" x="38" :y="graphHeight - 30"> - {{legendTitle}} Series {{index + 1}} {{formatMetricUsage(series)}} + {{createSeriesString(index, series)}} </text> <text v-else diff --git a/app/assets/javascripts/monitoring/components/monitoring_paths.vue b/app/assets/javascripts/monitoring/components/graph/path.vue index 043f1bf66bb..043f1bf66bb 100644 --- a/app/assets/javascripts/monitoring/components/monitoring_paths.vue +++ b/app/assets/javascripts/monitoring/components/graph/path.vue |