mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-29 23:49:33 +00:00
159 lines
5.4 KiB
Lua
159 lines
5.4 KiB
Lua
--
|
|
-- (C) 2013-16 - ntop.org
|
|
--
|
|
|
|
dirs = ntop.getDirs()
|
|
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
|
|
|
|
require "lua_utils"
|
|
local json = require('dkjson')
|
|
|
|
local min_align = function(secs) return secs - (secs % 60) end
|
|
|
|
local stats_type = _GET["stats_type"]
|
|
local period_mins = 60 -- TODO: make it configurable
|
|
local now = os.time()
|
|
local period_begin = min_align(now - period_mins * 60)
|
|
|
|
sendHTTPHeader('text/html; charset=iso-8859-1')
|
|
|
|
interface.select(ifname)
|
|
|
|
|
|
local res = {}
|
|
local aggr = {}
|
|
|
|
local selection
|
|
local aggregation
|
|
local labeller
|
|
if stats_type == "severity_pie" or stats_type == "type_pie" or stats_type == "count_sparkline" or stats_type == "top_hosts" then
|
|
if stats_type == "severity_pie" then
|
|
selection = "alert_severity as label, count(*) as value"
|
|
aggregation = "where alert_tstamp >= ".. period_begin .." group by label"
|
|
labeller = alertSeverityLabel
|
|
elseif stats_type == "type_pie" then
|
|
selection = "alert_type as label, count(*) as value"
|
|
aggregation = "where alert_tstamp >= ".. period_begin .." group by label"
|
|
labeller = alertTypeLabel
|
|
elseif stats_type == "count_sparkline" then
|
|
selection = "(alert_tstamp - alert_tstamp % 60) as label, count(*) as value"
|
|
aggregation = "where alert_tstamp >= ".. period_begin .." group by label"
|
|
labeller = nil
|
|
elseif stats_type == "top_hosts" then
|
|
selection = "alert_entity_val as label, count(*) as value"
|
|
aggregation = "where alert_entity = "..alertEntity("host")
|
|
aggregation = aggregation.." and alert_tstamp >= ".. period_begin
|
|
aggregation = aggregation.." group by label order by value desc limit 5"
|
|
labeller = nil
|
|
end
|
|
for _, engaged in pairs({true, false}) do
|
|
local r = interface.selectAlertsRaw(engaged, selection, aggregation)
|
|
if r == nil then r = {} end
|
|
-- must aggregate again to sum counters between engaged and closed alerts
|
|
for k, v in ipairs(r) do
|
|
|
|
if v["label"] ~= nil and labeller ~= nil then
|
|
v["label"] = labeller(v["label"], true)
|
|
end
|
|
|
|
if aggr[v["label"]] ~= nil then
|
|
aggr[v["label"]] = aggr[v["label"]] + v["value"]
|
|
else
|
|
aggr[v["label"]] = v["value"]
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
elseif stats_type == "duration_pie" then
|
|
|
|
local binner = function(value)
|
|
value = tonumber(value)
|
|
if value == nil then return nil end
|
|
local bin
|
|
if value < 60 then bin = "[0,1)"
|
|
elseif value < 60 * 5 then bin = "[1,5)"
|
|
elseif value < 60 * 10 then bin = "[5,10)"
|
|
else bin = "10+" end
|
|
-- local log_base = 2
|
|
-- local bin = math.floor(math.log(value) / math.log(log_base))
|
|
-- bin = tostring(log_base^bin).." s <= d < "..tostring(log_base^(bin+1)).." s"
|
|
return bin.." min"
|
|
end
|
|
|
|
-- engaged
|
|
-- the duration is the current instant minus the alert timestamp
|
|
selection = "(strftime('%s','now') - alert_tstamp) as label, count(*) as value"
|
|
aggregation = "where alert_tstamp >= ".. period_begin .. " group by label"
|
|
local r_engaged = interface.selectAlertsRaw(true, selection, aggregation)
|
|
if r_engaged == nil then r_engaged = {} end
|
|
|
|
-- not engaged
|
|
-- the duration is the difference between the end and the start time
|
|
selection = "(alert_tstamp_end - alert_tstamp) as label, count(*) as value"
|
|
-- we don't take into account 'instant' alerts
|
|
aggregation = "where alert_tstamp >= ".. period_begin .. " and alert_tstamp_end is not null group by label"
|
|
local r_closed = interface.selectAlertsRaw(false, selection, aggregation)
|
|
if r_closed == nil then r_closed = {} end
|
|
|
|
-- let's put things together
|
|
for _, r in pairs({r_engaged, r_closed}) do
|
|
for k, v in ipairs(r) do
|
|
if v["label"] ~= nil then
|
|
v["label"] = binner(v["label"])
|
|
end
|
|
if aggr[v["label"]] ~= nil then
|
|
aggr[v["label"]] = aggr[v["label"]] + v["value"]
|
|
else
|
|
aggr[v["label"]] = v["value"]
|
|
end
|
|
end
|
|
end
|
|
|
|
elseif stats_type == "counts_pie" then
|
|
|
|
local num_engaged = interface.getNumAlerts(true, now - period_mins * 60)
|
|
local num_closed = interface.getNumAlerts(false, now - period_mins * 60)
|
|
if num_engaged > 0 then aggr["Engaged"] = num_engaged end
|
|
if num_closed > 0 then aggr["Closed"] = num_closed end
|
|
|
|
elseif stats_type == "counts_plain" then
|
|
for _, range in pairs({{"count-last-minute", 60}, {"count-last-hour", 3600},
|
|
{"count-last-day", 86400}, {"count-last-period", period_mins * 60}}) do
|
|
local num_engaged = interface.getNumAlerts(true, now - range[2])
|
|
local num_closed = interface.getNumAlerts(false, now - range[2])
|
|
aggr[range[1]] = num_engaged + num_closed
|
|
end
|
|
end
|
|
|
|
|
|
-- post-processing before last aggregation
|
|
if stats_type == "count_sparkline" then
|
|
local time_now = min_align(now)
|
|
local time_range_min = min_align(now - period_mins * 60)
|
|
-- add padding to the table
|
|
for minute=time_range_min,time_now,60 do
|
|
minute = tostring(minute)
|
|
if aggr[minute] == nil then
|
|
aggr[minute] = 0
|
|
end
|
|
end
|
|
|
|
--prepare the final result
|
|
for k, v in pairsByKeys(aggr, rev) do
|
|
res[#res + 1] = tonumber(v)
|
|
end
|
|
elseif stats_type == "counts_plain" then
|
|
res = aggr
|
|
elseif stats_type == "top_hosts" then
|
|
for k, v in pairs(aggr) do aggr[k] = tonumber(v) end
|
|
for k, v in pairsByValues(aggr, rev) do
|
|
res[#res + 1] = {host=k, value=v}
|
|
end
|
|
else
|
|
for k, v in pairs(aggr) do
|
|
res[#res + 1] = {label=k, value=tonumber(v)}
|
|
end
|
|
end
|
|
|
|
print(json.encode(res, nil))
|