mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-04 09:50:09 +00:00
Fixes incorrect probe charts displayed
This commit is contained in:
parent
dd031989d9
commit
e1a3b209d5
1 changed files with 200 additions and 195 deletions
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
local dirs = ntop.getDirs()
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
require "lua_utils"
|
||||
|
|
@ -6,227 +5,233 @@ require "lua_utils"
|
|||
local ts_rest_utils = {}
|
||||
|
||||
function ts_rest_utils.get_timeseries(http_context)
|
||||
local graph_common = require "graph_common"
|
||||
local graph_utils = require "graph_utils"
|
||||
local ts_utils = require("ts_utils")
|
||||
local ts_common = require("ts_common")
|
||||
local graph_common = require "graph_common"
|
||||
local graph_utils = require "graph_utils"
|
||||
local ts_utils = require("ts_utils")
|
||||
local ts_common = require("ts_common")
|
||||
|
||||
local ts_schema = http_context.ts_schema
|
||||
local tstart = http_context.epoch_begin
|
||||
local tend = http_context.epoch_end
|
||||
local compare_backward = http_context.ts_compare
|
||||
local tags = http_context.tags
|
||||
local extended_times = http_context.extended
|
||||
local ts_aggregation = http_context.ts_aggregation
|
||||
local no_fill = tonumber(http_context.no_fill)
|
||||
local ts_schema = http_context.ts_schema
|
||||
local tstart = http_context.epoch_begin
|
||||
local tend = http_context.epoch_end
|
||||
local compare_backward = http_context.ts_compare
|
||||
local tags = http_context.tags
|
||||
local extended_times = http_context.extended
|
||||
local ts_aggregation = http_context.ts_aggregation
|
||||
local no_fill = tonumber(http_context.no_fill)
|
||||
|
||||
tstart = tonumber(tstart) or (os.time() - 3600)
|
||||
tend = tonumber(tend) or os.time()
|
||||
if http_context.tskey then
|
||||
-- This can contain a MAC address for local broadcast domain hosts
|
||||
local tskey = http_context.tskey
|
||||
|
||||
-- Setting host_ip (check that the provided IP matches the provided
|
||||
-- mac address as safety check and to avoid security issues)
|
||||
if tags.host then
|
||||
local host = hostkey2hostinfo(tags.host)
|
||||
|
||||
if not isEmptyString(host["host"]) then
|
||||
local serialize_by_mac = ntop.getPref(string.format("ntopng.prefs.ifid_" .. tags.ifid .. ".serialize_local_broadcast_hosts_as_macs")) == "1"
|
||||
local host_info = interface.getHostInfo(host["host"], host["vlan"])
|
||||
-- local mac_info = split(tskey, "_")
|
||||
-- if (host_info) and (host_info.mac == mac_info[1]) then
|
||||
-- tags.host_ip = tags.host;
|
||||
if(host_info ~= nil) then
|
||||
local mac_info = split(tskey, "_")
|
||||
|
||||
if(host_info.name ~= nil) then
|
||||
-- Add the symbolic host name (if present)
|
||||
tags.label = host_info.name
|
||||
end
|
||||
|
||||
if(host_info.mac == mac_info[1]) then
|
||||
tags.host_ip = tags.host;
|
||||
end
|
||||
|
||||
if(host_info.mac) then
|
||||
tags.mac = host_info.mac;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tags.host = tskey
|
||||
end
|
||||
|
||||
local options = {
|
||||
max_num_points = tonumber(http_context.limit) or 60,
|
||||
initial_point = toboolean(http_context.initial_point),
|
||||
with_series = true,
|
||||
target_aggregation = ts_aggregation or "raw",
|
||||
}
|
||||
|
||||
if(no_fill == 1) then
|
||||
options.fill_value = 0/0 -- NaN
|
||||
end
|
||||
|
||||
if tags.ifid then
|
||||
interface.select(tags.ifid)
|
||||
end
|
||||
|
||||
if((ts_schema == "top:flow_check:duration")
|
||||
or (ts_schema == "top:elem_check:duration")
|
||||
or (ts_schema == "custom:flow_check:total_stats")
|
||||
or (ts_schema == "custom:elem_check:total_stats")) then
|
||||
-- NOTE: Temporary fix for top checks page
|
||||
tags.check = nil
|
||||
end
|
||||
|
||||
local function performQuery(tstart, tend, keep_total, additional_options)
|
||||
local res
|
||||
additional_options = additional_options or {}
|
||||
local options = table.merge(options, additional_options)
|
||||
|
||||
if starts(ts_schema, "top:") then
|
||||
local ts_schema = split(ts_schema, "top:")[2]
|
||||
|
||||
res = ts_utils.queryTopk(ts_schema, tags, tstart, tend, options)
|
||||
else
|
||||
res = ts_utils.query(ts_schema, tags, tstart, tend, options)
|
||||
tstart = tonumber(tstart) or (os.time() - 3600)
|
||||
tend = tonumber(tend) or os.time()
|
||||
if http_context.tskey then
|
||||
-- This can contain a MAC address for local broadcast domain hosts
|
||||
local tskey = http_context.tskey
|
||||
|
||||
if(not keep_total) and (res) and (res.additional_series) then
|
||||
-- no need for total serie in normal queries
|
||||
res.additional_series.total = nil
|
||||
end
|
||||
end
|
||||
-- Setting host_ip (check that the provided IP matches the provided
|
||||
-- mac address as safety check and to avoid security issues)
|
||||
if tags.host then
|
||||
local host = hostkey2hostinfo(tags.host)
|
||||
|
||||
return res
|
||||
end
|
||||
if not isEmptyString(host["host"]) then
|
||||
local serialize_by_mac = ntop.getPref(string.format(
|
||||
"ntopng.prefs.ifid_" .. tags.ifid .. ".serialize_local_broadcast_hosts_as_macs")) == "1"
|
||||
local host_info = interface.getHostInfo(host["host"], host["vlan"])
|
||||
-- local mac_info = split(tskey, "_")
|
||||
-- if (host_info) and (host_info.mac == mac_info[1]) then
|
||||
-- tags.host_ip = tags.host;
|
||||
if (host_info ~= nil) then
|
||||
local mac_info = split(tskey, "_")
|
||||
|
||||
local res
|
||||
if (host_info.name ~= nil) then
|
||||
-- Add the symbolic host name (if present)
|
||||
tags.label = host_info.name
|
||||
end
|
||||
|
||||
if(ntop.getPref("ntopng.prefs.ndpi_flows_rrd_creation") == "1") then
|
||||
if(ts_schema == "host:ndpi") then
|
||||
ts_schema = "custom:host_ndpi_and_flows"
|
||||
elseif(ts_schema == "iface:ndpi") then
|
||||
ts_schema = "custom:iface_ndpi_and_flows"
|
||||
end
|
||||
end
|
||||
if (host_info.mac == mac_info[1]) then
|
||||
tags.host_ip = tags.host;
|
||||
end
|
||||
|
||||
if starts(ts_schema, "custom:") and graph_utils.performCustomQuery then
|
||||
res = graph_utils.performCustomQuery(ts_schema, tags, tstart, tend, options)
|
||||
compare_backward = nil
|
||||
else
|
||||
-- if Mac address ts is requested, check if the serialize by mac is enabled and if no data is found, use the host timeseries.
|
||||
-- if (table.len(res) == 0) or (res.statistics) and (res.statistics.total == 0) then
|
||||
local serialize_by_mac = ntop.getPref(string.format("ntopng.prefs.ifid_" .. tags.ifid .. ".serialize_local_broadcast_hosts_as_macs")) == "1"
|
||||
local tmp = split(ts_schema, ":")
|
||||
|
||||
if (serialize_by_mac) and (tags.mac) then
|
||||
ts_schema = "host:" .. tmp[2]
|
||||
tags.host = tags.mac .. "_v4"
|
||||
end
|
||||
if (host_info.mac) then
|
||||
tags.mac = host_info.mac;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
res = performQuery(tstart, tend) or {}
|
||||
--end
|
||||
end
|
||||
if tskey ~= 0 then
|
||||
tags.host = tskey
|
||||
end
|
||||
end
|
||||
|
||||
if res == nil then
|
||||
res = {}
|
||||
local options = {
|
||||
max_num_points = tonumber(http_context.limit) or 60,
|
||||
initial_point = toboolean(http_context.initial_point),
|
||||
with_series = true,
|
||||
target_aggregation = ts_aggregation or "raw"
|
||||
}
|
||||
|
||||
if(ts_utils.getLastError() ~= nil) then
|
||||
res["tsLastError"] = ts_utils.getLastError()
|
||||
res["error"] = ts_utils.getLastErrorMessage()
|
||||
rest_utils.answer(rest_utils.consts.err.internal_error, res)
|
||||
else
|
||||
rest_utils.answer(rest_utils.consts.success.ok, res)
|
||||
end
|
||||
if (no_fill == 1) then
|
||||
options.fill_value = 0 / 0 -- NaN
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
if tags.ifid then
|
||||
interface.select(tags.ifid)
|
||||
end
|
||||
|
||||
-- Add metadata
|
||||
res.schema = ts_schema
|
||||
res.query = tags
|
||||
res.max_points = options.max_num_points
|
||||
if ((ts_schema == "top:flow_check:duration") or (ts_schema == "top:elem_check:duration") or
|
||||
(ts_schema == "custom:flow_check:total_stats") or (ts_schema == "custom:elem_check:total_stats")) then
|
||||
-- NOTE: Temporary fix for top checks page
|
||||
tags.check = nil
|
||||
end
|
||||
|
||||
if not isEmptyString(compare_backward) and compare_backward ~= "1Y" and (res.step ~= nil) then
|
||||
local backward_sec = graph_common.getZoomDuration(compare_backward)
|
||||
local tstart_cmp = res.start - backward_sec
|
||||
local tend_cmp = tstart_cmp + res.step * (res.count - 1)
|
||||
local function performQuery(tstart, tend, keep_total, additional_options)
|
||||
local res
|
||||
additional_options = additional_options or {}
|
||||
local options = table.merge(options, additional_options)
|
||||
|
||||
-- Try to use the same aggregation as the original query
|
||||
local res_cmp = performQuery(tstart_cmp, tend_cmp, true, {target_aggregation=res.source_aggregation}) or {}
|
||||
local total_cmp_serie = nil
|
||||
if starts(ts_schema, "top:") then
|
||||
local ts_schema = split(ts_schema, "top:")[2]
|
||||
|
||||
if res_cmp and res_cmp.additional_series and res_cmp.additional_series.total and (res_cmp.step) and res_cmp.step >= res.step then
|
||||
total_cmp_serie = res_cmp.additional_series.total
|
||||
res = ts_utils.queryTopk(ts_schema, tags, tstart, tend, options)
|
||||
else
|
||||
res = ts_utils.query(ts_schema, tags, tstart, tend, options)
|
||||
|
||||
if res_cmp.step > res.step then
|
||||
-- The steps may not still correspond if the past query overlaps a retention policy
|
||||
-- bound (it will have less points, but with an higher step), upscale to solve this
|
||||
total_cmp_serie = ts_common.upsampleSerie(total_cmp_serie, res.count)
|
||||
end
|
||||
end
|
||||
if (not keep_total) and (res) and (res.additional_series) then
|
||||
-- no need for total serie in normal queries
|
||||
res.additional_series.total = nil
|
||||
end
|
||||
end
|
||||
|
||||
if total_cmp_serie then
|
||||
res.additional_series = res.additional_series or {}
|
||||
res.additional_series[compare_backward.. " " ..i18n("details.ago")] = total_cmp_serie
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- TODO make a script parameter?
|
||||
local extend_labels = true
|
||||
local res
|
||||
|
||||
if extend_labels and graph_utils.extendLabels then
|
||||
graph_utils.extendLabels(res)
|
||||
end
|
||||
if (ntop.getPref("ntopng.prefs.ndpi_flows_rrd_creation") == "1") then
|
||||
if (ts_schema == "host:ndpi") then
|
||||
ts_schema = "custom:host_ndpi_and_flows"
|
||||
elseif (ts_schema == "iface:ndpi") then
|
||||
ts_schema = "custom:iface_ndpi_and_flows"
|
||||
end
|
||||
end
|
||||
|
||||
if (res.query) and (res.query.if_index) then
|
||||
local snmp_utils = require "snmp_utils"
|
||||
local snmp_cached_dev = require "snmp_cached_dev"
|
||||
local cached_device = snmp_cached_dev:create(tags.device)
|
||||
res.query.label = shortenString(snmp_utils.get_snmp_interface_label(cached_device["interfaces"][res.query.if_index]), 64)
|
||||
end
|
||||
if starts(ts_schema, "custom:") and graph_utils.performCustomQuery then
|
||||
res = graph_utils.performCustomQuery(ts_schema, tags, tstart, tend, options)
|
||||
compare_backward = nil
|
||||
else
|
||||
-- if Mac address ts is requested, check if the serialize by mac is enabled and if no data is found, use the host timeseries.
|
||||
-- if (table.len(res) == 0) or (res.statistics) and (res.statistics.total == 0) then
|
||||
local serialize_by_mac = ntop.getPref(string.format("ntopng.prefs.ifid_" .. tags.ifid ..
|
||||
".serialize_local_broadcast_hosts_as_macs")) == "1"
|
||||
local tmp = split(ts_schema, ":")
|
||||
|
||||
-- Add layout information
|
||||
local layout = graph_utils.get_timeseries_layout(ts_schema)
|
||||
local filtered_serie = {}
|
||||
if (serialize_by_mac) and (tags.mac) then
|
||||
ts_schema = "host:" .. tmp[2]
|
||||
tags.host = tags.mac .. "_v4"
|
||||
end
|
||||
|
||||
for _, serie in pairs(res.series or {}) do
|
||||
res = performQuery(tstart, tend) or {}
|
||||
-- end
|
||||
end
|
||||
|
||||
if not serie.type then
|
||||
if layout[serie.label] then
|
||||
serie.type = layout[serie.label]
|
||||
end
|
||||
end
|
||||
if res == nil then
|
||||
res = {}
|
||||
|
||||
local ts_tot_value = 0
|
||||
for _, ts_value in pairs(serie.data or {}) do
|
||||
ts_tot_value = ts_tot_value + tonumber(ts_value or 0)
|
||||
end
|
||||
if (ts_utils.getLastError() ~= nil) then
|
||||
res["tsLastError"] = ts_utils.getLastError()
|
||||
res["error"] = ts_utils.getLastErrorMessage()
|
||||
rest_utils.answer(rest_utils.consts.err.internal_error, res)
|
||||
else
|
||||
rest_utils.answer(rest_utils.consts.success.ok, res)
|
||||
end
|
||||
|
||||
if ts_tot_value > 0 then
|
||||
filtered_serie[#filtered_serie + 1] = serie
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
res.series = filtered_serie
|
||||
-- Add metadata
|
||||
res.schema = ts_schema
|
||||
res.query = tags
|
||||
res.max_points = options.max_num_points
|
||||
|
||||
if extended_times then
|
||||
if res.series and res.step then
|
||||
for k, serie in pairs(res.series) do
|
||||
serie.data = ts_common.serieWithTimestamp(serie.data, tstart, res.step)
|
||||
end
|
||||
end
|
||||
if res.additional_series and res.step then
|
||||
for k, serie in pairs(res.additional_series) do
|
||||
res.additional_series[k] = ts_common.serieWithTimestamp(serie, tstart, res.step)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
if not isEmptyString(compare_backward) and compare_backward ~= "1Y" and (res.step ~= nil) then
|
||||
local backward_sec = graph_common.getZoomDuration(compare_backward)
|
||||
local tstart_cmp = res.start - backward_sec
|
||||
local tend_cmp = tstart_cmp + res.step * (res.count - 1)
|
||||
|
||||
-- Try to use the same aggregation as the original query
|
||||
local res_cmp = performQuery(tstart_cmp, tend_cmp, true, {
|
||||
target_aggregation = res.source_aggregation
|
||||
}) or {}
|
||||
local total_cmp_serie = nil
|
||||
|
||||
if res_cmp and res_cmp.additional_series and res_cmp.additional_series.total and (res_cmp.step) and res_cmp.step >=
|
||||
res.step then
|
||||
total_cmp_serie = res_cmp.additional_series.total
|
||||
|
||||
if res_cmp.step > res.step then
|
||||
-- The steps may not still correspond if the past query overlaps a retention policy
|
||||
-- bound (it will have less points, but with an higher step), upscale to solve this
|
||||
total_cmp_serie = ts_common.upsampleSerie(total_cmp_serie, res.count)
|
||||
end
|
||||
end
|
||||
|
||||
if total_cmp_serie then
|
||||
res.additional_series = res.additional_series or {}
|
||||
res.additional_series[compare_backward .. " " .. i18n("details.ago")] = total_cmp_serie
|
||||
end
|
||||
end
|
||||
|
||||
-- TODO make a script parameter?
|
||||
local extend_labels = true
|
||||
|
||||
if extend_labels and graph_utils.extendLabels then
|
||||
graph_utils.extendLabels(res)
|
||||
end
|
||||
|
||||
if (res.query) and (res.query.if_index) then
|
||||
local snmp_utils = require "snmp_utils"
|
||||
local snmp_cached_dev = require "snmp_cached_dev"
|
||||
local cached_device = snmp_cached_dev:create(tags.device)
|
||||
res.query.label = shortenString(snmp_utils.get_snmp_interface_label(
|
||||
cached_device["interfaces"][res.query.if_index]), 64)
|
||||
end
|
||||
|
||||
-- Add layout information
|
||||
local layout = graph_utils.get_timeseries_layout(ts_schema)
|
||||
local filtered_serie = {}
|
||||
|
||||
for _, serie in pairs(res.series or {}) do
|
||||
|
||||
if not serie.type then
|
||||
if layout[serie.label] then
|
||||
serie.type = layout[serie.label]
|
||||
end
|
||||
end
|
||||
|
||||
local ts_tot_value = 0
|
||||
for _, ts_value in pairs(serie.data or {}) do
|
||||
ts_tot_value = ts_tot_value + tonumber(ts_value or 0)
|
||||
end
|
||||
|
||||
if ts_tot_value > 0 then
|
||||
filtered_serie[#filtered_serie + 1] = serie
|
||||
end
|
||||
end
|
||||
|
||||
res.series = filtered_serie
|
||||
|
||||
if extended_times then
|
||||
if res.series and res.step then
|
||||
for k, serie in pairs(res.series) do
|
||||
serie.data = ts_common.serieWithTimestamp(serie.data, tstart, res.step)
|
||||
end
|
||||
end
|
||||
if res.additional_series and res.step then
|
||||
for k, serie in pairs(res.additional_series) do
|
||||
res.additional_series[k] = ts_common.serieWithTimestamp(serie, tstart, res.step)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return res
|
||||
end -- end get_timeseries
|
||||
|
||||
return ts_rest_utils
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue