mirror of
https://github.com/ntop/ntopng.git
synced 2026-10-27 00:40:31 +00:00
294 lines
11 KiB
Lua
294 lines
11 KiB
Lua
--
|
|
-- (C) 2013-26 - ntop.org
|
|
--
|
|
|
|
local dirs = ntop.getDirs()
|
|
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
|
|
require "lua_utils"
|
|
local json = require("dkjson")
|
|
|
|
local interface_utils = {}
|
|
|
|
function interface_utils.get_pingable_interfaces()
|
|
local res = {}
|
|
|
|
local interfaces = ntop.getPingIfNames()
|
|
|
|
for id, ifname in pairs(interfaces) do
|
|
local custom_name = getHumanReadableInterfaceName(ifname)
|
|
|
|
if isEmptyString(custom_name) then
|
|
custom_name = nil
|
|
end
|
|
|
|
-- Note: returning in a format compatible with /lua/rest/v2/get/ntopng/interfaces.lua
|
|
res[#res + 1] = {
|
|
ifid = tonumber(id),
|
|
ifname = ifname,
|
|
name = custom_name or ifname,
|
|
is_packet_interface = true,
|
|
is_pcap_interface = false,
|
|
is_zmq_interface = false,
|
|
}
|
|
end
|
|
return res
|
|
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
local function override_stats(stats, overr_stats)
|
|
-- override stats with the values calculated from the latest user reset
|
|
for k, v in pairs(overr_stats or {}) do
|
|
stats[k] = v
|
|
end
|
|
return stats
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
-- Lightview mode has no backend support, merging stats from all interfaces here.
|
|
-- Used by if_stats.lua and rest/v2/get/interface/lightview/data.lua
|
|
-- Returns ifstats and info with:
|
|
-- ifaces: list of interfaces
|
|
-- probes_stats: nProbe instances
|
|
-- drops: dropped flows (collector) or packets
|
|
-- update_freq: min stats update frequency (sec) of interfaces
|
|
function interface_utils.getLightViewStats(ifstats)
|
|
local prev_ifid = interface.getId()
|
|
local info = {
|
|
ifaces = {},
|
|
probes_stats = {},
|
|
drops = 0,
|
|
update_freq = nil
|
|
}
|
|
local zmq_stats = {}
|
|
local exporters_stats = {}
|
|
local agg_stats = {
|
|
bytes = 0,
|
|
packets = 0,
|
|
drops = 0,
|
|
num_deduplicated_flows = 0
|
|
}
|
|
local agg_discarded_probing = nil
|
|
local agg_db_stats = {
|
|
flows = 0,
|
|
dropped_flows = 0
|
|
}
|
|
local agg_export_stats = {}
|
|
local agg_anomalies = {
|
|
num_local_hosts_anomalies = 0,
|
|
num_remote_hosts_anomalies = 0,
|
|
tot_num_anomalies = {
|
|
local_hosts = 0,
|
|
remote_hosts = 0
|
|
}
|
|
}
|
|
local agg_traffic = {
|
|
tx = 0,
|
|
rx = 0,
|
|
tx_pkts = 0,
|
|
rx_pkts = 0
|
|
}
|
|
local has_traffic_directions = false
|
|
local agg_alerts = {
|
|
engaged = 0,
|
|
dropped = 0
|
|
}
|
|
local agg_tcp = {
|
|
retransmissions = 0,
|
|
out_of_order = 0,
|
|
lost = 0
|
|
}
|
|
local agg_eth = {
|
|
ingress = { bytes = 0, packets = 0 },
|
|
egress = { bytes = 0, packets = 0 }
|
|
}
|
|
local agg_remote = {
|
|
bps = 0,
|
|
pps = 0
|
|
}
|
|
local agg_zmq_counters = {
|
|
["zmq.num_flow_exports"] = 0,
|
|
["zmq.drops.export_queue_full"] = 0,
|
|
["zmq.drops.flow_collection_drops"] = 0,
|
|
["zmq.drops.flow_collection_udp_socket_drops"] = 0
|
|
}
|
|
local exporters_drops = 0
|
|
local packet_drops = 0
|
|
|
|
for interface_name, _ in pairsByKeys(interface.getIfNames() or {}) do
|
|
interface.select(interface_name)
|
|
|
|
local tmp = interface.getStats()
|
|
local is_collector = (tmp.zmqRecvStats ~= nil and table.len(tmp.zmqRecvStats) > 0)
|
|
|
|
info.ifaces[#info.ifaces + 1] = {
|
|
id = interface.getId(),
|
|
name = getHumanReadableInterfaceName(interface_name)
|
|
}
|
|
|
|
local freq = interface.getStatsUpdateFreq(tmp.id)
|
|
if freq and (not info.update_freq or freq < info.update_freq) then
|
|
info.update_freq = freq
|
|
end
|
|
|
|
if tmp.stats and tmp.stats_since_reset then
|
|
tmp.stats = override_stats(tmp.stats, tmp.stats_since_reset)
|
|
end
|
|
if tmp.zmqRecvStats and tmp.zmqRecvStats_since_reset then
|
|
tmp.zmqRecvStats = override_stats(tmp.zmqRecvStats, tmp.zmqRecvStats_since_reset)
|
|
end
|
|
|
|
for k, v in pairs(tmp.probes or {}) do
|
|
info.probes_stats[k] = v
|
|
end
|
|
for k, v in pairs(tmp.exporters or {}) do
|
|
if not exporters_stats[k] then
|
|
exporters_stats[k] = {}
|
|
end
|
|
for key_stat, value_stat in pairs(v) do
|
|
exporters_stats[k][key_stat] = value_stat + (exporters_stats[k][key_stat] or 0)
|
|
end
|
|
exporters_drops = exporters_drops + (v["num_drops"] or 0)
|
|
end
|
|
for k, v in pairs(tmp.zmqRecvStats or {}) do
|
|
zmq_stats[k] = (zmq_stats[k] or 0) + v
|
|
end
|
|
|
|
if tmp.stats then
|
|
agg_stats.bytes = agg_stats.bytes + (tmp.stats.bytes or 0)
|
|
agg_stats.packets = agg_stats.packets + (tmp.stats.packets or 0)
|
|
agg_stats.drops = agg_stats.drops + (tmp.stats.drops or 0)
|
|
agg_stats.num_deduplicated_flows = agg_stats.num_deduplicated_flows + (tmp.stats.num_deduplicated_flows or 0)
|
|
|
|
if not is_collector then
|
|
packet_drops = packet_drops + (tmp.stats.drops or 0)
|
|
end
|
|
|
|
if tmp.stats.discarded_probing_packets then
|
|
agg_discarded_probing = agg_discarded_probing or { packets = 0, bytes = 0 }
|
|
agg_discarded_probing.packets = agg_discarded_probing.packets + (tmp.stats.discarded_probing_packets or 0)
|
|
agg_discarded_probing.bytes = agg_discarded_probing.bytes + (tmp.stats.discarded_probing_bytes or 0)
|
|
end
|
|
end
|
|
|
|
if tmp.dbStats then
|
|
agg_db_stats.flows = agg_db_stats.flows + (tmp.dbStats.flows or 0)
|
|
agg_db_stats.dropped_flows = agg_db_stats.dropped_flows + (tmp.dbStats.dropped_flows or 0)
|
|
end
|
|
|
|
for _, db_type in ipairs({ "db", "es", "kafka", "syslog" }) do
|
|
local s = tmp.stats_since_reset and tmp.stats_since_reset[db_type]
|
|
if s then
|
|
agg_export_stats[db_type] = agg_export_stats[db_type] or {
|
|
flow_export_count = 0,
|
|
flow_export_rate = 0,
|
|
flow_export_drops = 0
|
|
}
|
|
agg_export_stats[db_type].flow_export_count = agg_export_stats[db_type].flow_export_count + (s.flow_export_count or 0)
|
|
agg_export_stats[db_type].flow_export_rate = agg_export_stats[db_type].flow_export_rate + (s.flow_export_rate or 0)
|
|
agg_export_stats[db_type].flow_export_drops = agg_export_stats[db_type].flow_export_drops + (s.flow_export_drops or 0)
|
|
end
|
|
end
|
|
|
|
if tmp.anomalies then
|
|
agg_anomalies.num_local_hosts_anomalies = agg_anomalies.num_local_hosts_anomalies + (tmp.anomalies.num_local_hosts_anomalies or 0)
|
|
agg_anomalies.num_remote_hosts_anomalies = agg_anomalies.num_remote_hosts_anomalies + (tmp.anomalies.num_remote_hosts_anomalies or 0)
|
|
local an = tmp.anomalies.tot_num_anomalies or {}
|
|
agg_anomalies.tot_num_anomalies.local_hosts = agg_anomalies.tot_num_anomalies.local_hosts + (an.local_hosts or 0)
|
|
agg_anomalies.tot_num_anomalies.remote_hosts = agg_anomalies.tot_num_anomalies.remote_hosts + (an.remote_hosts or 0)
|
|
end
|
|
|
|
if tmp.has_traffic_directions then
|
|
has_traffic_directions = true
|
|
agg_traffic.tx = agg_traffic.tx + (tmp.traffic_sent_since_reset or 0)
|
|
agg_traffic.rx = agg_traffic.rx + (tmp.traffic_rcvd_since_reset or 0)
|
|
agg_traffic.tx_pkts = agg_traffic.tx_pkts + (tmp.packets_sent_since_reset or 0)
|
|
agg_traffic.rx_pkts = agg_traffic.rx_pkts + (tmp.packets_rcvd_since_reset or 0)
|
|
end
|
|
|
|
agg_alerts.engaged = agg_alerts.engaged + (tmp.num_alerts_engaged or 0)
|
|
agg_alerts.dropped = agg_alerts.dropped + (tmp.num_dropped_alerts or 0)
|
|
|
|
if tmp.tcpPacketStats then
|
|
agg_tcp.retransmissions = agg_tcp.retransmissions + (tmp.tcpPacketStats.retransmissions or 0)
|
|
agg_tcp.out_of_order = agg_tcp.out_of_order + (tmp.tcpPacketStats.out_of_order or 0)
|
|
agg_tcp.lost = agg_tcp.lost + (tmp.tcpPacketStats.lost or 0)
|
|
end
|
|
|
|
if tmp.eth then
|
|
for _, dir in ipairs({ "ingress", "egress" }) do
|
|
if tmp.eth[dir] then
|
|
agg_eth[dir].bytes = agg_eth[dir].bytes + (tmp.eth[dir].bytes or 0)
|
|
agg_eth[dir].packets = agg_eth[dir].packets + (tmp.eth[dir].packets or 0)
|
|
end
|
|
end
|
|
end
|
|
|
|
agg_remote.bps = agg_remote.bps + (tonumber(tmp.remote_bps) or 0)
|
|
agg_remote.pps = agg_remote.pps + (tonumber(tmp.remote_pps) or 0)
|
|
|
|
for k, _ in pairs(agg_zmq_counters) do
|
|
agg_zmq_counters[k] = agg_zmq_counters[k] + (tonumber(tmp[k]) or 0)
|
|
end
|
|
end
|
|
|
|
interface.select(tostring(prev_ifid))
|
|
|
|
ifstats.zmqRecvStats = zmq_stats
|
|
ifstats.exporters = exporters_stats
|
|
ifstats.probes = info.probes_stats
|
|
ifstats.stats.bytes = agg_stats.bytes
|
|
ifstats.stats.packets = agg_stats.packets
|
|
ifstats.stats.drops = agg_stats.drops
|
|
ifstats.stats.num_deduplicated_flows = agg_stats.num_deduplicated_flows
|
|
ifstats.stats_since_reset.drops = agg_stats.drops
|
|
|
|
ifstats.stats.discarded_probing_packets = agg_discarded_probing and agg_discarded_probing.packets or nil
|
|
ifstats.stats.discarded_probing_bytes = agg_discarded_probing and agg_discarded_probing.bytes or nil
|
|
|
|
if agg_db_stats.flows > 0 or agg_db_stats.dropped_flows > 0 then
|
|
ifstats.dbStats = agg_db_stats
|
|
end
|
|
for db_type, s in pairs(agg_export_stats) do
|
|
ifstats.stats_since_reset[db_type] = s
|
|
end
|
|
|
|
ifstats.anomalies = agg_anomalies
|
|
ifstats.has_traffic_directions = has_traffic_directions
|
|
ifstats.traffic_sent_since_reset = agg_traffic.tx
|
|
ifstats.traffic_rcvd_since_reset = agg_traffic.rx
|
|
ifstats.packets_sent_since_reset = agg_traffic.tx_pkts
|
|
ifstats.packets_rcvd_since_reset = agg_traffic.rx_pkts
|
|
ifstats.num_alerts_engaged = agg_alerts.engaged
|
|
ifstats.num_dropped_alerts = agg_alerts.dropped
|
|
ifstats.tcpPacketStats = agg_tcp
|
|
ifstats.eth = ifstats.eth or {}
|
|
ifstats.eth.ingress = ifstats.eth.ingress or {}
|
|
ifstats.eth.egress = ifstats.eth.egress or {}
|
|
ifstats.eth.ingress.bytes = agg_eth.ingress.bytes
|
|
ifstats.eth.ingress.packets = agg_eth.ingress.packets
|
|
ifstats.eth.egress.bytes = agg_eth.egress.bytes
|
|
ifstats.eth.egress.packets = agg_eth.egress.packets
|
|
ifstats.remote_bps = agg_remote.bps
|
|
ifstats.remote_pps = agg_remote.pps
|
|
for k, v in pairs(agg_zmq_counters) do
|
|
ifstats[k] = v
|
|
end
|
|
|
|
-- flows when collecting, packets otherwise
|
|
if table.len(zmq_stats) > 0 then
|
|
info.drops = exporters_drops
|
|
else
|
|
info.drops = packet_drops
|
|
end
|
|
|
|
return ifstats, info
|
|
end
|
|
|
|
-- ##############################################
|
|
|
|
return interface_utils
|