mirror of
https://github.com/ntop/ntopng.git
synced 2026-05-05 02:16:39 +00:00
Implements checkmk timeseries alert integration (#5269)
This commit is contained in:
parent
bc4fb9040b
commit
bdb4ceb7e0
3 changed files with 124 additions and 3 deletions
|
|
@ -913,7 +913,7 @@ function alert_store:count_by_severity_and_time_historical()
|
|||
|
||||
-- Group by according to the timeslot, that is, the alert timestamp MODULO the slot width
|
||||
local q = string.format("SELECT severity, (tstamp - tstamp %% %u) as slot, count(*) count FROM %s WHERE %s GROUP BY severity, slot ORDER BY severity, slot ASC",
|
||||
time_slot_width, self._table_name, where_clause)
|
||||
time_slot_width, self._table_name, where_clause)
|
||||
|
||||
local q_res = interface.alert_store_query(q) or {}
|
||||
|
||||
|
|
@ -930,13 +930,78 @@ function alert_store:count_by_severity_and_time_historical()
|
|||
local cur_slot = tonumber(p.slot)
|
||||
local cur_count = tonumber(p.count)
|
||||
if cur_slot >= min_slot and cur_slot <= max_slot then
|
||||
all_severities[severity_id].all_slots[cur_slot] = cur_count
|
||||
all_severities[severity_id].all_slots[cur_slot] = cur_count
|
||||
end
|
||||
end
|
||||
|
||||
return self:_prepare_count_by_severity_and_time_series(all_severities, min_slot, max_slot, time_slot_width)
|
||||
end
|
||||
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Performs a query and counts the number of records in multiple time slots using the old response format (CheckMK integration)
|
||||
function alert_store:old_timeseries_query_historical()
|
||||
local group_by = "hour"
|
||||
local time_slot_width = "3600"
|
||||
local where_clause = self:build_where_clause()
|
||||
|
||||
if severity then
|
||||
where_clause = string.format("severity = %u", severity) .. " AND " .. where_clause
|
||||
end
|
||||
|
||||
-- Group by according to the timeslot, that is, the alert timestamp MODULO the slot width
|
||||
local q = string.format("SELECT (tstamp - tstamp %% %u) as hour, count(*) count FROM %s WHERE %s GROUP BY hour",
|
||||
time_slot_width, self._table_name, where_clause)
|
||||
|
||||
local q_res = interface.alert_store_query(q) or {}
|
||||
|
||||
local res = alert_utils.formatOldTimeseries(q_res, self._epoch_begin, self._epoch_end)
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Performs a query and counts the number of records in multiple time slots using the old response format (CheckMK integration)
|
||||
function alert_store:old_timeseries_query_engaged(filter, severity)
|
||||
local group_by = "hour"
|
||||
local time_slot_width = "3600"
|
||||
local where_clause = self:build_where_clause()
|
||||
local entity_id_filter = tonumber(self._alert_entity and self._alert_entity.entity_id) -- Possibly set in subclasses constructor
|
||||
local entity_value_filter = filter
|
||||
local alert_id_filter = nil
|
||||
local severity_filter = nil
|
||||
local role_filter = nil
|
||||
|
||||
local alerts = interface.getEngagedAlerts(entity_id_filter, entity_value_filter, alert_id_filter, severity_filter)
|
||||
|
||||
q_res = self:filter_alerts(alerts)
|
||||
|
||||
-- Query done, now format the array
|
||||
local res = alert_utils.formatOldTimeseries(q_res, self._epoch_begin, self._epoch_end)
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
-- Old timeseries --
|
||||
--@brief Count from memory (engaged) or database (historical)
|
||||
--@return Alert counters divided into severity and time slots
|
||||
function alert_store:count_by_severity_and_time_old_ts()
|
||||
-- Add filters
|
||||
self:add_request_filters()
|
||||
-- Add limits and sort criteria
|
||||
self:add_request_ranges()
|
||||
|
||||
if self._status == alert_consts.alert_status.engaged.alert_status_id then -- Engaged
|
||||
return self:old_timeseries_query_engaged() or {}
|
||||
else -- Historical
|
||||
return self:old_timeseries_query_historical() or {}
|
||||
end
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Count from memory (engaged) or database (historical)
|
||||
|
|
@ -947,6 +1012,7 @@ function alert_store:count_by_severity_and_time()
|
|||
-- Add limits and sort criteria
|
||||
self:add_request_ranges()
|
||||
|
||||
-- old queries, integration with CheckMK
|
||||
if self._status == alert_consts.alert_status.engaged.alert_status_id then -- Engaged
|
||||
return self:count_by_severity_and_time_engaged() or 0
|
||||
else -- Historical
|
||||
|
|
@ -1006,7 +1072,14 @@ function alert_store:count_by_severity_and_time_request()
|
|||
colors = {}
|
||||
}
|
||||
|
||||
local count_data = self:count_by_severity_and_time()
|
||||
local count_data = 0
|
||||
local old_ts = toboolean(_GET["old_alert_ts"]) or false
|
||||
|
||||
if old_ts and old_ts == true then
|
||||
return self:count_by_severity_and_time_old_ts()
|
||||
else
|
||||
count_data = self:count_by_severity_and_time()
|
||||
end
|
||||
|
||||
for _, severity in pairsByField(alert_severities, "severity_id", rev) do
|
||||
if(count_data[severity.severity_id] ~= nil) then
|
||||
|
|
|
|||
|
|
@ -947,4 +947,51 @@ function alert_utils.formatBehaviorAlert(params, anomalies, stats, id, subtype,
|
|||
end
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
local function addDayEpoch(res, day_epoch)
|
||||
res[day_epoch] = {
|
||||
0, --[[ Counter for alerts between 00:00 and 00:59 UTC --]]
|
||||
0, --[[ Counter for alerts between 01:00 and 01:59 UTC --]]
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 --[[ Counter for alerts in other hours, until 23:00 to 23:59 --]]
|
||||
}
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
--@brief Function used to format the old timeseries format (CheckMK integration)
|
||||
function alert_utils.formatOldTimeseries(q_res, _epoch_begin, _epoch_end)
|
||||
local hour_secs = 60*60
|
||||
local day_secs = 60*60*24
|
||||
local epoch_begin = _epoch_begin - (_epoch_begin % day_secs) -- Round begin to start of day
|
||||
local epoch_end = _epoch_end - (_epoch_end % day_secs) + day_secs -- Round end to end of day
|
||||
local res = {}
|
||||
|
||||
tprint(q_res)
|
||||
for _, v in ipairs(q_res) do
|
||||
local tstamp = v.hour or v.tstamp
|
||||
-- Midnight UTC of the day containing v.hour
|
||||
local day_epoch = tstamp - (tstamp % day_secs)
|
||||
|
||||
-- Hour of the day containing v.hour, from 0 to 23, inclusive
|
||||
-- NOTE: Use the `floor` to make sure hour is an integer as it will be used to index a Lua array
|
||||
local hour = math.floor((tstamp - day_epoch) / hour_secs)
|
||||
|
||||
-- Here we add 1 to the hour as Lua array are indexed starting from 1, whereas `hour` is an integer starting from zero
|
||||
if not res[day_epoch] then
|
||||
res = addDayEpoch(res, day_epoch)
|
||||
end
|
||||
|
||||
-- This is done for both, enganged and historical alert, historical have v.hour and v.count, instead engaged
|
||||
-- There is one entry per engaged, reporting the starting time (tstamp), so just add +1 to the hour having that alert
|
||||
res[day_epoch][hour + 1] = tonumber(--[[ Historical ]]v.count or --[[ Engaged ]]((res[day_epoch][hour + 1] or 0) + 1))
|
||||
end -- for
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
-- ##############################################
|
||||
|
||||
return alert_utils
|
||||
|
|
|
|||
|
|
@ -1539,6 +1539,7 @@ local known_parameters = {
|
|||
["severity"] = validateListOfTypeInline(validateFilters(validateNumber)), -- Same as alert_severity
|
||||
["alert_granularity"] = validateNumber, -- An alert granularity
|
||||
["entity"] = validateNumber, -- An alert entity type
|
||||
["old_alert_ts"] = validateBool, -- Used to know if the new or the old timeseries format is requested
|
||||
["role"] = validateListOfTypeInline(validateFilters(validateSingleWord)), -- attacker/victim
|
||||
["role_cli_srv"] = validateListOfTypeInline(validateFilters(validateSingleWord)), -- client/server
|
||||
["acknowledged"] = validateListOfTypeInline(validateFilters(validateSingleWord)), -- acknowledged
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue