mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 23:49:33 +00:00
406 lines
16 KiB
JavaScript
406 lines
16 KiB
JavaScript
/**
|
|
(C) 2022 - ntop.org
|
|
*/
|
|
import { ntopng_utility, ntopng_url_manager } from "../services/context/ntopng_globals_services.js";
|
|
import metricsConsts from "../constants/metrics-consts.js"
|
|
import NtopUtils from "./ntop-utils.js";
|
|
|
|
const set_timeseries_groups_in_url = (timeseries_groups) => {
|
|
let params_timeseries_groups = [];
|
|
timeseries_groups.forEach((ts_group) => {
|
|
let param = get_ts_group_url_param(ts_group);
|
|
params_timeseries_groups.push(param);
|
|
});
|
|
let url_timeseries_groups = params_timeseries_groups.join(";;");
|
|
ntopng_url_manager.set_key_to_url("timeseries_groups", url_timeseries_groups);
|
|
};
|
|
|
|
function get_ts_group_url_param(ts_group) {
|
|
let timeseries = [];
|
|
ts_group.timeseries.forEach((ts) => {
|
|
timeseries.push(`${ts.id}=${ts.raw}:${ts.past}:${ts.avg}:${ts.perc_95}`);
|
|
});
|
|
let metric_schema_query = ts_group.metric.schema;
|
|
if (ts_group.metric.query != null) {
|
|
metric_schema_query = `${metric_schema_query}+${ts_group.metric.query}`;
|
|
}
|
|
let timeseries_param = timeseries.join("|");
|
|
let source_value_array_query = ts_group.source_array.map((source) => source.value).join("+");
|
|
let param = `${ts_group.source_type.id};${source_value_array_query};${metric_schema_query};${timeseries_param}`;
|
|
return param;
|
|
}
|
|
|
|
const get_timeseries_groups_from_url = async (http_prefix, url_timeseries_groups) => {
|
|
if (url_timeseries_groups == null) {
|
|
url_timeseries_groups = ntopng_url_manager.get_url_entry("timeseries_groups");
|
|
}
|
|
if (url_timeseries_groups == null || url_timeseries_groups == "") {
|
|
return null;
|
|
}
|
|
let groups = url_timeseries_groups.split(";;");
|
|
groups.map(async (g) => {
|
|
let ts_group = await get_url_param_from_ts_group(g);
|
|
return ts_group;
|
|
});
|
|
let timeseries_groups = Promise.all(groups.map(async (g) => {
|
|
let ts_group = await get_url_param_from_ts_group(g);
|
|
return ts_group;
|
|
}));
|
|
return timeseries_groups;
|
|
};
|
|
|
|
const get_ts_group = (source_type, source_array, metric, customized_ts) => {
|
|
let ts_config = {
|
|
raw: true,
|
|
past: true, /* By default enable the past serie */
|
|
avg: false,
|
|
perc_95: false,
|
|
}
|
|
|
|
if (customized_ts && customized_ts.raw != null) ts_config.raw = customized_ts.raw;
|
|
if (customized_ts && customized_ts.past != null) ts_config.past = customized_ts.past;
|
|
if (customized_ts && customized_ts.avg != null) ts_config.avg = customized_ts.avg;
|
|
if (customized_ts && customized_ts.perc_95 != null) ts_config.perc_95 = customized_ts.perc_95;
|
|
|
|
let id = get_ts_group_id(source_type, source_array, metric);
|
|
let timeseries = [];
|
|
for (let key in metric.timeseries) {
|
|
let ts = metric.timeseries[key];
|
|
ts_config.id = key;
|
|
ts_config.label = ts.label;
|
|
timeseries.push(ts_config);
|
|
}
|
|
return {
|
|
id, source_type, source_array, metric, timeseries,
|
|
};
|
|
};
|
|
|
|
const get_default_timeseries_groups = async (http_prefix, metric_ts_schema, metric_query) => {
|
|
let source_type = get_current_page_source_type();
|
|
let source_array = await get_default_source_array(http_prefix, source_type);
|
|
let metrics = await get_metrics(http_prefix, source_type, source_array);
|
|
let metric = get_default_metric(metrics, metric_ts_schema, metric_query);
|
|
let ts_group = get_ts_group(source_type, source_array, metric);
|
|
return [ts_group];
|
|
};
|
|
|
|
async function get_url_param_from_ts_group(ts_group_url_param) {
|
|
let g = ts_group_url_param;
|
|
let info = g.split(";");
|
|
let source_type_id = info[0];
|
|
let source_value_query = info[1];
|
|
let source_value_array = source_value_query.split("+");
|
|
|
|
let metric_schema_query = info[2];
|
|
let metric_schema_query_array = metric_schema_query.split("+");
|
|
if (metric_schema_query_array.length < 2) {
|
|
metric_schema_query_array.push(null);
|
|
}
|
|
|
|
let timeseries_url = info[3];
|
|
|
|
let source_type = get_source_type_from_id(source_type_id);
|
|
let source_array = await get_source_array_from_value_array(http_prefix, source_type, source_value_array);
|
|
let metric = await get_metric_from_schema(http_prefix, source_type, source_array, metric_schema_query_array[0], metric_schema_query_array[1]);
|
|
let timeseries = get_timeseries(timeseries_url, metric);
|
|
return {
|
|
id: get_ts_group_id(source_type, source_array, metric),
|
|
source_type,
|
|
source_array,
|
|
metric,
|
|
timeseries,
|
|
};
|
|
}
|
|
|
|
const get_ts_group_id = (source_type, source_array, metric, enable_source_def_value_dict, set_source_type_id_group) => {
|
|
let metric_id = "";
|
|
if (metric != null) {
|
|
metric_id = metric.schema;
|
|
if (metric.query != null) {
|
|
metric_id = `${metric_id} - ${metric.query}`;
|
|
}
|
|
}
|
|
let source_def_array = source_type.source_def_array;
|
|
let source_value_array = source_array.map((source, i) => {
|
|
let source_def_value = source_def_array[i].value;
|
|
if (enable_source_def_value_dict != null && !enable_source_def_value_dict[source_def_value]) { return null; }
|
|
return source.value;
|
|
}).filter((s) => s != null).join("_");
|
|
let source_type_id = source_type.id;
|
|
if (set_source_type_id_group && source_type.id_group != null) {
|
|
source_type_id = source_type.id_group;
|
|
}
|
|
return `${source_type_id} - ${source_value_array} - ${metric_id}`;
|
|
};
|
|
|
|
function get_timeseries(timeseries_url, metric) {
|
|
let ts_url_array = timeseries_url.split("|");
|
|
let r = /(.+)=(.+):(.+):(.+):(.+)/;
|
|
let timeseries = [];
|
|
ts_url_array.forEach((ts_url) => {
|
|
let values = r.exec(ts_url);
|
|
if (values.length > 0) {
|
|
let id = values[1];
|
|
let label = metric.timeseries[id].label;
|
|
let raw = JSON.parse(values[2]);
|
|
let past = JSON.parse(values[3]);
|
|
let avg = JSON.parse(values[4]);
|
|
let perc_95 = JSON.parse(values[5]);
|
|
timeseries.push({
|
|
id, label, raw, past, avg, perc_95,
|
|
});
|
|
}
|
|
});
|
|
return timeseries;
|
|
}
|
|
|
|
const ui_types = metricsConsts.ui_types;
|
|
|
|
// dictionary of functions to convert an element of source_url rest result to a source ({label, value })
|
|
const sources_url_el_to_source = metricsConsts.sources_url_el_to_source;
|
|
|
|
const sources_types = metricsConsts.sources_types;
|
|
const sources_types_tables = metricsConsts.sources_types_tables;
|
|
|
|
const get_source_type_from_id = (source_type_id) => {
|
|
return sources_types.find((st) => st.id == source_type_id);
|
|
};
|
|
|
|
const get_default_source_array = async (http_prefix, source_type) => {
|
|
let source_value_array = get_default_source_value_array(source_type);
|
|
let source_array = await get_source_array_from_value_array(http_prefix, source_type, source_value_array);
|
|
return source_array;
|
|
};
|
|
|
|
async function get_source_array_from_value_dict(http_prefix, source_type, source_value_dict) {
|
|
let source_value_array = source_type.source_def_array.map((source_def) => source_value_dict[source_def.value]);
|
|
let source_array = await get_source_array_from_value_array(http_prefix, source_type, source_value_array);
|
|
return source_array;
|
|
}
|
|
|
|
const get_source_array_from_value_array = async (http_prefix, source_type, source_value_array) => {
|
|
if (source_type == null) {
|
|
source_type = get_current_page_source_type();
|
|
}
|
|
let source_array = [];
|
|
let source;
|
|
for (let i = 0; i < source_value_array.length; i++) {
|
|
let source_value = source_value_array[i];
|
|
let source_def = source_type.source_def_array[i];
|
|
if (source_def.sources_url || source_def.sources_function) {
|
|
let sources = [];
|
|
sources = await get_sources(http_prefix, source_type.id, source_def, source_value_array);
|
|
source = sources.find((s) => s.value == source_value);
|
|
if (source == null) {
|
|
source = sources[0];
|
|
}
|
|
} else {
|
|
source = { label: source_value, value: source_value };
|
|
}
|
|
source_array.push(source);
|
|
}
|
|
return source_array;
|
|
};
|
|
|
|
let cache_sources = {};
|
|
|
|
function get_source_def_key(id, source_def, selected_source_value_array) {
|
|
let key = `${id}_${source_def.value}`;
|
|
if (!source_def.refresh_on_sources_change) {
|
|
return key;
|
|
}
|
|
const value_array = selected_source_value_array.join("_");
|
|
key = `${key}_${value_array}`;
|
|
return key;
|
|
}
|
|
|
|
const get_sources = async (http_prefix, id, source_def, selected_source_value_array) => {
|
|
let key = get_source_def_key(id, source_def, selected_source_value_array);
|
|
if (cache_sources[key] == null) {
|
|
if (source_def.sources_url) {
|
|
let url = `${http_prefix}/${source_def.sources_url}`;
|
|
cache_sources[key] = ntopng_utility.http_request(url);
|
|
} else if (source_def.sources_function) {
|
|
cache_sources[key] = source_def.sources_function(selected_source_value_array);
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
let sources = await cache_sources[key];
|
|
if (source_def.sources_url) {
|
|
let f_map_source_element = sources_url_el_to_source[source_def.value_map_sources_res];
|
|
if (f_map_source_element == null) {
|
|
f_map_source_element = sources_url_el_to_source[source_def.value];
|
|
}
|
|
if (f_map_source_element == null) {
|
|
throw `:Error: metrics-manager.js, missing sources_url_to_source ${source_def.value} key`;
|
|
}
|
|
sources = sources.map((s) => f_map_source_element(s));
|
|
}
|
|
return sources.sort(NtopUtils.sortAlphabetically);
|
|
};
|
|
|
|
function set_source_value_object_in_url(source_type, source_value_object) {
|
|
source_type.source_def_array.forEach((source_def) => {
|
|
let source_value = source_value_object[source_def.value];
|
|
if (source_value == null) { return; }
|
|
if (source_def.f_set_value_url != null) {
|
|
source_def.f_set_value_url();
|
|
} else if (source_def.value_url != null) {
|
|
ntopng_url_manager.set_key_to_url(source_def.value_url, source_value);
|
|
} else {
|
|
ntopng_url_manager.set_key_to_url(source_def.value, source_value);
|
|
}
|
|
});
|
|
}
|
|
|
|
const get_default_source_value_array = (source_type) => {
|
|
if (source_type == null) {
|
|
source_type = get_current_page_source_type();
|
|
}
|
|
let source_value_array = source_type.source_def_array.map((source_def) => {
|
|
if (source_def.f_get_value_url != null) {
|
|
return source_def.f_get_value_url();
|
|
}
|
|
let source_def_value = source_def.value_url;
|
|
if (source_def_value == null) {
|
|
source_def_value = source_def.value;
|
|
}
|
|
let source_value = ntopng_url_manager.get_url_entry(source_def_value);
|
|
return source_value;
|
|
});
|
|
return source_value_array;
|
|
};
|
|
|
|
function get_metrics_url(http_prefix, source_type, source_array, epoch) {
|
|
let params = source_type.source_def_array.map((source_def, i) => {
|
|
return `${source_def.value}=${source_array[i].value}`;
|
|
}).join("&");
|
|
let epoch_string = ``;
|
|
if (epoch != null) {
|
|
epoch_string = `epoch_end=${epoch.epoch_end}&epoch_begin=${epoch.epoch_begin}`
|
|
}
|
|
let url = `${http_prefix}/lua/rest/v2/get/timeseries/type/consts.lua?query=${source_type.query}&${params}&${epoch_string}`;
|
|
return url;
|
|
}
|
|
|
|
function get_metric_key(source_type, source_array) {
|
|
let source_array_key = source_array.map((source) => source.value).join("_");
|
|
let key = `${source_type.id}_${source_array_key}`;
|
|
return key;
|
|
}
|
|
|
|
let cache_metrics = {};
|
|
let last_metrics_time_interval = null;
|
|
const get_metrics = async (http_prefix, source_type, source_array, status) => {
|
|
let epoch_begin = status?.epoch_begin || ntopng_url_manager.get_url_entry("epoch_begin");
|
|
let epoch_end = status?.epoch_end || ntopng_url_manager.get_url_entry("epoch_end");
|
|
let current_last_metrics_time_interval = `${epoch_begin}_${epoch_end}`;
|
|
if (source_type == null) {
|
|
source_type = get_current_page_source_type();
|
|
}
|
|
if (source_array == null) {
|
|
source_array = await get_default_source_array(http_prefix, source_type);
|
|
}
|
|
// let url = `${http_prefix}/lua/rest/v2/get/timeseries/type/consts.lua?query=${source_type.value}`;
|
|
let url = get_metrics_url(http_prefix, source_type, source_array, { epoch_begin: epoch_begin, epoch_end: epoch_end });
|
|
let key = get_metric_key(source_type, source_array);
|
|
if (current_last_metrics_time_interval != last_metrics_time_interval) {
|
|
cache_metrics[key] = null;
|
|
last_metrics_time_interval = current_last_metrics_time_interval;
|
|
}
|
|
if (cache_metrics[key] == null) {
|
|
cache_metrics[key] = ntopng_utility.http_request(url);
|
|
}
|
|
let metrics = await cache_metrics[key];
|
|
if (metrics == null || metrics.length == 0) { return [{}]; }
|
|
if (metrics.some((m) => m.default_visible == true) == false) {
|
|
metrics[0].default_visible = true;
|
|
}
|
|
return ntopng_utility.clone(metrics);
|
|
};
|
|
|
|
const get_current_page_source_type = () => {
|
|
let pathname = window.location.pathname;
|
|
for (let i = 0; i < sources_types.length; i += 1) {
|
|
let regExp = new RegExp(sources_types[i].regex_page_url);
|
|
if (regExp.test(pathname) == true) {
|
|
return sources_types[i];
|
|
}
|
|
}
|
|
throw `source_type not found for ${pathname}`;
|
|
};
|
|
|
|
const get_metric_from_schema = async (http_prefix, source_type, source_array, metric_schema, metric_query, status) => {
|
|
let metrics = await get_metrics(http_prefix, source_type, source_array, status);
|
|
if (metric_schema === 'top:iface:ndpi') {
|
|
return metrics.find((m) => m.schema == metric_schema && m.query == metric_query) ||
|
|
metrics.find((m) => m.schema == 'top:iface:ndpi_full' && m.query == metric_query)
|
|
}
|
|
const metric = metrics.find((m) => m.schema == metric_schema && m.query == metric_query);
|
|
return metric
|
|
};
|
|
|
|
const get_metric_query_from_ts_query = (ts_query, source_type) => {
|
|
if (source_type == null) {
|
|
source_type = get_current_page_source_type();
|
|
}
|
|
let source_def_dict = {};
|
|
source_type.source_def_array.forEach((s_def) => source_def_dict[s_def.value] = true);
|
|
let metric_query = null
|
|
let ts_query_array = ts_query.split(",");
|
|
for (let i = 0; i < ts_query_array.length; i += 1) {
|
|
let ts_val_key = ts_query_array[i].split(":")[0];
|
|
if (source_def_dict[ts_val_key] == null) {
|
|
if (!metric_query) { metric_query = `${ts_query_array[i]}` }
|
|
else { metric_query = `${metric_query},${ts_query_array[i]}` }
|
|
}
|
|
}
|
|
return metric_query;
|
|
};
|
|
|
|
const get_default_metric = (metrics, metric_ts_schema, metric_query) => {
|
|
let default_metric;
|
|
if (metric_ts_schema != null) {
|
|
default_metric = metrics.find((m) => m.schema == metric_ts_schema && (metric_query == null || m.query == metric_query));
|
|
}
|
|
if (default_metric == null) {
|
|
default_metric = metrics.find((m) => m.default_visible == true);
|
|
}
|
|
if (default_metric != null) {
|
|
return default_metric;
|
|
}
|
|
return metrics[0];
|
|
};
|
|
|
|
const metricsManager = function () {
|
|
return {
|
|
set_timeseries_groups_in_url,
|
|
get_timeseries_groups_from_url,
|
|
get_default_timeseries_groups,
|
|
get_ts_group,
|
|
get_ts_group_id,
|
|
|
|
sources_types,
|
|
sources_types_tables,
|
|
get_source_type_from_id,
|
|
get_current_page_source_type,
|
|
|
|
get_sources,
|
|
get_default_source_array,
|
|
get_source_array_from_value_dict,
|
|
get_source_array_from_value_array,
|
|
get_default_source_value_array,
|
|
|
|
get_metrics,
|
|
get_metric_from_schema,
|
|
get_metric_query_from_ts_query,
|
|
get_default_metric,
|
|
|
|
set_source_value_object_in_url,
|
|
|
|
ui_types,
|
|
};
|
|
}();
|
|
|
|
export default metricsManager;
|