Commit ab3978af authored by Jose Ivan Vargas's avatar Jose Ivan Vargas

Added basic javascript/frontend functionality

parent e70dbfbe
......@@ -241,14 +241,25 @@
}
}
.loading-metrics,
.empty-metrics {
padding: 30px 10px;
.custom-monitored-metrics {
margin-bottom: 0;
.panel-title {
display: flex;
align-items: center;
> .btn-success {
margin-left: auto;
}
}
}
.empty-metrics,
.loading-metrics {
p,
.btn {
margin-top: 10px;
margin-bottom: 0;
margin: 10px 0;
margin-left: 10px;
}
}
......
.row.prepend-top-default.append-bottom-default
.col-lg-3
%h4.prepend-top-0
Metric
%p
Metric allows you measuring stuff
= succeed "." do
= link_to "Read more about queries", help_page_path("prometheus/custom_metrics")
= form_for [@project.namespace.becomes(Namespace), @project, @metric], html: { class: 'col-lg-9' } do |f|
= form_errors(@metric)
.form-group
......@@ -16,13 +8,13 @@
= f.label :query, 'Query', class: 'label-light'
= f.text_field :query, required: true, class: 'form-control'
.form-group
= f.label :y_label, 'Y label', class: 'label-light'
= f.label :y_label, 'Y-axis label', class: 'label-light'
= f.text_field :y_label, class: 'form-control'
.form-group
= f.label :unit, 'Unit', class: 'label-light'
= f.label :unit, 'Unit label', class: 'label-light'
= f.text_field :unit, class: 'form-control'
.form-group
= f.label :legend, 'Legend', class: 'label-light'
= f.label :legend, 'Legend label', class: 'label-light'
= f.text_field :legend, class: 'form-control'
.form-actions
......
- breadcrumb_title @metric.title
- add_to_breadcrumbs("Settings", edit_project_path(@project))
- add_to_breadcrumbs("Prometheus", edit_project_service_path(@project, @project.prometheus_service))
- add_to_breadcrumbs "Settings", edit_project_path(@project)
- add_to_breadcrumbs "Integrations", project_settings_integrations_path(@project)
- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, 'prometheus')
- breadcrumb_title "Edit metric"
- page_title @metric.title, "Prometheus Metrics"
= render 'form'
- @no_container = true
- breadcrumb_title "Metrics"
- page_title 'Metrics'
- add_to_breadcrumbs "Settings", edit_project_path(@project)
- add_to_breadcrumbs "Integrations", project_settings_integrations_path(@project)
- add_to_breadcrumbs "Prometheus", edit_project_service_path(@project, 'prometheus')
- breadcrumb_title "New metric"
- page_title "New metric"
%div{ class: container_class }
%h3.page-title
......
- content_for :page_specific_javascripts do
= webpack_bundle_tag('prometheus_metrics')
= webpack_bundle_tag('ee_prometheus_metrics')
.row.prepend-top-default.append-bottom-default.prometheus-metrics-monitoring.js-prometheus-metrics-monitoring
.col-lg-3
......@@ -10,21 +10,34 @@
= link_to s_('PrometheusService|More information'), help_page_path('user/project/integrations/prometheus')
.col-lg-9
.panel.panel-default.js-panel-monitored-metrics{ data: { "active-metrics" => "#{active_namespace_project_prometheus_metrics_path(@project, :json)}" } }
.panel.panel-default.custom-monitored-metrics.js-panel-custom-monitored-metrics{ data: { "active-custom-metrics" => "#{project_prometheus_metrics_path(@project, :json)}" } }
.panel-heading
%h3.panel-title
= s_('PrometheusService|Monitored')
= s_('PrometheusService|Custom application metrics')
%span.badge.js-custom-monitored-count 0
= link_to s_('PrometheusService|New metric'), new_project_prometheus_metric_path(@project), class: 'btn btn-success js-new-metric-button hidden'
.panel-body
.loading-metrics.js-loading-custom-metrics
%p
= icon('spinner spin', class: 'metrics-load-spinner')
= s_('PrometheusService|Finding custom metrics...')
.empty-metrics.hidden.js-empty-custom-metrics
= link_to s_('PrometheusService|New metric'), new_project_prometheus_metric_path(@project), class: 'btn btn-success'
%ul.list-unstyled.metrics-list.hidden.js-custom-metrics-list
.panel.panel-default.js-panel-monitored-metrics{ data: { "active-metrics" => "#{active_project_prometheus_metrics_path(@project, :json)}" } }
.panel-heading
%h3.panel-title
= s_('PrometheusService|Common metrics')
%span.badge.js-monitored-count 0
.panel-body
.loading-metrics.text-center.js-loading-metrics
= icon('spinner spin 3x', class: 'metrics-load-spinner')
.loading-metrics.js-loading-metrics
%p
= icon('spinner spin', class: 'metrics-load-spinner')
= s_('PrometheusService|Finding and configuring metrics...')
.empty-metrics.text-center.hidden.js-empty-metrics
= custom_icon('icon_empty_metrics')
.empty-metrics.hidden.js-empty-metrics
%p
= s_('PrometheusService|No metrics are being monitored. To start monitoring, deploy to an environment.')
= link_to s_('PrometheusService|View environments'), project_environments_path(@project), class: 'btn btn-success'
= s_('PrometheusService|Waiting for your first deployment to an environment to find common metrics')
%ul.list-unstyled.metrics-list.hidden.js-metrics-list
.panel.panel-default.hidden.js-panel-missing-env-vars
......
......@@ -75,6 +75,7 @@ var config = {
project_import_gl: './projects/project_import_gitlab_project.js',
project_new: './projects/project_new.js',
prometheus_metrics: './prometheus_metrics',
ee_prometheus_metrics: 'ee/prometheus_metrics',
protected_branches: './protected_branches',
ee_protected_branches: 'ee/protected_branches',
protected_tags: './protected_tags',
......
import PrometheusMetrics from './prometheus_metrics';
$(() => {
const prometheusMetrics = new PrometheusMetrics('.js-prometheus-metrics-monitoring');
prometheusMetrics.loadActiveCustomMetrics();
});
import CEPrometheusMetrics from '~/prometheus_metrics/prometheus_metrics';
import PANEL_STATE from '~/prometheus_metrics/constants';
import axios from '~/lib/utils/axios_utils';
import statusCodes from '~/lib/utils/http_status';
import { backOff } from '~/lib/utils/common_utils';
const MAX_REQUESTS = 3;
function backOffRequest(makeRequestCallback) {
let requestCounter = 0;
return backOff((next, stop) => {
makeRequestCallback().then((resp) => {
if (resp.status === statusCodes.NO_CONTENT) {
requestCounter += 1;
if (requestCounter < MAX_REQUESTS) {
next();
} else {
stop(new Error('Failed to retrieve prometheus custom metrics'));
}
} else {
stop(resp);
}
}).catch(stop);
});
}
export default class PrometheusMetrics {
constructor(wrapperSelector) {
// Call the common metrics (CE stuff basically)
const cePrometheusMetrics = new CEPrometheusMetrics(wrapperSelector);
cePrometheusMetrics.loadActiveMetrics();
this.$wrapperCustomMetrics = $(wrapperSelector);
this.$monitoredCustomMetricsPanel = this.$wrapperCustomMetrics.find('.js-panel-custom-monitored-metrics');
this.$monitoredCustomMetricsCount = this.$monitoredCustomMetricsPanel.find('.js-custom-monitored-count');
this.$monitoredCustomMetricsLoading = this.$monitoredCustomMetricsPanel.find('.js-loading-custom-metrics');
this.$monitoredCustomMetricsEmpty = this.$monitoredCustomMetricsPanel.find('.js-empty-custom-metrics');
this.$monitoredCustomMetricsList = this.$monitoredCustomMetricsPanel.find('.js-custom-metrics-list');
this.activeCustomMetricsEndpoint = this.$monitoredCustomMetricsPanel.data('active-custom-metrics');
}
showMonitoringCustomMetricsPanelState(stateName) {
switch (stateName) {
case PANEL_STATE.LOADING:
this.$monitoredCustomMetricsLoading.removeClass('hidden');
this.$monitoredCustomMetricsEmpty.addClass('hidden');
this.$monitoredCustomMetricsList.addClass('hidden');
break;
case PANEL_STATE.LIST:
this.$monitoredCustomMetricsLoading.addClass('hidden');
this.$monitoredCustomMetricsEmpty.addClass('hidden');
this.$monitoredCustomMetricsList.removeClass('hidden');
break;
default:
this.$monitoredCustomMetricsLoading.addClass('hidden');
this.$monitoredCustomMetricsEmpty.removeClass('hidden');
this.$monitoredCustomMetricsList.addClass('hidden');
break;
}
}
populateActiveMetrics(metrics) {
let totalMonitoredMetrics = 0;
metrics.forEach((metric) => {
this.$monitoredMetricsList.append(`<li>${metric.group}</li>`);
totalMonitoredMetrics += metric.active_metrics;
});
this.$monitoredMetricsCount.text(totalMonitoredMetrics);
this.showMonitoringCustomMetricsPanelState(PANEL_STATE.LIST);
}
loadActiveCustomMetrics() {
backOffRequest(() => axios.get(this.activeCustomMetricsEndpoint))
.then(resp => resp.data)
.then((response) => {
if (!response || !response.data) {
// add a flash
this.showMonitoringCustomMetricsPanelState(PANEL_STATE.EMPTY);
} else {
this.populateActiveMetrics(response.data);
}
}).catch((err) => {
this.showMonitoringCustomMetricsPanelState(PANEL_STATE.EMPTY);
});
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment