diff --git a/httpdocs/css/pie-chart.css b/httpdocs/css/pie-chart.css index 927b21805a..c8f788b42c 100644 --- a/httpdocs/css/pie-chart.css +++ b/httpdocs/css/pie-chart.css @@ -21,6 +21,12 @@ -moz-box-sizing: border-box; box-sizing: border-box; } + +.pie-chart-small { + height: 260px; + width: 280px; +} + .pie-chart .total{ font-size: 18px; font-weight: bold; diff --git a/httpdocs/js/pie-chart.js b/httpdocs/js/pie-chart.js index ed0b93a37e..f46356759b 100644 --- a/httpdocs/js/pie-chart.js +++ b/httpdocs/js/pie-chart.js @@ -326,6 +326,14 @@ function create_pie_chart(name, units) { var textOffset = 14; var tweenDuration = 250; var r = 116; //100; + + if($(name).hasClass("pie-chart-small")) { + w = 270; + h = 250; + r = w / 3 - 20; + ir = r / 2; + } + var lines, valueLabels, nameLabels; //D3 helper function to populate pie slice parameters from array data @@ -351,7 +359,7 @@ function create_pie_chart(name, units) { var vis = d3.select(name).append("svg:svg") .attr("width", w) .attr("height", h) - .attr("viewBox","0 0 500 325") + .attr("viewBox","0 0 " + w + " " + h) .attr("preserveAspectRatio","xMidYMid"); //GROUP FOR ARCS/PATHS diff --git a/include/AlertsManager.h b/include/AlertsManager.h index 3b4fdd1f1b..57c6c332be 100644 --- a/include/AlertsManager.h +++ b/include/AlertsManager.h @@ -166,6 +166,12 @@ class AlertsManager : protected StoreManager { int deleteAlerts(bool engaged, const int *rowid); int deleteAlerts(bool engaged, AlertEntity alert_entity, const char *alert_entity_value); + + /* + ========== raw API ====== + */ + int selectAlertsRaw(lua_State *vm, bool engaged, const char *selection, const char *clauses); + /* Following are the legacy methods that were formally global to the whole ntopng */ #ifdef NOTUSED /** diff --git a/scripts/lua/get_alerts_stats_data.lua b/scripts/lua/get_alerts_stats_data.lua new file mode 100644 index 0000000000..8438ef6bfb --- /dev/null +++ b/scripts/lua/get_alerts_stats_data.lua @@ -0,0 +1,106 @@ +-- +-- (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 stats_type = _GET["stats_type"] + +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" then + if stats_type == "severity_pie" then + selection = "alert_severity as label, count(*) as value" + aggregation = "group by label" + labeller = alertSeverityLabel + elseif stats_type == "type_pie" then + selection = "alert_type as label, count(*) as value" + aggregation = "group by label" + labeller = alertTypeLabel + 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 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 = "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_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 + aggr["Engaged"] = interface.getNumAlerts(true) + aggr["Closed"] = interface.getNumAlerts(false) +end + +for k, v in pairs(aggr) do + res[#res + 1] = {label=k, value=tonumber(v)} +end + +print(json.encode(res, nil)) diff --git a/scripts/lua/modules/alert_utils.lua b/scripts/lua/modules/alert_utils.lua index 09d1544019..dccaf6fec3 100644 --- a/scripts/lua/modules/alert_utils.lua +++ b/scripts/lua/modules/alert_utils.lua @@ -671,6 +671,33 @@ end -- ################################# +function drawAlertStatsCharts() + print[[ +
| Severity | Type | Duration | Counts |
|---|---|---|---|
| + | + | + | + |