gitlab-org--gitlab-foss/app/assets/javascripts/monitoring/utils.js

195 lines
5.7 KiB
JavaScript
Raw Normal View History

import { queryToObject, mergeUrlParams, removeParams } from '~/lib/utils/url_utility';
import {
timeRangeParamNames,
timeRangeFromParams,
timeRangeToParams,
} from '~/lib/utils/datetime_range';
/**
* This method is used to validate if the graph data format for a chart component
* that needs a time series as a response from a prometheus query (queryRange) is
* of a valid format or not.
* @param {Object} graphData the graph data response from a prometheus request
* @returns {boolean} whether the graphData format is correct
*/
export const graphDataValidatorForValues = (isValues, graphData) => {
const responseValueKeyName = isValues ? 'value' : 'values';
return (
Array.isArray(graphData.metrics) &&
graphData.metrics.filter(query => {
if (Array.isArray(query.result)) {
return (
query.result.filter(res => Array.isArray(res[responseValueKeyName])).length ===
query.result.length
);
}
return false;
}).length === graphData.metrics.filter(query => query.result).length
);
};
/* eslint-disable @gitlab/require-i18n-strings */
/**
* Checks that element that triggered event is located on cluster health check dashboard
* @param {HTMLElement} element to check against
* @returns {boolean}
*/
const isClusterHealthBoard = () => (document.body.dataset.page || '').includes(':clusters:show');
/**
* Tracks snowplow event when user generates link to metric chart
* @param {String} chart link that will be sent as a property for the event
* @return {Object} config object for event tracking
*/
export const generateLinkToChartOptions = chartLink => {
const isCLusterHealthBoard = isClusterHealthBoard();
const category = isCLusterHealthBoard
? 'Cluster Monitoring'
: 'Incident Management::Embedded metrics';
const action = isCLusterHealthBoard
? 'generate_link_to_cluster_metric_chart'
: 'generate_link_to_metrics_chart';
return { category, action, label: 'Chart link', property: chartLink };
};
/**
* Tracks snowplow event when user downloads CSV of cluster metric
* @param {String} chart title that will be sent as a property for the event
* @return {Object} config object for event tracking
*/
export const downloadCSVOptions = title => {
const isCLusterHealthBoard = isClusterHealthBoard();
const category = isCLusterHealthBoard
? 'Cluster Monitoring'
: 'Incident Management::Embedded metrics';
const action = isCLusterHealthBoard
? 'download_csv_of_cluster_metric_chart'
: 'download_csv_of_metrics_dashboard_chart';
return { category, action, label: 'Chart title', property: title };
};
/**
* Generate options for snowplow to track adding a new metric via the dashboard
* custom metric modal
* @return {Object} config object for event tracking
*/
export const getAddMetricTrackingOptions = () => ({
category: document.body.dataset.page,
action: 'click_button',
label: 'add_new_metric',
property: 'modal',
});
/**
* This function validates the graph data contains exactly 3 metrics plus
* value validations from graphDataValidatorForValues.
* @param {Object} isValues
* @param {Object} graphData the graph data response from a prometheus request
* @returns {boolean} true if the data is valid
*/
export const graphDataValidatorForAnomalyValues = graphData => {
const anomalySeriesCount = 3; // metric, upper, lower
return (
graphData.metrics &&
graphData.metrics.length === anomalySeriesCount &&
graphDataValidatorForValues(false, graphData)
);
};
/**
* Returns a time range from the current URL params
*
* @returns {Object|null} The time range defined by the
* current URL, reading from search query or `window.location.search`.
* Returns `null` if no parameters form a time range.
*/
export const timeRangeFromUrl = (search = window.location.search) => {
const params = queryToObject(search);
return timeRangeFromParams(params);
};
/**
* Returns a URL with no time range based on the current URL.
*
* @param {String} New URL
*/
export const removeTimeRangeParams = (url = window.location.href) =>
removeParams(timeRangeParamNames, url);
/**
* Returns a URL for the a different time range based on the
* current URL and a time range.
*
* @param {String} New URL
*/
export const timeRangeToUrl = (timeRange, url = window.location.href) => {
const toUrl = removeTimeRangeParams(url);
const params = timeRangeToParams(timeRange);
return mergeUrlParams(params, toUrl);
};
/**
* Get the metric value from first data point.
* Currently only used for bar charts
*
* @param {Array} values data points
* @returns {Number}
*/
const metricValueMapper = values => values[0]?.[1];
/**
* Get the metric name from metric object
* Currently only used for bar charts
* e.g. { handler: '/query' }
* { method: 'get' }
*
* @param {Object} metric metric object
* @returns {String}
*/
const metricNameMapper = metric => Object.values(metric)?.[0];
/**
* Parse metric object to extract metric value and name in
* [<metric-value>, <metric-name>] format.
* Currently only used for bar charts
*
* @param {Object} param0 metric object
* @returns {Array}
*/
const resultMapper = ({ metric, values = [] }) => [
metricValueMapper(values),
metricNameMapper(metric),
];
/**
* Bar charts graph data parser to massage data from
* backend to a format acceptable by bar charts component
* in GitLab UI
*
* e.g.
* {
* SLO: [
* [98, 'api'],
* [99, 'web'],
* [99, 'database']
* ]
* }
*
* @param {Array} data series information
* @returns {Object}
*/
export const barChartsDataParser = (data = []) =>
data?.reduce(
(acc, { result = [], label }) => ({
...acc,
[label]: result.map(resultMapper),
}),
{},
);
export default {};