mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 23:49:33 +00:00
Add sankey with live Top Flow Talkers to dashboard. Add REST endpoint for Top Flow Talkers.
This commit is contained in:
parent
aabfe91e75
commit
b280416afa
2 changed files with 308 additions and 0 deletions
296
scripts/lua/rest/v2/get/flow/graph.lua
Normal file
296
scripts/lua/rest/v2/get/flow/graph.lua
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
--
|
||||
-- (C) 2013-23 - ntop.org
|
||||
--
|
||||
|
||||
local dirs = ntop.getDirs()
|
||||
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
||||
|
||||
require "flow_utils"
|
||||
require "lua_utils"
|
||||
local rest_utils = require("rest_utils")
|
||||
|
||||
--
|
||||
-- Return graph (sankey) data for active flows
|
||||
-- Example: curl -u admin:admin -H "Content-Type: application/json" -d '{"ifid": "1"}' http://localhost:3000/lua/rest/v2/get/flow/graph.lua
|
||||
--
|
||||
|
||||
local flows_filter = getFlowsFilter()
|
||||
local rc = rest_utils.consts.success.ok
|
||||
|
||||
local ifid = _GET["ifid"]
|
||||
local tracked_host = _GET["host"]
|
||||
local sankey_version = _GET["sankey_version"]
|
||||
|
||||
if isEmptyString(ifid) then
|
||||
rc = rest_utils.consts.err.invalid_interface
|
||||
rest_utils.answer(rc)
|
||||
return
|
||||
end
|
||||
|
||||
interface.select(ifid)
|
||||
|
||||
local max_num_peers = 10
|
||||
local max_num_links = 32
|
||||
local peers = getTopFlowPeers(tracked_host, max_num_peers, true --[[ high details for cli2srv.last/srv2cli.last fields ]])
|
||||
local is_pcap_dump = interface.isPcapDumpInterface()
|
||||
local debug = false
|
||||
|
||||
-- 1. compute total traffic
|
||||
local total_traffic = 0
|
||||
|
||||
for _, values in ipairs(peers) do
|
||||
local key
|
||||
local bytes
|
||||
if(values["cli.ip"] == tracked_host) then
|
||||
key = hostinfo2hostkey(values, "srv")
|
||||
else
|
||||
key = hostinfo2hostkey(values, "cli")
|
||||
end
|
||||
|
||||
if is_pcap_dump then
|
||||
bytes = values["bytes"]
|
||||
else
|
||||
bytes = values["bytes.last"]
|
||||
end
|
||||
|
||||
total_traffic = total_traffic + bytes
|
||||
if(debug) then io.write("->"..key.."\t[".. (values["bytes.last"]) .."][".. values["duration"].."]" .. "\n") end
|
||||
end
|
||||
|
||||
if(debug) then io.write("\n") end
|
||||
|
||||
-- 2. compute flow threshold under which we do not add any relation
|
||||
local threshold
|
||||
if(tracked_host == nil) then
|
||||
threshold = (total_traffic * 3) / 100
|
||||
else
|
||||
threshold = 1
|
||||
end
|
||||
|
||||
if(debug) then io.write("\nThreshold: "..threshold.."\n") end
|
||||
|
||||
-- map host -> incremental number
|
||||
|
||||
local hosts = {}
|
||||
local num = 0
|
||||
|
||||
local nodes = {}
|
||||
|
||||
-- fills hosts table with available hosts
|
||||
while(num == 0) do
|
||||
for _, values in ipairs(peers) do
|
||||
local key
|
||||
if(values["cli.ip"] == tracked_host) then
|
||||
key = hostinfo2hostkey(values, "srv")
|
||||
else
|
||||
key = hostinfo2hostkey(values, "cli")
|
||||
end
|
||||
|
||||
local bytes
|
||||
if(values["bytes.last"] == 0 and values.duration < 3) or is_pcap_dump then
|
||||
bytes = values["bytes"]
|
||||
else
|
||||
bytes = values["bytes.last"]
|
||||
end
|
||||
|
||||
if(bytes > threshold) then
|
||||
if(debug) then io.write("==>" .. key .. "\t[T:" .. tracked_host .. "][" .. values["duration"] .. "][" .. bytes .. "]\n") end
|
||||
if((debug) and (findString(key, tracked_host) ~= nil))then io.write("findString(key, tracked_host)==>"..findString(key, tracked_host)) end
|
||||
if((debug) and (findString(values["cli.ip"], tracked_host) ~= nil)) then io.write("findString(values[cli.ip], tracked_host)==>"..findString(values["cli.ip"], tracked_host)) end
|
||||
if((debug) and (findString(values["srv.ip"], tracked_host) ~= nil)) then io.write("findString(values[srv.ip], tracked_host)==>"..findString(values["srv.ip"], tracked_host)) end
|
||||
|
||||
local k = {hostinfo2hostkey(values, "cli"), hostinfo2hostkey(values, "srv")} --string.split(key, " ")
|
||||
|
||||
-- Note some checks are redundant here, they are already performed in getFlowPeers
|
||||
if((tracked_host == nil)
|
||||
or findString(k[1], tracked_host)
|
||||
or findString(k[2], tracked_host)
|
||||
or findString(values["cli.ip"], tracked_host)
|
||||
or findString(values["srv.ip"], tracked_host)) then
|
||||
|
||||
-- for each cli, srv
|
||||
for k, word in pairs(k) do
|
||||
if(hosts[word] == nil) then
|
||||
hosts[word] = num
|
||||
|
||||
host_info = hostkey2hostinfo(word)
|
||||
|
||||
-- 3. add node
|
||||
local hinfo = hostkey2hostinfo(word)
|
||||
name = hostinfo2label(hinfo)
|
||||
|
||||
nodes[#nodes + 1] = {
|
||||
-- sankey_version == 3
|
||||
node_id = #nodes,
|
||||
label = name,
|
||||
link = ntop.getHttpPrefix() .. "/lua/host_details.lua?" .. hostinfo2url(host_info),
|
||||
|
||||
-- old version
|
||||
name = name,
|
||||
host = host_info["host"],
|
||||
vlan = host_info["vlan"]
|
||||
}
|
||||
|
||||
num = num + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if(num == 0) then
|
||||
-- Lower the threshold to hope finding hosts
|
||||
threshold = threshold / 2
|
||||
end
|
||||
|
||||
if(threshold <= 1) then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
top_host = nil
|
||||
top_value = 0
|
||||
|
||||
if ((num == 0) and (tracked_host == nil)) then
|
||||
-- 2.1 It looks like in this network there are many flows with no clear predominant traffic
|
||||
-- Then we take the host with most traffic and add flows belonging to it
|
||||
|
||||
hosts_stats = interface.getHostsInfo(true, "column_traffic", max_num_peers)
|
||||
hosts_stats = hosts_stats["hosts"]
|
||||
for key, value in pairs(hosts_stats) do
|
||||
value = hosts_stats[key]["traffic"]
|
||||
if((value ~= nil) and (value > top_value)) then
|
||||
top_host = key
|
||||
top_value = value
|
||||
end -- if
|
||||
end -- for
|
||||
|
||||
if(top_host ~= nil) then
|
||||
-- We now have have to find this host and some peers
|
||||
hosts[top_host] = 0
|
||||
|
||||
host_info = hostkey2hostinfo(top_host)
|
||||
|
||||
nodes[#nodes + 1] = {
|
||||
-- sankey_version == 3
|
||||
node_id = #nodes,
|
||||
label = top_host,
|
||||
link = "#",
|
||||
|
||||
-- old version
|
||||
name = top_host,
|
||||
host = host_info["host"],
|
||||
vlan = host_info["vlan"]
|
||||
}
|
||||
|
||||
num = num + 1
|
||||
|
||||
for _, values in ipairs(peers) do
|
||||
local key
|
||||
if(values["cli.ip"] == tracked_host) then
|
||||
key = hostinfo2hostkey(values, "srv")
|
||||
else
|
||||
key = hostinfo2hostkey(values, "cli")
|
||||
end
|
||||
|
||||
if(findString(key, ip) or findString(values["client"], ip) or findString(values["server"], ip)) then
|
||||
for key,word in pairs(split(key, " ")) do
|
||||
if(hosts[word] == nil) then
|
||||
hosts[word] = num
|
||||
|
||||
host_info = hostkey2hostinfo(word)
|
||||
|
||||
-- 3. add host
|
||||
nodes[#nodes + 1] = {
|
||||
-- sankey_version == 3
|
||||
node_id = #nodes,
|
||||
label = word,
|
||||
link = "#",
|
||||
|
||||
-- old version
|
||||
name = word,
|
||||
host = host_info["host"],
|
||||
vlan = host_info["vlan"]
|
||||
}
|
||||
|
||||
num = num + 1
|
||||
end --if
|
||||
end -- for
|
||||
end -- if
|
||||
end -- for
|
||||
end -- if
|
||||
end -- if
|
||||
|
||||
-- 4. compute links
|
||||
|
||||
local links = {}
|
||||
num = 0
|
||||
|
||||
-- Avoid to have a link A->B, and B->A
|
||||
local reverse_nodes = {}
|
||||
for _, values in ipairs(peers) do
|
||||
local key = {hostinfo2hostkey(values, "cli"), hostinfo2hostkey(values, "srv")} --string.split(key, " ")
|
||||
local val
|
||||
if is_pcap_dump then
|
||||
val = values["bytes"]
|
||||
else
|
||||
val = values["bytes.last"]
|
||||
end
|
||||
|
||||
if(((val == 0) or (val > threshold)) or ((top_host ~= nil) and (findString(table.concat(key, " "), top_host) ~= nil)) and (num < max_num_links)) then
|
||||
e = {}
|
||||
id = 0
|
||||
for k, word in pairs(key) do
|
||||
e[id] = hosts[word]
|
||||
id = id + 1
|
||||
end
|
||||
|
||||
if((e[0] ~= nil) and (e[1] ~= nil) and (e[0] ~= e[1]) and (reverse_nodes[e[0]..":"..e[1]] == nil)) then
|
||||
|
||||
reverse_nodes[e[1]..":"..e[0]] = 1
|
||||
|
||||
if is_pcap_dump then
|
||||
sentv = values["cli2srv.last"]
|
||||
recvv = values["srv2cli.last"]
|
||||
else
|
||||
sentv = values["cli2srv.bytes"]
|
||||
recvv = values["srv2cli.bytes"]
|
||||
end
|
||||
|
||||
if(val == 0) then
|
||||
val = 1
|
||||
end
|
||||
|
||||
links[#links+1] = {
|
||||
-- sankey_version == 3
|
||||
source_node_id = tostring(e[0]),
|
||||
target_node_id = tostring(e[1]),
|
||||
label = "",
|
||||
optional_info = {
|
||||
link_color = "",
|
||||
link = "#"
|
||||
},
|
||||
|
||||
-- common
|
||||
value = val,
|
||||
|
||||
-- old version
|
||||
source = e[0],
|
||||
target = e[1],
|
||||
sent = sentv,
|
||||
rcvd = recvv
|
||||
}
|
||||
|
||||
num = num + 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local res = {
|
||||
nodes = nodes,
|
||||
links = links,
|
||||
max_entries_reached = true
|
||||
}
|
||||
|
||||
rest_utils.answer(rc, res)
|
||||
Loading…
Add table
Add a link
Reference in a new issue