-- -- (C) 2013-18 - ntop.org -- dirs = ntop.getDirs() package.path = dirs.installdir .. "/scripts/lua/modules/?.lua;" .. package.path require "lua_utils" require "graph_utils" require "grafana_utils" local ts_utils = require("ts_utils") interface.select(ifname) local ifnames = interface.getIfNames() if isCORSpreflight() then processCORSpreflight() else local corsr = {} corsr["Access-Control-Allow-Origin"] = _SERVER["Origin"] sendHTTPHeader('application/json', nil, corsr) local epoch_begin = toEpoch(_POST["payload"]["range"]["from"]) local epoch_end = toEpoch(_POST["payload"]["range"]["to"]) -- override max_num_points in singlerrd2json global_max_num_points = _POST["payload"]["maxDataPoints"] if global_max_num_points > 600 then global_max_num_points = 600 end local res = {} for _, t in pairs(_POST["payload"]["targets"]) do if t["target"] == nil then t["target"] = "" end local is_host = string.starts(t["target"] or '', "host_") local addr if is_host then addr = string.match(t["target"], "_(.-)_") -- host address is between the first two underscores t["target"] = string.gsub(t["target"], "host_(.-)_", "") end local is_traffic = string.ends(t["target"], "_traffic_bps") or string.ends(t["target"], "_traffic_total_bytes") local is_packets = string.ends(t["target"], "_traffic_pps") or string.ends(t["target"], "_traffic_total_packets") local is_allprotos = string.ends(t["target"], "_allprotocols_bps") local is_allcategories = string.ends(t["target"], "_allcategories_bps") local ifname = string.gsub(t["target"], "^(.-)_", "") -- lazy match to remove up to the first underscore ifname = string.gsub(ifname, "_(.-)$", "") -- lazy match to remove up to the last underscore local schema = nil local is_topk = false if is_traffic then if is_host then schema = "host:traffic" else schema = "iface:traffic" end elseif is_packets then schema = "iface:packets" elseif is_allprotos then if is_host then schema = "host:ndpi" else schema = "iface:ndpi" end is_topk = true elseif is_allcategories then if is_host then schema = "host:ndpi_categories" else schema = "iface:ndpi_categories" end is_topk = true else goto continue end local datapoints = {} local options = { max_num_points = global_max_num_points, -- always request full series -- as, by default, queryTopk only returns -- cumulated total values while grafana needs full timeseries with_series = true, } local rr local tags = {ifid=getInterfaceId(ifname), host=addr} if is_topk then rr = ts_utils.queryTopk(schema, tags, epoch_begin, epoch_end, options) else rr = ts_utils.query(schema, tags, epoch_begin, epoch_end, options) end if not rr then goto continue end local totalval = nil if rr.statistics then totalval = rr.statistics.total end local label = ifname if is_host then label = addr..", "..label end label = "["..label.."]" if is_allprotos then toSeries(rr, res, label) elseif string.ends(t["target"], "traffic_total_bytes") or string.ends(t["target"], "traffic_total_packets") then if totalval then res[#res + 1] = {target="Total", datapoints={{totalval, 0 --[[ it's an integral, an instant is not meaningful here --]]}}} end else toSeries(rr, res, label) end -- tprint({target=target, is_traffic=is_traffic, is_packets=is_packets, entity_name=entity_name}) ::continue:: end --tprint(_POST["payload"]) -- tprint("QUERY") -- tprint(_POST) print(json.encode(res, nil)) end