Depois de ler a resposta de MelBurslan e vários comentários, decidi tentar (inspirado em suas sugestões) fazer uma versão em Lua. Isso foi feito em Lua 5.1.5 - Não tenho certeza se ele funcionará com a Lua mais recente.
A ideia geral é usar popen
(open a pipe) de Lua para executar top
e então processar os dados resultantes usando uma expressão regular (ou padrão , como é chamado em Lua ). Linhas correspondentes (que seriam a maioria delas) são então consideradas para cruzar a porcentagem limite. Se eles fizerem isso, eles serão adicionados a uma tabela.
Se a tabela não estiver vazia, então zenity
é chamado para exibir uma mensagem ao usuário. Algumas "pegadinhas" que encontrei durante o desenvolvimento:
- Eu adicionei um tempo limite de 60 segundos ao zenity para que, se você não estivesse no PC no momento, não preenchesse a tela com caixas de diálogo de aviso.
- Eu adicionei
--display=:0.0
para que uma tela de exibição fosse encontrada durante a execução emcron
. -
Eu simplifiquei o teste para "a cada 15 minutos" no crontab, assim:
*/15 * * * * /home/nick/check_cpu_usage.lua
-
A expressão regular captura tudo de
top
caso você queira fazer outros testes (por exemplo, usar muita memória).
Acho que isso seria mais rápido do que disparar muitos processos e subpastas. Parece funcionar bem. Teste reduzindo o limite (por exemplo, para 5) e altere a entrada do crontab para verificar a cada minuto.
check_cpu_usage.lua
#! /usr/local/bin/lua
THRESHOLD = 90 -- percent
-- pipe output of top through a file "f"
f = assert (io.popen ("top -b -n 1 -w 512"))
t = { }
-- check each line
for line in f:lines() do
-- match top output, eg.
-- PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
-- 30734 nick 20 0 6233848 3.833g 3.731g S 8.6 12.2 3:11.75 VirtualBox
local pid, user, priority, nice, virt, res, shr,
status, cpu, mem, time, command =
string.match (line,
"^%s*(%d+)%s+(%a+)%s+(%-?%d+)%s+(%-?%d+)" ..
-- pid user priority nice
"%s+([%d.]+[g]?)%s+([%d.]+[g]?)%s+([%d.]+[g]?)%s+([DRSTZ])%s+(%d+%.%d+)%s+(%d+%.%d+)" ..
-- virtual res shr status %cpu %mem
"%s+([0-9:.]+)%s+(.*)$")
-- time command
-- if a match (first few lines won't) check for CPU threshold
if pid then
cpu = tonumber (cpu)
if cpu >= THRESHOLD then
table.insert (t, string.format ("%s (%.1f%%)", command, cpu))
end -- if
end -- if
end -- for loop
f:close()
-- if any over the limit, alert us
if #t > 0 then
os.execute ('zenity --title="CPU usage warning!" --info ' ..
'--text="These processes are using more than ' ..
THRESHOLD .. '% CPU:\n' ..
table.concat (t, ", ") ..
'" --ok-label="OK" ' ..
'--timeout=60 ' .. -- close dialog after one minute in case we aren't around
'--display=:0.0 ' -- ensure visible when running under cron
)
end -- if