mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-28 06:59:33 +00:00
Fixed pie chart no data messagae missing, handle no data from component (#10238)
This commit is contained in:
parent
90f0ebe8f7
commit
c755e701f0
7 changed files with 158 additions and 28 deletions
|
|
@ -261,6 +261,7 @@ await build({
|
|||
outDir: 'httpdocs/dist',
|
||||
emptyOutDir: false,
|
||||
minify: isProd ? 'esbuild' : false,
|
||||
reportCompressedSize: false,
|
||||
rollupOptions: {
|
||||
input: { login: resolve(__dirname, 'assets/scripts/login.js') },
|
||||
output: {
|
||||
|
|
|
|||
|
|
@ -176,11 +176,17 @@ function render(data) {
|
|||
/* Filtered data, excludes values too small to be shown in the chart
|
||||
* values with a number lesser then 0.0%
|
||||
*/
|
||||
const filtered_data = data.map((d, i) => ({
|
||||
const filtered_data = data
|
||||
.filter((d) => d.value > 0) // only exclude actual zeros
|
||||
.map((d) => ({
|
||||
label: d.label,
|
||||
value: d.value,
|
||||
percentage: total > 0 ? (d.value / total * 100).toFixed(1) : "0"
|
||||
})).filter((el) => el.percentage > 0.0);
|
||||
percentage: total > 0 ? (d.value / total * 100).toFixed(2) : "0"
|
||||
}));
|
||||
// there is no data to show
|
||||
if (filtered_data.length === 0) {
|
||||
no_data.value = true;
|
||||
}
|
||||
|
||||
items.value = filtered_data.map((d, i) => ({
|
||||
name: d.label,
|
||||
|
|
|
|||
|
|
@ -3542,6 +3542,15 @@ local lang = {
|
|||
["unresolved_hostname_description"] = "Trigger an alert when a TLS/QUIC/HTTP flow connects with a symbolic hostname not previously resolved via DNS",
|
||||
},
|
||||
["flow_details"] = {
|
||||
["bgp_peer_id"] = "Peer ID",
|
||||
["bgp_prefix"] = "BGP Prefix",
|
||||
["bgp_peer_id"] = "Peer ID",
|
||||
["bgp_origin"] = "Origin",
|
||||
["bgp_as_path"] = "AS Path",
|
||||
["bgp_next_hop"] = "Next Hop",
|
||||
["bgp_med"] = "MED",
|
||||
["bgp_local_pref"] = "Local Preference",
|
||||
["bgp_communities"]= "Communities",
|
||||
["acceptable_label"] = "Acceptable",
|
||||
["actual_peak_throughput"] = "Actual / Peak / Average Throughput",
|
||||
["additional_alert_type"] = "Other Issues",
|
||||
|
|
@ -6143,6 +6152,13 @@ local lang = {
|
|||
["total_flow_duration"] = "Total Duration",
|
||||
["total_num_calls"] = "Total %{subdir} Scripts Num Calls",
|
||||
["total_stats"] = "Total %{subdir} Scripts Stats",
|
||||
["alerts_drops"] = "Alerts Drops",
|
||||
["any_issue"] = "Any Issue",
|
||||
["availability"] = "Availability",
|
||||
["num_filtered"] = "Filtered",
|
||||
["periodic_activities_tot_not_executed_descr_short"] = "Not Executed",
|
||||
["periodic_activities_tot_running_slow_descr_short"] = "Running Slow",
|
||||
["script"] = "Script",
|
||||
["work_completion"] = "Completion",
|
||||
},
|
||||
["invalid_filters"] = {
|
||||
|
|
@ -7125,6 +7141,7 @@ local lang = {
|
|||
["timeout_warning"] = "Request Timeout",
|
||||
["ask_a_question"] = "Ask nAnalyst a question",
|
||||
["error_label"] = "Error",
|
||||
["calls"] = "Calls",
|
||||
["input_placeholder"] = "Ask a question",
|
||||
["analyzing"] = "Analyzing...",
|
||||
["investigating"] = "Investigating...",
|
||||
|
|
@ -7149,6 +7166,11 @@ local lang = {
|
|||
["usage_by_user"] = "Usage By User",
|
||||
["initial_call"] = "User Question",
|
||||
["tool_followup"] = "Tool Followup",
|
||||
["total_tokens"] = "Total Tokens",
|
||||
["unique_chats"] = "Unique Chats",
|
||||
["token_share"] = "Token Share",
|
||||
["avg_ms"] = "Avg Response ms",
|
||||
["max_ms"] = "Max Response ms",
|
||||
["final_response"] = "Final Response",
|
||||
["retry"] = "Retry",
|
||||
["stat_total_calls"] = "Total LLM Calls",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,107 @@ local format_utils = {}
|
|||
|
||||
local clock_start = os.clock()
|
||||
|
||||
function format_utils.formatBgpBmpInfo(bgp_data)
|
||||
for prefix, peers in pairs(bgp_data) do
|
||||
|
||||
local peer_list = {}
|
||||
for bgp_id, info in pairs(peers) do
|
||||
peer_list[#peer_list + 1] = { id = bgp_id, info = info }
|
||||
end
|
||||
|
||||
print("</table>\n")
|
||||
|
||||
print("<table class='table table-bordered table-striped' width='100%'>")
|
||||
|
||||
-- Prefix
|
||||
print("<tr><th colspan=" .. (#peer_list + 1) .. ">" ..
|
||||
i18n("flow_details.bgp_prefix") .. ": " .. prefix .. "</th></tr>\n")
|
||||
|
||||
-- Peer ID
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_peer_id") .."</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
print("<th>" .. peer.id .. "</th>")
|
||||
end
|
||||
print("</tr>\n")
|
||||
|
||||
-- BGP Origin
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_origin") .. "</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
print("<td>" .. (peer.info["origin"] or "") .. "</td>")
|
||||
end
|
||||
|
||||
print("</tr>\n")
|
||||
|
||||
-- AS Path
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_as_path") .. "</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
local as_path_string = ""
|
||||
|
||||
if peer.info["as_path"] and #peer.info["as_path"] > 0 then
|
||||
local parts = {}
|
||||
|
||||
for _, asn in ipairs(peer.info["as_path"]) do
|
||||
parts[#parts + 1] = tostring(asn)
|
||||
end
|
||||
|
||||
as_path_string = table.concat(parts, ' ')
|
||||
end
|
||||
|
||||
print("<td>" .. as_path_string .. "</td>")
|
||||
end
|
||||
|
||||
print("</tr>\n")
|
||||
|
||||
-- Next Hop
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_next_hop") .. "</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
print("<td>" .. (peer.info["next_hop"] or "") .. "</td>")
|
||||
end
|
||||
|
||||
print("</tr>\n")
|
||||
|
||||
-- MED
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_med") .. "</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
local med_string = (peer.info["med"] ~= nil) and tostring(peer.info["med"]) or ""
|
||||
print("<td>" .. med_string .. "</td>")
|
||||
end
|
||||
|
||||
print("</tr>\n")
|
||||
|
||||
-- Local Preference
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_local_pref") .. "</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
local lp_string = (peer.info["local_pref"] ~= nil) and tostring(peer.info["local_pref"]) or ""
|
||||
print("<td>" .. lp_string .. "</td>")
|
||||
end
|
||||
|
||||
print("</tr>\n")
|
||||
|
||||
-- Communities
|
||||
print("<tr><th>" .. i18n("flow_details.bgp_communities") .. "</th>")
|
||||
for _, peer in ipairs(peer_list) do
|
||||
local communities_string = ""
|
||||
|
||||
if peer.info["communities"] and #peer.info["communities"] > 0 then
|
||||
local badges = {}
|
||||
|
||||
for _, c in ipairs(peer.info["communities"]) do
|
||||
badges[#badges + 1] = "<span class='badge bg-secondary'>" .. c .. "</span>"
|
||||
end
|
||||
communities_string = table.concat(badges, " ")
|
||||
end
|
||||
print("<td>" .. communities_string .. "</td>")
|
||||
|
||||
end
|
||||
print("</tr>\n")
|
||||
|
||||
print("</table>\n")
|
||||
print("<table class='table table-bordered table-striped'>\n")
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function format_utils.createBreakdown(percentage1, percentage2, label1, label2)
|
||||
if percentage1 == 0 and percentage2 == 0 then
|
||||
return '<div style="height:8px;background:var(--border-subtle,#e9ecef);border-radius:100px;" data-bs-toggle="tooltip" title="No data available"></div>'
|
||||
|
|
@ -80,19 +181,19 @@ function format_utils.timeToSeconds(time)
|
|||
|
||||
local index = 1 -- represents which time we are analyzing, seconds, minutes, ecc.
|
||||
-- Split by : to get days, hours, minutes and seconds
|
||||
for _, time_in_string in pairsByKeys(time_splitted:split(":") or {}, rev) do
|
||||
for _, time_in_stringing in pairsByKeys(time_splitted:split(":") or {}, rev) do
|
||||
if index == 1 then
|
||||
-- Seconds
|
||||
seconds = seconds + tonumber(time_in_string)
|
||||
seconds = seconds + tonumber(time_in_stringing)
|
||||
elseif index == 2 then
|
||||
-- Minutes
|
||||
seconds = seconds + tonumber(time_in_string) * 60
|
||||
seconds = seconds + tonumber(time_in_stringing) * 60
|
||||
elseif index == 3 then
|
||||
-- Hours
|
||||
seconds = seconds + tonumber(time_in_string) * 3600
|
||||
seconds = seconds + tonumber(time_in_stringing) * 3600
|
||||
elseif index == 4 then
|
||||
-- Days
|
||||
seconds = seconds + tonumber(time_in_string) * 86400
|
||||
seconds = seconds + tonumber(time_in_stringing) * 86400
|
||||
end
|
||||
|
||||
index = index + 1
|
||||
|
|
@ -788,9 +889,9 @@ local _asn_cache = {}
|
|||
-- asn name formatted consistently
|
||||
-- @params asn: ASN Id
|
||||
-- short_version: Boolean, true if short version is needed (only name)
|
||||
-- shorten_string: Boolean, true if 64 char must be used
|
||||
-- shorten_stringing: Boolean, true if 64 char must be used
|
||||
-- @returns The formatted ASN name
|
||||
function format_utils.formatASN(asn, short_version, shorten_string)
|
||||
function format_utils.formatASN(asn, short_version, shorten_stringing)
|
||||
local name = ""
|
||||
|
||||
if asn then
|
||||
|
|
@ -813,7 +914,7 @@ function format_utils.formatASN(asn, short_version, shorten_string)
|
|||
-- if no asn info is present, curl to get ASN name
|
||||
name = ntop.getASNameFromASN(asn)
|
||||
end
|
||||
if (shorten_string) then
|
||||
if (shorten_stringing) then
|
||||
name = shortenString(name)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -78,13 +78,6 @@ function stats_utils.collapse_top_stats(stats, threshold)
|
|||
value = other_total,
|
||||
}
|
||||
end
|
||||
|
||||
if #top_res == 0 then
|
||||
top_res[#top_res + 1] = {
|
||||
label = i18n("no_flows"),
|
||||
value = 0,
|
||||
}
|
||||
end
|
||||
|
||||
return top_res
|
||||
end
|
||||
|
|
|
|||
|
|
@ -29,10 +29,12 @@ end
|
|||
local data = {}
|
||||
|
||||
for key, value in pairsByField(stats.qoe, "num", rev) do
|
||||
data[#data + 1] = {
|
||||
label = i18n("flow_details.qoe_" .. key .. "_label") or "",
|
||||
value = value.num
|
||||
}
|
||||
if value.num > 0 then
|
||||
data[#data + 1] = {
|
||||
label = i18n("flow_details.qoe_" .. key .. "_label") or "",
|
||||
value = value.num
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if collapse_stats then
|
||||
|
|
|
|||
|
|
@ -19,11 +19,16 @@ interface.select(ifid)
|
|||
|
||||
local ifstats = interface.getFlowsStatus()
|
||||
|
||||
local data = {
|
||||
{ label = i18n('enstablished'), value = ifstats["Established"] },
|
||||
{ label = i18n('syn'), value = ifstats["SYN"] },
|
||||
{ label = i18n('rst'), value = ifstats["RST"] },
|
||||
{ label = i18n('fin'), value = ifstats["FIN"] },
|
||||
}
|
||||
local function add_entry(t, label_key, val)
|
||||
if val ~= 0 then
|
||||
table.insert(t, { label = i18n(label_key), value = val })
|
||||
end
|
||||
end
|
||||
|
||||
local data = {}
|
||||
add_entry(data, 'enstablished', ifstats["Established"])
|
||||
add_entry(data, 'syn', ifstats["SYN"])
|
||||
add_entry(data, 'rst', ifstats["RST"])
|
||||
add_entry(data, 'fin', ifstats["FIN"])
|
||||
|
||||
rest_utils.answer(rest_utils.consts.success.ok, data)
|
||||
Loading…
Add table
Add a link
Reference in a new issue