Refactors RTT to Active Monitoring

Addresses #3741

Refactors RTT: rtt_utils to active_monitoring_utils

Refactors RTT: rtt_host to am_host schema name

Refactors RTT: import_active_monitoring_config.lua

Refactors RTT: active_monitoring_stats.lua

Refactors RTT: active_monitoring_stats i18n

Refactors RTT: get_active_monitoring_config.lua

Refactors RTT: get_active_monitoring_hosts

Refactors RTT: edit_active_monitoring_host

Refactors RTT: active_monitoring.lua

Refactors RTT: active_monitor

Refactors RTT: active_monitoring_utils.js

Refactors RTT: get_active_monitoring_hosts.lua fixes

Refactors RTT: last_rtt

Refactors RTT: rtt_host to am_host
This commit is contained in:
Simone Mainardi 2020-04-13 19:11:06 +02:00
parent 32b5cecf7d
commit 3e14bc30f8
27 changed files with 202 additions and 204 deletions

View file

@ -0,0 +1,398 @@
--
-- (C) 2013-20 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local page_utils = require("page_utils")
local alert_consts = require("alert_consts")
local active_monitoring_utils = require("active_monitoring_utils")
local plugins_utils = require("plugins_utils")
local template = require("template_utils")
local active_monitoring_utils = require("active_monitoring_utils")
local json = require("dkjson")
local graph_utils = require("graph_utils")
local alert_utils = require("alert_utils")
local ts_creation = plugins_utils.timeseriesCreationEnabled()
if not isAllowedSystemInterface() then
return
end
sendHTTPContentTypeHeader('text/html')
page_utils.set_active_menu_entry(page_utils.menu_entries.active_monitor)
dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
local page = _GET["page"] or "overview"
local host = _GET["am_host"]
local measurement = _GET["measurement"]
local base_url = plugins_utils.getUrl("active_monitoring_stats.lua") .. "?ifid=" .. getInterfaceId(ifname)
local url = base_url
local info = ntop.getInfo()
local measurement_info
if(not isEmptyString(host) and not isEmptyString(measurement)) then
host = active_monitoring_utils.getHost(host, measurement)
measurement_info = active_monitoring_utils.getMeasurementInfo(host.measurement)
else
host = nil
end
if host then
url = url .. "&am_host=" .. host.host .. "&measurement=" .. host.measurement
end
local title = i18n("graphs.active_monitoring")
if((host ~= nil) and (page ~= "overview")) then
title = title..": " .. host.label
end
if isAdministrator() then
if(_POST["action"] == "reset_config") then
active_monitoring_utils.resetConfig()
end
end
page_utils.print_navbar(title, url,
{
{
active = page == "overview" or not page,
page_name = "overview",
label = "<i class=\"fas fa-lg fa-home\"></i>",
url = base_url,
},
{
hidden = not host or not ts_creation,
active = page == "historical",
page_name = "historical",
label = "<i class='fas fa-lg fa-chart-area'></i>",
},
{
hidden = not isAdministrator() or not plugins_utils.hasAlerts(getSystemInterfaceId(), {entity = alert_consts.alertEntity("pinged_host")}),
active = page == "alerts",
page_name = "alerts",
label = "<i class=\"fas fa-lg fa-exclamation-triangle\"></i>",
},
}
)
-- #######################################################
if(page == "overview") then
print(template.gen("modal_confirm_dialog.html", {
dialog={
id = "reset-modal",
action = "$('#reset-form').submit()",
title = i18n("config_scripts.config_reset"),
message = i18n("active_monitoring_stats.config_reset_confirm"),
confirm = i18n("reset")
}
}))
print(
template.gen("config_list_components/import_modal.html", {
dialog={
id = "import-modal",
title = i18n("host_pools.config_import"),
label = "",
message = i18n("host_pools.config_import_message"),
cancel = i18n("cancel"),
apply = i18n("apply"),
}
})
)
print([[
<div class='container-fluid my-3'>
<div class='row'>
<div class="col-md-12">
<div id="rtt-alert" class="alert alert-success" style="display: none" role="alert">
<strong>]] .. i18n("success") .. [[</strong> <span class="alert-body"></span>
<button type="button" class="close" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
</div>
<div class='row'>
<div class='col-md-12 col-12'>
<table class="table w-100 table-striped table-hover table-bordered" id="rtt-table">
<thead>
<tr>
<th>]].. i18n("flow_details.url") ..[[</th>
<th>]].. i18n("chart") ..[[</th>
<th>]].. i18n("threshold") .. [[</th>
<th>]].. i18n("active_monitoring_stats.last_measurement") .. [[</th>
<th>]].. i18n("system_stats.last_ip") .. [[</th>
<th>]].. i18n("active_monitoring_stats.measurement") .. [[</th>
<th>]].. i18n("actions") .. [[</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div id='rtt-edit-modal' class="modal fade" tabindex="-1" role="dialog">
<form method="post" id='rtt-edit-form'>
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">]] .. i18n("active_monitoring_stats.edit_record") .. [[</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body container-fluid">
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("active_monitoring_stats.measurement") .. [[</label>
<div class="col-sm-5">
]].. generate_select("select-edit-measurement", "measurement", true, false, active_monitoring_utils.getAvailableMeasurements(), "measurement-select") ..[[
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("about.host_callbacks_directory") .. [[</label>
<div class="col-sm-5">
<input placeholder="yourhostname.org" required id="input-edit-host" type="text" name="host" class="form-control measurement-host" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("internals.periodicity") .. [[</label>
<div class="col-sm-5">
]].. generate_select("select-edit-granularity", "granularity", true, false, {}, "measurement-granularity") ..[[
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("threshold") .. [[</label>
<div class="col-sm-5">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text measurement-operator"></span>
</div>
<input placeholder="100" required id="input-edit-threshold" name="threshold" type="number" class="form-control rounded-right" min="10" max="10000">
<span class="my-auto ml-1 measurement-unit"></span>
</div>
</div>
</div>
<div id='script-description' class='alert alert-light' role='alert'>
]] .. i18n("notes") ..[[
<ul>
<li>]] .. i18n("active_monitoring_stats.rtt_note_icmp") ..[[</li>
<li>]] .. i18n("active_monitoring_stats.rtt_note_http") ..[[</li>
<li>]] .. i18n("active_monitoring_stats.note_alert") ..[[</li>
</ul>
</div>
<span class="invalid-feedback"></span>
</div>
<div class="modal-footer">
<button id="btn-reset-defaults" type="button" class="btn btn-danger mr-auto">]] .. i18n("reset") .. [[</button>
<button type="button" class="btn btn-secondary" data-dismiss="modal">]] .. i18n("cancel") .. [[</button>
<button type="submit" class="btn btn-primary">]] .. i18n("apply") .. [[</button>
</div>
</div>
</div>
</form>
</div>
<div id='rtt-add-modal' class="modal fade" tabindex="-1" role="dialog">
<form method="post" id='rtt-add-form'>
<div class="modal-dialog modal-lg modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">]] .. i18n("active_monitoring_stats.add_record") .. [[</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body container-fluid">
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("active_monitoring_stats.measurement") .. [[</label>
<div class="col-sm-5">
]] .. generate_select("select-add-measurement", "measurement", true, false, active_monitoring_utils.getAvailableMeasurements(), "measurement-select") ..[[
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("about.host_callbacks_directory") .. [[</label>
<div class="col-sm-5">
<input placeholder="yourhostname.org" required id="input-add-host" type="text" name="host" class="form-control measurement-host" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("internals.periodicity") .. [[</label>
<div class="col-sm-5">
]].. generate_select("select-add-granularity", "granularity", true, false, {}, "measurement-granularity") ..[[
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">]] .. i18n("threshold") .. [[</label>
<div class="col-sm-5">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text measurement-operator"></span>
</div>
<input placeholder="100" required id="input-add-threshold" value="100" name="threshold" type="number" class="form-control rounded-right" min="1" max="10000">
<span class="my-auto ml-1 measurement-unit"></span>
</div>
</div>
</div>
<div id='script-description' class='alert alert-light' role='alert'>
]] .. i18n("notes") ..[[
<ul>
<li>]] .. i18n("active_monitoring_stats.rtt_note_icmp") ..[[</li>
<li>]] .. i18n("active_monitoring_stats.rtt_note_http") ..[[</li>
<li>]] .. i18n("active_monitoring_stats.note_alert") ..[[</li>
</ul>
</div>
<span class="invalid-feedback"></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">]] .. i18n("cancel") .. [[</button>
<button type="submit" class="btn btn-primary">]] .. i18n("add") .. [[</button>
</div>
</div>
</div>
</form>
</div>
<div id='rtt-delete-modal' class="modal fade" tabindex="-1" role="dialog">
<form id='rtt-delete-form'>
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">]] .. i18n("delete") .. [[: <span id="delete-host"></span></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
<div class="modal-body">
<p>
]] .. i18n("active_monitoring_stats.confirm_delete") .. [[
</p>
<span class="invalid-feedback"></span>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">]] .. i18n("cancel") .. [[</button>
<button id="btn-delete-rtt" type="submit" class="btn btn-danger">]] .. i18n("delete") .. [[</button>
</div>
</div>
</div>
</form>
</div>
<div style="margin-bottom: 1rem">
<form action="]] .. ntop.getHttpPrefix() .. [[/plugins/get_active_monitoring_config.lua" class="form-inline" method="GET">
<button type="submit" class="btn btn-secondary"><span>]] .. i18n('config_scripts.config_export') .. [[</span></button>
</form><button id="import-modal-btn" data-toggle="modal" data-target="#import-modal" class="btn btn-secondary"><span>]] .. i18n('config_scripts.config_import') .. [[</span></button>
<form class="form-inline" method="POST" id="reset-form">
<input type="hidden" name="csrf" value="]].. ntop.getRandomCSRFValue() ..[["/>
<input type="hidden" name="action" value="reset_config"/>
<button type="button" id="reset-modal-btn" data-toggle="modal" data-target="#reset-modal" class="btn btn-secondary"><span>]] .. i18n('config_scripts.config_reset') .. [[</span></button>
</form>
</div>
<div>
]].. i18n("notes") .. [[<ul>
<li>]].. i18n("active_monitoring_stats.note1", {product=info.product}) ..[[</li>
<li>]].. i18n("active_monitoring_stats.note2") ..[[</li>
<li>]].. i18n("active_monitoring_stats.note_alert") ..[[</li>
</ul>
</div>
]])
local measurements_info = {}
-- This information is required in rtt-utils.js in order to properly
-- render the template
for key, info in pairs(active_monitoring_utils.getMeasurementsInfo()) do
measurements_info[key] = {
granularities = active_monitoring_utils.getAvailableGranularities(key),
operator = info.operator,
unit = i18n(info.i18n_unit) or info.i18n_unit,
force_host = info.force_host,
}
end
print([[
<link href="]].. ntop.getHttpPrefix() ..[[/datatables/datatables.min.css" rel="stylesheet"/>
<script type="text/javascript">
i18n.showing_x_to_y_rows = "]].. i18n('showing_x_to_y_rows', {x='_START_', y='_END_', tot='_TOTAL_'}) ..[[";
i18n.search = "]].. i18n("search") ..[[:";
i18n.msec = "]] .. i18n("active_monitoring_stats.msec") .. [[";
i18n.edit = "]] .. i18n("users.edit") .. [[";
i18n.delete = "]] .. i18n("delete") .. [[";
i18n.expired_csrf = "]] .. i18n("expired_csrf") .. [[";
let get_host = "]].. (_GET["host"] ~= nil and _GET["host"] or "") ..[[";
let rtt_csrf = "]].. ntop.getRandomCSRFValue() ..[[";
let import_csrf = "]].. ntop.getRandomCSRFValue() ..[[";
let measurements_info = ]] .. json.encode(measurements_info) .. [[;
</script>
<script type='text/javascript' src=']].. ntop.getHttpPrefix() ..[[/js/active_monitoring/active_monitoring_utils.js?]] ..(ntop.getStartupEpoch()) ..[['></script>
]])
elseif((page == "historical") and (host ~= nil) and (measurement_info ~= nil)) then
local suffix = "_" .. host.granularity
local schema = _GET["ts_schema"] or ("am_host:rtt" .. suffix)
local selected_epoch = _GET["epoch"] or ""
local tags = {ifid=getSystemInterfaceId(), host=host.host, measure=host.measurement --[[ note: measurement is a reserved InfluxDB keyword ]]}
local notes = {}
url = url.."&page=historical"
local timeseries = {
{ schema="am_host:rtt" .. suffix, label=i18n("graphs.num_ms_rtt"), value_formatter=(measurement_info.value_js_formatter or "fmillis") },
}
for _, note in ipairs(measurement_info.i18n_chart_notes or {}) do
notes[#notes + 1] = i18n(note) or note
end
for _, ts_info in ipairs(measurement_info.additional_timeseries or {}) do
-- Add the per-granularity suffix (e.g. _min)
ts_info.schema = ts_info.schema .. suffix
timeseries[#timeseries + 1] = ts_info
end
graph_utils.drawGraphs(getSystemInterfaceId(), schema, tags, _GET["zoom"], url, selected_epoch, {
timeseries = timeseries,
notes = notes,
})
elseif((page == "alerts") and isAdministrator()) then
local old_ifname = ifname
local ts_utils = require("ts_utils")
local influxdb = ts_utils.getQueryDriver()
-- NOTE: system interface must be manually sected and then unselected
interface.select(getSystemInterfaceId())
_GET["ifid"] = getSystemInterfaceId()
_GET["entity"] = alert_consts.alertEntity("pinged_host")
if host then
_GET["entity_val"] = active_monitoring_utils.getRttHostKey(host.host, host.measurement)
end
alert_utils.drawAlerts()
interface.select(old_ifname)
end
-- #######################################################
dofile(dirs.installdir .. "/scripts/lua/inc/footer.lua")

View file

@ -0,0 +1,162 @@
--
-- (C) 2019-20 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require("dkjson")
local active_monitoring_utils = require("active_monitoring_utils")
sendHTTPContentTypeHeader('application/json')
-- ################################################
local action = _POST["action"]
local host = _POST["am_host"]
local measurement = _POST["measurement"]
local rv = {}
local function reportError(msg)
print(json.encode({ error = msg, success = false, csrf = ntop.getRandomCSRFValue() }))
end
local function isValidHostMeasurementCombination(host, measurement)
local host_v4 = isIPv4(host)
local host_v6 = isIPv6(host)
local expected_ipv = ternary((measurement == "icmp6"), 6, 4)
if(((expected_ipv == 6) and host_v6) or
((expected_ipv == 4) and host_v4)) then
-- IP address version matches
return(true)
elseif(((expected_ipv == 6) and host_v4) or
((expected_ipv == 4) and host_v6)) then
reportError(i18n("active_monitoring_stats.invalid_combination"))
return(false)
end
-- Host is a domain, try to resolve it to validate it
if(ntop.resolveHost(host, ternary((expected_ipv == 4), true, false)) ~= nil) then
-- Valid Host
return(true)
end
reportError(i18n("active_monitoring_stats.invalid_host"))
return(false)
end
-- ################################################
if isEmptyString(action) then
reportError(i18n("active_monitoring_stats.empty_action"))
return
end
if isEmptyString(host) then
reportError(i18n("missing_x_parameter", {param='am_host'}))
return
end
if isEmptyString(measurement) then
reportError(i18n("missing_x_parameter", {param='measurement'}))
return
end
if not haveAdminPrivileges() then
reportError(i18n("not_admin"))
return
end
-- ################################################
if(action == "add") then
local existing
local rtt_value = _POST["rtt_max"]
local granularity = _POST["granularity"]
local url = active_monitoring_utils.formatRttHost(host, measurement)
if(isValidHostMeasurementCombination(host, measurement) == false) then
-- NOTE: reportError already called
return
end
existing = active_monitoring_utils.hasHost(host, measurement)
if existing then
reportError(i18n("active_monitoring_stats.host_exists", {host=url}))
return
end
active_monitoring_utils.addHost(host, measurement, rtt_value, granularity)
rv.message = i18n("active_monitoring_stats.host_add_ok", {host=url})
elseif(action == "edit") then
local existing
local rtt_value = _POST["rtt_max"]
local granularity = _POST["granularity"]
local url = active_monitoring_utils.formatRttHost(host, measurement)
local old_rtt_host = _POST["old_rtt_host"]
local old_measurement = _POST["old_measurement"]
if(isValidHostMeasurementCombination(host, measurement) == false) then
-- NOTE: reportError already called
return
end
if isEmptyString(old_rtt_host) then
reportError(i18n("missing_x_parameter", {param='old_rtt_host'}))
return
end
if isEmptyString(old_measurement) then
reportError(i18n("missing_x_parameter", {param='old_measurement'}))
return
end
local old_url = active_monitoring_utils.formatRttHost(old_rtt_host, old_measurement)
existing = active_monitoring_utils.hasHost(old_rtt_host, old_measurement)
if not existing then
reportError(i18n("active_monitoring_stats.host_not_exists", {host=old_url}))
return
end
if((old_rtt_host ~= host) or (old_measurement ~= measurement)) then
-- The key has changed, delete the old host and create a new one
existing = active_monitoring_utils.hasHost(host, measurement)
if existing then
reportError(i18n("active_monitoring_stats.host_exists", {host=url}))
return
end
active_monitoring_utils.deleteHost(old_rtt_host, old_measurement)
active_monitoring_utils.addHost(host, measurement, rtt_value, granularity)
else
-- The key is the same, only update the rtt
active_monitoring_utils.addHost(host, measurement, rtt_value, granularity)
end
rv.message = i18n("active_monitoring_stats.host_edit_ok", {host=old_url})
elseif(action == "delete") then
local url = active_monitoring_utils.formatRttHost(host, measurement)
local existing = active_monitoring_utils.hasHost(host, measurement)
if not existing then
reportError(i18n("active_monitoring_stats.host_not_exists", {host=url}))
end
active_monitoring_utils.deleteHost(host, measurement)
rv.message = i18n("active_monitoring_stats.host_delete_ok", {host=url})
else
reportError(i18n("active_monitoring_stats.bad_action_param"))
return
end
-- ################################################
rv.success = true
rv.csrf = ntop.getRandomCSRFValue()
print(json.encode(rv))

View file

@ -0,0 +1,26 @@
--
-- (C) 2019-20 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local page_utils = require("page_utils")
local active_monitoring_utils = require "active_monitoring_utils"
if not haveAdminPrivileges() then
sendHTTPContentTypeHeader('text/html')
page_utils.print_header()
dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
print("<div class=\"alert alert-danger\"><img src=".. ntop.getHttpPrefix() .. "/img/warning.png>"..i18n("error_not_granted").."</div>")
return
end
sendHTTPContentTypeHeader('application/json', 'attachment; filename="active_monitoring_conf.json"')
local conf = active_monitoring_utils.getHosts(true --[[ only retrieve the configuration ]])
print(json.encode(conf, nil))

View file

@ -0,0 +1,75 @@
--
-- (C) 2019-20 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local format_utils = require("format_utils")
local json = require("dkjson")
local active_monitoring_utils = require("active_monitoring_utils")
local plugins_utils = require("plugins_utils")
sendHTTPContentTypeHeader('application/json')
local charts_available = plugins_utils.timeseriesCreationEnabled()
-- ################################################
local active_monitoring_hosts = active_monitoring_utils.getHosts()
local res = {}
for key, active_monitoring_host in pairs(active_monitoring_hosts) do
local chart = ""
local m_info = active_monitoring_utils.getMeasurementInfo(active_monitoring_host.measurement)
if not m_info then
goto continue
end
if charts_available then
chart = plugins_utils.getUrl('active_monitoring_stats.lua') .. '?am_host='.. active_monitoring_host.host ..'&measurement='.. active_monitoring_host.measurement ..'&page=historical'
end
local column_last_ip = ""
local column_last_update = ""
local column_last_rtt = ""
local last_update = active_monitoring_utils.getLastRttUpdate(active_monitoring_host.host, active_monitoring_host.measurement)
if(last_update ~= nil) then
local tdiff = os.time() - last_update.when
if(tdiff <= 600) then
column_last_update = secondsToTime(tdiff).. " " ..i18n("details.ago")
else
column_last_update = format_utils.formatPastEpochShort(last_update.when)
end
column_last_rtt = last_update.value
column_last_ip = last_update.ip
end
if(column_last_rtt == "") then chart = "" end
res[#res + 1] = {
key = key,
url = active_monitoring_host.label,
host = active_monitoring_host.host,
measurement = active_monitoring_host.measurement,
chart = chart,
threshold = active_monitoring_host.max_rtt,
last_measure = column_last_rtt,
last_mesurement_time = column_last_update,
last_ip = column_last_ip,
granularity = active_monitoring_host.granularity,
unit = i18n(m_info.i18n_unit) or m_info.i18n_unit,
}
::continue::
end
-- ################################################
print(json.encode(res))

View file

@ -0,0 +1,61 @@
--
-- (C) 2019-20 - ntop.org
--
local dirs = ntop.getDirs()
package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path
require "lua_utils"
local json = require ("dkjson")
local page_utils = require("page_utils")
local active_monitoring_utils = require "active_monitoring_utils"
local json = require ("dkjson")
if not haveAdminPrivileges() then
sendHTTPContentTypeHeader('text/html')
page_utils.print_header()
dofile(dirs.installdir .. "/scripts/lua/inc/menu.lua")
print("<div class=\"alert alert-danger\"><img src=".. ntop.getHttpPrefix() .. "/img/warning.png>"..i18n("error_not_granted").."</div>")
return
end
local result = {}
result.csrf = ntop.getRandomCSRFValue()
sendHTTPContentTypeHeader('application/json')
-- ################################################
if(_POST["JSON"] == nil) then
result.error = "invalid-parameter"
print(json.encode(result))
return
end
local data = json.decode(_POST["JSON"])
if(table.empty(data)) then
result.error = "bad-format"
print(json.encode(result))
return
end
-- ################################################
active_monitoring_utils.resetConfig()
for host_key, conf in pairs(data) do
host = active_monitoring_utils.key2host(host_key)
active_monitoring_utils.addHost(host.host, host.measurement, conf.max_rtt, conf.granularity)
end
-- ################################################
if result.error == nil then
result.success = true
end
print(json.encode(result))

View file

@ -0,0 +1,12 @@
return {
label = "active_monitoring_stats.active_monitoring",
script = "active_monitoring_stats.lua",
sort_order = 1500,
menu_entry = {key = "active_monitor", i18n_title = "active_monitoring_stats.active_monitoring", section = "system_stats"},
is_shown = function()
local user_scripts = require("user_scripts")
return(user_scripts.isSystemScriptEnabled("active_monitoring"))
end
}