2021-07-29 22:37:30 -04:00
|
|
|
local timeseries = require 'timeseries'
|
2021-08-08 18:19:37 -04:00
|
|
|
local text_table = require 'text_table'
|
2021-08-08 15:58:53 -04:00
|
|
|
local i_o = require 'i_o'
|
2021-08-08 15:10:09 -04:00
|
|
|
local pure = require 'pure'
|
2022-07-18 19:38:15 -04:00
|
|
|
local sys = require 'sys'
|
2017-07-19 00:36:15 -04:00
|
|
|
|
2022-07-17 18:40:24 -04:00
|
|
|
return function(update_freq, config, common, width, point)
|
2021-07-17 23:45:12 -04:00
|
|
|
local DIAL_THICKNESS = 8
|
2021-07-19 21:14:38 -04:00
|
|
|
local DIAL_RADIUS = 32
|
|
|
|
local DIAL_SPACING = 40
|
|
|
|
local CACHE_Y_OFFSET = 7
|
|
|
|
local CACHE_X_OFFSET = 50
|
2021-07-17 23:45:12 -04:00
|
|
|
local TEXT_SPACING = 20
|
2022-07-18 23:44:51 -04:00
|
|
|
local PLOT_SECTION_BREAK = 23
|
2021-07-17 23:45:12 -04:00
|
|
|
local PLOT_HEIGHT = 56
|
|
|
|
local TABLE_SECTION_BREAK = 20
|
|
|
|
|
2021-11-10 12:24:13 -05:00
|
|
|
local __math_floor = math.floor
|
2021-07-17 23:45:12 -04:00
|
|
|
|
2022-07-17 19:30:48 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- state
|
|
|
|
|
2022-07-18 23:44:51 -04:00
|
|
|
local _show_swap = config.show_stats and config.show_swap
|
|
|
|
|
2022-07-18 19:38:15 -04:00
|
|
|
local mod_state = {mem = {total = sys.meminfo_field_reader('MemTotal')()}}
|
|
|
|
local update_state
|
2022-07-18 19:38:03 -04:00
|
|
|
|
2022-07-18 23:44:51 -04:00
|
|
|
if _show_swap == true then
|
2022-07-18 19:38:15 -04:00
|
|
|
mod_state.swap = {total = sys.meminfo_field_reader('SwapTotal')()}
|
|
|
|
update_state = sys.meminfo_updater_swap(mod_state.mem, mod_state.swap)
|
|
|
|
else
|
|
|
|
update_state = sys.meminfo_updater_noswap(mod_state.mem)
|
2022-07-17 19:30:48 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
local read_state = function()
|
2022-07-18 19:38:15 -04:00
|
|
|
update_state()
|
2022-07-17 19:30:48 -04:00
|
|
|
-- see manpage for free command for formulas
|
2022-07-18 19:38:15 -04:00
|
|
|
local m = mod_state.mem
|
2022-07-17 19:30:48 -04:00
|
|
|
m.used_percent =
|
|
|
|
(m.total -
|
|
|
|
m.memfree -
|
|
|
|
m.cached -
|
|
|
|
m.buffers -
|
|
|
|
m.sreclaimable) / m.total
|
|
|
|
end
|
|
|
|
|
2021-07-17 23:45:12 -04:00
|
|
|
-----------------------------------------------------------------------------
|
2022-07-14 18:02:47 -04:00
|
|
|
-- mem stats (dial + text)
|
|
|
|
|
|
|
|
local mk_stats = function(y)
|
2022-07-14 20:13:29 -04:00
|
|
|
local MEM_X = point.x + DIAL_RADIUS + DIAL_THICKNESS / 2
|
2022-07-14 18:02:47 -04:00
|
|
|
local DIAL_DIAMETER = DIAL_RADIUS * 2 + DIAL_THICKNESS
|
2022-07-18 19:38:03 -04:00
|
|
|
local CACHE_X
|
|
|
|
local SWAP_X
|
2022-07-18 23:44:51 -04:00
|
|
|
if _show_swap == true then
|
2022-07-18 19:38:03 -04:00
|
|
|
SWAP_X = MEM_X + DIAL_DIAMETER + DIAL_SPACING
|
|
|
|
CACHE_X = SWAP_X + CACHE_X_OFFSET + DIAL_DIAMETER / 2
|
|
|
|
else
|
|
|
|
CACHE_X = MEM_X + CACHE_X_OFFSET + DIAL_DIAMETER / 2
|
|
|
|
end
|
2022-07-17 12:40:36 -04:00
|
|
|
local CACHE_WIDTH = point.x + width - CACHE_X
|
2022-07-14 18:02:47 -04:00
|
|
|
local format_percent = function(x)
|
|
|
|
return string.format('%i%%', x)
|
|
|
|
end
|
2022-07-18 19:38:03 -04:00
|
|
|
|
|
|
|
-- memory bits (used no matter what)
|
2022-07-14 18:02:47 -04:00
|
|
|
local mem = common.make_dial(
|
|
|
|
MEM_X,
|
|
|
|
y + DIAL_RADIUS,
|
|
|
|
DIAL_RADIUS,
|
|
|
|
DIAL_THICKNESS,
|
|
|
|
80,
|
|
|
|
format_percent,
|
|
|
|
__math_floor
|
|
|
|
)
|
|
|
|
local cache = common.make_text_rows_formatted(
|
|
|
|
CACHE_X,
|
|
|
|
y + CACHE_Y_OFFSET,
|
|
|
|
CACHE_WIDTH,
|
|
|
|
TEXT_SPACING,
|
|
|
|
{'Page Cache', 'Buffers', 'Shared', 'Kernel Slab'},
|
|
|
|
'%.1f%%'
|
|
|
|
)
|
2022-07-18 19:38:03 -04:00
|
|
|
local update_mem = function()
|
2022-07-17 19:30:48 -04:00
|
|
|
local m = mod_state.mem
|
2022-07-18 19:38:03 -04:00
|
|
|
local mtot = m.total
|
2022-07-14 18:02:47 -04:00
|
|
|
common.dial_set(mem, m.used_percent * 100)
|
|
|
|
|
2022-07-18 19:38:03 -04:00
|
|
|
common.text_rows_set(cache, 1, m.cached / mtot * 100)
|
|
|
|
common.text_rows_set(cache, 2, m.buffers / mtot * 100)
|
|
|
|
common.text_rows_set(cache, 3, m.shmem / mtot * 100)
|
|
|
|
common.text_rows_set(cache, 4, m.sreclaimable / mtot * 100)
|
2022-07-14 18:02:47 -04:00
|
|
|
end
|
2022-07-18 19:38:03 -04:00
|
|
|
local static_mem = function(cr)
|
2022-07-14 18:02:47 -04:00
|
|
|
common.dial_draw_static(mem, cr)
|
|
|
|
common.text_rows_draw_static(cache, cr)
|
|
|
|
end
|
2022-07-18 19:38:03 -04:00
|
|
|
local dynamic_mem = function(cr)
|
2022-07-14 18:02:47 -04:00
|
|
|
common.dial_draw_dynamic(mem, cr)
|
|
|
|
common.text_rows_draw_dynamic(cache, cr)
|
|
|
|
end
|
2022-07-18 19:38:03 -04:00
|
|
|
local ret = pure.partial(common.mk_acc, width, DIAL_DIAMETER)
|
|
|
|
|
|
|
|
-- add swap bits if needed
|
2022-07-18 23:44:51 -04:00
|
|
|
if _show_swap == true then
|
2022-07-18 19:38:03 -04:00
|
|
|
local swap = common.make_dial(
|
|
|
|
SWAP_X,
|
|
|
|
y + DIAL_RADIUS,
|
|
|
|
DIAL_RADIUS,
|
|
|
|
DIAL_THICKNESS,
|
|
|
|
80,
|
|
|
|
format_percent,
|
|
|
|
__math_floor
|
|
|
|
)
|
|
|
|
local update_swap = function()
|
|
|
|
local w = mod_state.swap
|
|
|
|
common.dial_set(swap, (w.total - w.free) / w.total * 100)
|
|
|
|
end
|
|
|
|
local static_swap = pure.partial(common.dial_draw_static, swap)
|
|
|
|
local dynamic_swap = pure.partial(common.dial_draw_dynamic, swap)
|
|
|
|
return ret(
|
|
|
|
pure.sequence(update_mem, update_swap),
|
|
|
|
pure.sequence(static_mem, static_swap),
|
|
|
|
pure.sequence(dynamic_mem, dynamic_swap)
|
|
|
|
)
|
|
|
|
else
|
|
|
|
return ret(update_mem, static_mem, dynamic_mem)
|
|
|
|
end
|
2021-07-19 21:14:38 -04:00
|
|
|
end
|
|
|
|
|
2021-07-17 23:45:12 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- memory consumption plot
|
|
|
|
|
2022-07-18 23:44:51 -04:00
|
|
|
local mk_bare_plot = function(y)
|
2022-07-14 18:02:47 -04:00
|
|
|
local obj = common.make_percent_timeseries(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x,
|
2022-07-14 18:02:47 -04:00
|
|
|
y,
|
2022-07-17 12:40:36 -04:00
|
|
|
width,
|
2022-07-14 18:02:47 -04:00
|
|
|
PLOT_HEIGHT,
|
|
|
|
update_freq
|
|
|
|
)
|
2022-07-17 18:54:23 -04:00
|
|
|
return common.mk_acc(
|
2022-07-17 12:40:36 -04:00
|
|
|
width,
|
2022-07-14 18:02:47 -04:00
|
|
|
PLOT_HEIGHT,
|
2022-07-17 19:30:48 -04:00
|
|
|
function() timeseries.update(obj, mod_state.mem.used_percent) end,
|
2022-07-14 18:02:47 -04:00
|
|
|
pure.partial(timeseries.draw_static, obj),
|
|
|
|
pure.partial(timeseries.draw_dynamic, obj)
|
|
|
|
)
|
|
|
|
end
|
2020-04-11 15:14:14 -04:00
|
|
|
|
2022-07-18 23:44:51 -04:00
|
|
|
local mk_tagged_plot = function(y)
|
|
|
|
local obj = common.make_tagged_percent_timeseries(
|
|
|
|
point.x,
|
|
|
|
y,
|
|
|
|
width,
|
|
|
|
PLOT_HEIGHT,
|
|
|
|
PLOT_SECTION_BREAK,
|
|
|
|
"Total Memory",
|
|
|
|
update_freq
|
|
|
|
)
|
|
|
|
return common.mk_acc(
|
|
|
|
width,
|
|
|
|
PLOT_HEIGHT + PLOT_SECTION_BREAK,
|
|
|
|
function()
|
|
|
|
common.tagged_percent_timeseries_set(
|
|
|
|
obj,
|
|
|
|
mod_state.mem.used_percent * 100
|
|
|
|
)
|
|
|
|
end,
|
|
|
|
pure.partial(common.tagged_percent_timeseries_draw_static, obj),
|
|
|
|
pure.partial(common.tagged_percent_timeseries_draw_dynamic, obj)
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
local mk_plot = config.show_stats and mk_bare_plot or mk_tagged_plot
|
|
|
|
|
2021-07-17 23:45:12 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- memory top table
|
|
|
|
|
2022-07-14 18:02:47 -04:00
|
|
|
local mk_tbl = function(y)
|
2022-07-18 00:36:44 -04:00
|
|
|
local num_rows = config.table_rows
|
|
|
|
local table_conky = pure.map_n(
|
2022-07-14 18:02:47 -04:00
|
|
|
function(i)
|
|
|
|
return {
|
|
|
|
comm = '${top_mem name '..i..'}',
|
|
|
|
pid = '${top_mem pid '..i..'}',
|
|
|
|
mem = '${top_mem mem '..i..'}',
|
|
|
|
}
|
|
|
|
end,
|
2022-07-18 00:36:44 -04:00
|
|
|
num_rows)
|
2022-07-14 18:02:47 -04:00
|
|
|
local obj = common.make_text_table(
|
2022-07-14 20:13:29 -04:00
|
|
|
point.x,
|
2022-07-14 18:02:47 -04:00
|
|
|
y,
|
2022-07-17 12:40:36 -04:00
|
|
|
width,
|
2022-07-18 00:36:44 -04:00
|
|
|
num_rows,
|
2022-07-14 18:02:47 -04:00
|
|
|
'Mem (%)'
|
|
|
|
)
|
2022-07-17 19:30:48 -04:00
|
|
|
local update = function()
|
2022-07-18 00:36:44 -04:00
|
|
|
for r = 1, num_rows do
|
|
|
|
text_table.set(obj, 1, r, i_o.conky(table_conky[r].comm, '(%S+)'))
|
|
|
|
text_table.set(obj, 2, r, i_o.conky(table_conky[r].pid))
|
|
|
|
text_table.set(obj, 3, r, i_o.conky(table_conky[r].mem))
|
2022-07-14 18:02:47 -04:00
|
|
|
end
|
|
|
|
end
|
2022-07-17 18:54:23 -04:00
|
|
|
return common.mk_acc(
|
2022-07-17 12:40:36 -04:00
|
|
|
width,
|
2022-07-19 00:54:46 -04:00
|
|
|
common.table_height(num_rows),
|
2022-07-14 18:02:47 -04:00
|
|
|
update,
|
|
|
|
pure.partial(text_table.draw_static, obj),
|
|
|
|
pure.partial(text_table.draw_dynamic, obj)
|
|
|
|
)
|
|
|
|
end
|
2021-07-17 23:45:12 -04:00
|
|
|
|
2022-07-14 18:02:47 -04:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
-- main functions
|
|
|
|
|
2022-07-17 19:12:31 -04:00
|
|
|
return {
|
|
|
|
header = 'MEMORY',
|
|
|
|
point = point,
|
|
|
|
width = width,
|
2022-07-17 22:30:38 -04:00
|
|
|
set_state = read_state,
|
2022-07-17 19:12:31 -04:00
|
|
|
top = {
|
2022-07-16 23:48:01 -04:00
|
|
|
{mk_stats, config.show_stats, PLOT_SECTION_BREAK},
|
|
|
|
{mk_plot, config.show_plot, TABLE_SECTION_BREAK},
|
2022-07-18 00:36:44 -04:00
|
|
|
{mk_tbl, config.table_rows > 0, 0},
|
2022-07-14 18:02:47 -04:00
|
|
|
}
|
2022-07-17 19:12:31 -04:00
|
|
|
}
|
2021-07-17 00:17:22 -04:00
|
|
|
end
|