feat: reordenar pestañas (Sistema por defecto) + stats de red
- Orden de pestañas: Sistema, Red, Docker. Sistema es la pestaña por
defecto al arrancar.
- Pestaña Red, bajo el gráfico:
- Paquetes/s por protocolo (TCP/UDP/ICMP, in/out) calculados como
delta de los contadores de /proc/net/snmp.
- Top 4 hosts remotos por número de conexiones establecidas (ss),
excluyendo loopback.
- Botones de la pestaña Red reubicados (BTN_Y) y el hook de ratón
ajustado al nuevo índice de pestaña.
This commit is contained in:
+109
-19
@@ -27,7 +27,7 @@ local H = 545
|
|||||||
local TAB_TOP = 4
|
local TAB_TOP = 4
|
||||||
local TAB_H = 24
|
local TAB_H = 24
|
||||||
local BTN_H = 26
|
local BTN_H = 26
|
||||||
local BTN_Y = 242 -- fila de botones de la pestaña Red
|
local BTN_Y = 322 -- fila de botones de la pestaña Red
|
||||||
|
|
||||||
-- Interfaz de red a monitorizar (enp5s0 es la fisica activa) ------------------
|
-- Interfaz de red a monitorizar (enp5s0 es la fisica activa) ------------------
|
||||||
local NIF = "enp5s0"
|
local NIF = "enp5s0"
|
||||||
@@ -35,8 +35,8 @@ local NIF = "enp5s0"
|
|||||||
-- Helper de metricas (temps + GPU), portado del widget previo -----------------
|
-- Helper de metricas (temps + GPU), portado del widget previo -----------------
|
||||||
local MET = os.getenv("HOME") .. "/.config/conky/conky_widget/metric.sh"
|
local MET = os.getenv("HOME") .. "/.config/conky/conky_widget/metric.sh"
|
||||||
|
|
||||||
-- Pestañas -------------------------------------------------------------------
|
-- Pestañas (Sistema por defecto) ---------------------------------------------
|
||||||
local TABS = { "Red", "Sistema", "Docker" }
|
local TABS = { "Sistema", "Red", "Docker" }
|
||||||
local current_tab = 1
|
local current_tab = 1
|
||||||
|
|
||||||
-- Botones de la pestaña Red. bin se comprueba antes de lanzar; si falta,
|
-- Botones de la pestaña Red. bin se comprueba antes de lanzar; si falta,
|
||||||
@@ -121,6 +121,70 @@ local function rate_kib(s)
|
|||||||
else return n / 1024 end
|
else return n / 1024 end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Paquetes por intervalo y protocolo: delta de los contadores de /proc/net/snmp.
|
||||||
|
-- g_proto guarda los paquetes del ultimo intervalo (≈ por segundo con
|
||||||
|
-- update_interval=1). Se actualiza una vez por frame desde conky_draw.
|
||||||
|
local g_proto = { tcp_in = 0, tcp_out = 0, udp_in = 0, udp_out = 0, icmp_in = 0, icmp_out = 0 }
|
||||||
|
local snmp_prev = nil
|
||||||
|
|
||||||
|
local function update_proto()
|
||||||
|
local f = io.open("/proc/net/snmp", "r")
|
||||||
|
if not f then return end
|
||||||
|
local hdr, cur = {}, {}
|
||||||
|
for line in f:lines() do
|
||||||
|
local proto, rest = line:match("^(%w+):%s+(.+)$")
|
||||||
|
if proto then
|
||||||
|
if hdr[proto] == nil then
|
||||||
|
local cols, i = {}, 0
|
||||||
|
for tok in rest:gmatch("%S+") do i = i + 1; cols[tok] = i end
|
||||||
|
hdr[proto] = cols
|
||||||
|
else
|
||||||
|
local vals = {}
|
||||||
|
for tok in rest:gmatch("%S+") do vals[#vals + 1] = tok end
|
||||||
|
cur[proto] = vals
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
f:close()
|
||||||
|
local function get(proto, col)
|
||||||
|
local cols = hdr[proto]; local vals = cur[proto]
|
||||||
|
if not cols or not vals then return 0 end
|
||||||
|
local idx = cols[col]; if not idx then return 0 end
|
||||||
|
return tonumber(vals[idx]) or 0
|
||||||
|
end
|
||||||
|
local c = {
|
||||||
|
tcp_in = get("Tcp", "InSegs"), tcp_out = get("Tcp", "OutSegs"),
|
||||||
|
udp_in = get("Udp", "InDatagrams"), udp_out = get("Udp", "OutDatagrams"),
|
||||||
|
icmp_in = get("Icmp", "InMsgs"), icmp_out = get("Icmp", "OutMsgs"),
|
||||||
|
}
|
||||||
|
if snmp_prev then
|
||||||
|
for k, v in pairs(c) do
|
||||||
|
local d = v - (snmp_prev[k] or v)
|
||||||
|
g_proto[k] = (d < 0) and 0 or d
|
||||||
|
end
|
||||||
|
end
|
||||||
|
snmp_prev = c
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Top hosts remotos por numero de conexiones TCP/UDP establecidas (ss) --------
|
||||||
|
local function top_remotes()
|
||||||
|
local out = str("${execi 3 ss -tun state established 2>/dev/null}")
|
||||||
|
local counts = {}
|
||||||
|
for line in out:gmatch("[^\n]+") do
|
||||||
|
if not line:match("^Netid") and not line:match("^State") then
|
||||||
|
local ip = line:match("([%d%.]+):%d+%s*$") or line:match("%[([%x:]+)%]:%d+%s*$")
|
||||||
|
-- Excluir loopback: no son hosts "remotos"
|
||||||
|
if ip and not ip:match("^127%.") and ip ~= "::1" then
|
||||||
|
counts[ip] = (counts[ip] or 0) + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local arr = {}
|
||||||
|
for ip, c in pairs(counts) do arr[#arr + 1] = { ip = ip, c = c } end
|
||||||
|
table.sort(arr, function(a, b) return a.c > b.c end)
|
||||||
|
return arr
|
||||||
|
end
|
||||||
|
|
||||||
-- Helpers de dibujo ----------------------------------------------------------
|
-- Helpers de dibujo ----------------------------------------------------------
|
||||||
local function setcol(cr, c, a)
|
local function setcol(cr, c, a)
|
||||||
cairo_set_source_rgba(cr, c[1], c[2], c[3], a or 1.0)
|
cairo_set_source_rgba(cr, c[1], c[2], c[3], a or 1.0)
|
||||||
@@ -208,27 +272,52 @@ end
|
|||||||
|
|
||||||
-- Panel: Red -----------------------------------------------------------------
|
-- Panel: Red -----------------------------------------------------------------
|
||||||
local function draw_red(cr)
|
local function draw_red(cr)
|
||||||
local y = 50
|
local y = 46
|
||||||
text(cr, 12, y, "Interfaz " .. NIF, COL.dim, 11); y = y + 22
|
text(cr, 12, y + 10, "Interfaz " .. NIF, COL.dim, 11); y = y + 20
|
||||||
|
|
||||||
text(cr, 12, y, "Down", COL.down, 12)
|
text(cr, 12, y + 10, "Down", COL.down, 12)
|
||||||
text(cr, 90, y, str("${downspeed " .. NIF .. "}"), COL.text, 13, true); y = y + 20
|
text(cr, 90, y + 10, str("${downspeed " .. NIF .. "}"), COL.text, 13, true); y = y + 18
|
||||||
text(cr, 12, y, "Up", COL.up, 12)
|
text(cr, 12, y + 10, "Up", COL.up, 12)
|
||||||
text(cr, 90, y, str("${upspeed " .. NIF .. "}"), COL.text, 13, true); y = y + 24
|
text(cr, 90, y + 10, str("${upspeed " .. NIF .. "}"), COL.text, 13, true); y = y + 20
|
||||||
|
|
||||||
graph(cr, 12, y, W - 24, 70, {
|
graph(cr, 12, y, W - 24, 56, {
|
||||||
{ data = hist.down, c = COL.down },
|
{ data = hist.down, c = COL.down },
|
||||||
{ data = hist.up, c = COL.up },
|
{ data = hist.up, c = COL.up },
|
||||||
})
|
})
|
||||||
y = y + 78
|
y = y + 62
|
||||||
|
|
||||||
|
-- Paquetes por segundo y protocolo (delta de /proc/net/snmp)
|
||||||
|
text(cr, 12, y + 10, "PAQUETES/s", COL.snow, 10, true)
|
||||||
|
rtext(cr, W - 10, y + 10, "in / out", COL.dim, 9); y = y + 15
|
||||||
|
local function prow(label, c, ipkt, opkt)
|
||||||
|
text(cr, 14, y + 10, label, c, 10)
|
||||||
|
rtext(cr, W - 10, y + 10, ipkt .. " / " .. opkt, COL.text, 10); y = y + 13
|
||||||
|
end
|
||||||
|
prow("TCP", COL.cyan, g_proto.tcp_in, g_proto.tcp_out)
|
||||||
|
prow("UDP", COL.green, g_proto.udp_in, g_proto.udp_out)
|
||||||
|
prow("ICMP", COL.yellow, g_proto.icmp_in, g_proto.icmp_out)
|
||||||
|
y = y + 4
|
||||||
|
|
||||||
|
-- Top hosts remotos por numero de conexiones establecidas
|
||||||
|
text(cr, 12, y + 10, "TOP REMOTOS", COL.snow, 10, true)
|
||||||
|
rtext(cr, W - 10, y + 10, "conex.", COL.dim, 9); y = y + 15
|
||||||
|
local arr = top_remotes()
|
||||||
|
if #arr == 0 then
|
||||||
|
text(cr, 14, y + 10, "sin conexiones establecidas", COL.dim, 9); y = y + 13
|
||||||
|
else
|
||||||
|
for i = 1, math.min(4, #arr) do
|
||||||
|
text(cr, 14, y + 10, arr[i].ip, COL.text, 10)
|
||||||
|
rtext(cr, W - 10, y + 10, tostring(arr[i].c), COL.green, 10); y = y + 13
|
||||||
|
end
|
||||||
|
end
|
||||||
|
y = y + 4
|
||||||
|
|
||||||
local conns = str("${execi 2 ss -tun state established 2>/dev/null | tail -n +2 | wc -l}")
|
local conns = str("${execi 2 ss -tun state established 2>/dev/null | tail -n +2 | wc -l}")
|
||||||
text(cr, 12, y, "Conexiones activas: " .. conns, COL.text, 11); y = y + 16
|
text(cr, 12, y + 10, "Conexiones activas: " .. conns, COL.text, 10); y = y + 13
|
||||||
text(cr, 12, y, "Total ↓ " .. str("${totaldown " .. NIF .. "}") ..
|
text(cr, 12, y + 9, "Total ↓ " .. str("${totaldown " .. NIF .. "}") ..
|
||||||
" ↑ " .. str("${totalup " .. NIF .. "}"), COL.dim, 10)
|
" ↑ " .. str("${totalup " .. NIF .. "}"), COL.dim, 9)
|
||||||
|
|
||||||
draw_buttons(cr)
|
draw_buttons(cr)
|
||||||
|
|
||||||
text(cr, 12, BTN_Y + BTN_H + 18,
|
text(cr, 12, BTN_Y + BTN_H + 18,
|
||||||
"Wireshark abre el buffer de captura mas reciente.", COL.dim, 9)
|
"Wireshark abre el buffer de captura mas reciente.", COL.dim, 9)
|
||||||
end
|
end
|
||||||
@@ -334,14 +423,15 @@ function conky_draw()
|
|||||||
push(hist.diskio, rate_kib(str("${diskio}")))
|
push(hist.diskio, rate_kib(str("${diskio}")))
|
||||||
push(hist.down, num("${downspeedf " .. NIF .. "}"))
|
push(hist.down, num("${downspeedf " .. NIF .. "}"))
|
||||||
push(hist.up, num("${upspeedf " .. NIF .. "}"))
|
push(hist.up, num("${upspeedf " .. NIF .. "}"))
|
||||||
|
update_proto()
|
||||||
|
|
||||||
setcol(cr, COL.bg, 0.86); rrect(cr, 0, 0, W, H, 10); cairo_fill(cr)
|
setcol(cr, COL.bg, 0.86); rrect(cr, 0, 0, W, H, 10); cairo_fill(cr)
|
||||||
|
|
||||||
draw_tabs(cr)
|
draw_tabs(cr)
|
||||||
if current_tab == 1 then
|
if current_tab == 1 then
|
||||||
draw_red(cr)
|
|
||||||
elseif current_tab == 2 then
|
|
||||||
draw_sys(cr)
|
draw_sys(cr)
|
||||||
|
elseif current_tab == 2 then
|
||||||
|
draw_red(cr)
|
||||||
else
|
else
|
||||||
draw_docker(cr)
|
draw_docker(cr)
|
||||||
end
|
end
|
||||||
@@ -376,8 +466,8 @@ function conky_mouse(event)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Botones de la pestaña Red
|
-- Botones de la pestaña Red (ahora es la pestaña 2)
|
||||||
if current_tab == 1 and y >= BTN_Y and y <= BTN_Y + BTN_H then
|
if current_tab == 2 and y >= BTN_Y and y <= BTN_Y + BTN_H then
|
||||||
local bw = (W - 24) / 3
|
local bw = (W - 24) / 3
|
||||||
for i = 1, 3 do
|
for i = 1, 3 do
|
||||||
local bx = 8 + (i - 1) * (bw + 4)
|
local bx = 8 + (i - 1) * (bw + 4)
|
||||||
|
|||||||
Reference in New Issue
Block a user