De vez en cuando (cada pocos días) noto que un proceso utiliza el 100% de la CPU. El proceso lo avrdude
inicia el IDE de Arduino que, bajo ciertas circunstancias que no he podido reproducir, simplemente permanece allí al 100% de la CPU, como se muestra en top
.
Posiblemente las circunstancias sean que comience una carga en la placa Arduino y la placa se desconecte durante el proceso.
Tengo 8 núcleos en el procesador, por lo que no es inmediatamente obvio que uno de ellos esté al máximo. De hecho, solo se nota si sucede varias veces seguidas, y luego tengo quizás 3 núcleos al 100% de CPU.
¿Hay alguna manera de realizar alguna verificación de tareas en segundo plano para esto (digamos, cada 15 minutos) y luego alertarme de alguna manera (por ejemplo, algún cuadro de diálogo emergente)? Estoy usando Ubuntu 14.04 LTS.
Gracias a MelBurslan por su respuesta, pero no sé por qué no funciona del todo. Mi script actual es este:
cpupercentthreshold=2
pstring=""
top -b -n 1 | sed -e "1,7d" | while read line; do
cpuutil=$(echo ${line} | awk '{print $9}' | cut -d"." -f 1)
procname=$(echo ${line} | awk '{print $12}' )
if [ ${cpuutil} -ge ${cpupercentthreshold} ]
then
echo ${cpuutil}
pstring=${pstring}${procname}" "
echo pstring is currently ${pstring}
fi
done
echo pstring is ${pstring}
if [ -n "${pstring}" ]
then
zenity --title="Warning!" --question --text="These processes are above CPU threshold limit ${pstring}" --ok-label="OK"
fi
Bajé el umbral para realizar pruebas. Sin embargo, como puede ver, recopila los procesos individuales correctamente, pero la prueba final (para mostrar el cuadro de diálogo) falla porque pstring de repente quedó vacío por razones que no puedo ver:
13
pstring is currently VirtualBox
6
pstring is currently VirtualBox Xorg
6
pstring is currently VirtualBox Xorg compiz
6
pstring is currently VirtualBox Xorg compiz ibus-engin+
6
pstring is currently VirtualBox Xorg compiz ibus-engin+ top
pstring is
Respuesta1
Después de leer la respuesta de MelBurslan y varios comentarios, decidí intentar (inspirado por sus sugerencias) hacer una versión en Lua. Esto se hizo enLua 5.1.5- No estoy seguro de si funcionará con la última versión de Lua.
La idea general es usar Lua popen
(abrir una tubería) para ejecutar top
y luego procesar los datos resultantes usando una expresión regular (opatrón, como se llama en Lua). Luego se consideran las líneas coincidentes (que serían la mayoría de ellas) para cruzar el porcentaje umbral. Si lo hacen, se agregan a una tabla.
Si la tabla no está vacía, zenity
se llama para mostrar un mensaje al usuario. Algunos "errores" que encontré durante el desarrollo:
- Agregué un tiempo de espera de 60 segundos a zenity para que, si no estaba en la PC en ese momento, no llenara la pantalla con cuadros de diálogo de advertencia.
- Agregué
--display=:0.0
para que se encontrara una pantalla de visualización cuando se ejecutaba encron
. Simplifiqué la prueba "cada 15 minutos" en el crontab, así:
*/15 * * * * /home/nick/check_cpu_usage.lua
La expresión regular captura todo
top
en caso de que desee realizar otras pruebas (por ejemplo, usar demasiada memoria).
Creo que esto sería más rápido que iniciar muchos procesos y subcapas. Parece funcionar bien. Pruebe reduciendo el umbral (por ejemplo, a 5) y cambie la entrada de crontab para verificar cada minutos.
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
Respuesta2
crea un script simple como este
cpupercentthreshold=75
pstring=""
top -b -n 1 | sed -e "1,7d" | while read line; do
cpuutil=$(echo ${line} | awk '{print $9}' | cut -d"." -f 1)
if [ ${cpuutil} -ge ${cpupercentthreshold} ]
then
pstring=${pstring}${procname}" "
fi
done
if [ -z "${pstring}" ]
then
echo "Everything looks good $(date)" >>mylogfile #if you want to keep track
else
zenity --title="Warning!" --question --text="These processes are above CPU threshold limit ${pstring}" --ok-label="OK"
fi
luego ejecute el comando crontab -e
e inserte una línea como esta:
0,15,30,45 * * * * /path/to/my/checker/script
guardar y Salir. Luego ejecuta
chmod 755 /path/to/my/checker/script
No lo conozco zenity
porque no he usado una pantalla gráfica en un servidor Linux por un tiempo y nunca necesité usarla. Entonces, si falla por algún motivo, busque ayuda en man zenity
. Es el reemplazo del ejecutable heredado xdialog
, según escuché.