Время от времени (раз в несколько дней) я замечаю, что какой-то процесс использует 100% CPU. Процесс запускается avrdude
Arduino IDE, которая при определенных обстоятельствах, которые я не смог воспроизвести, просто сидит на 100% CPU, как показано на top
.
Возможно, обстоятельства таковы, что начинается загрузка на плату Arduino, и плата во время процесса отключается.
У меня 8 ядер в процессоре, поэтому не сразу видно, что одно из них загружено. На самом деле, это становится заметно только если это происходит несколько раз подряд, и тогда у меня, возможно, 3 ядра загружены на 100% CPU.
Есть ли способ сделать так, чтобы какая-то фоновая задача проверяла это (скажем, каждые 15 минут), а затем оповещала меня каким-то образом (например, всплывающим диалоговым окном)? Я использую Ubuntu 14.04 LTS.
Спасибо MelBurslan за ответ, но я в недоумении, почему он не работает полностью. Мой текущий сценарий такой:
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
Я снизил порог для тестирования. Однако, как вы видите, он собирает отдельные процессы нормально, но последний тест (для отображения диалогового окна) не проходит, потому что pstring внезапно стал пустым по причинам, которые я не вижу:
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
решение1
Прочитав ответ MelBurslan и различные комментарии, я решил попробовать (вдохновленный их предложениями) сделать версию на Lua. Это было сделано вЛуа 5.1.5- Я не уверен, будет ли это работать с последней версией Lua.
Основная идея заключается в использовании Lua popen
(открыть канал) для выполнения top
и последующей обработки полученных данных с использованием регулярного выражения (илишаблон, как это называется в Lua). Совпадающие строки (а их большинство) затем рассматриваются как пересекающие пороговый процент. Если они это делают, они добавляются в таблицу.
Если таблица не пуста, то zenity
вызывается для отображения сообщения пользователю. Несколько "подводных камней", которые я обнаружил во время разработки:
- Я добавил в zenity тайм-аут в 60 секунд, чтобы, если вы в этот момент не находитесь за компьютером, экран не заполнялся предупреждающими диалогами.
- Я добавил
--display=:0.0
, чтобы при запуске под управлениемcron
. Я упростил тест для «каждых 15 минут» в crontab, вот так:
*/15 * * * * /home/nick/check_cpu_usage.lua
Регулярное выражение захватывает все данные
top
на случай, если вы захотите провести другие тесты (например, использование слишком большого объема памяти).
Я думаю, это будет быстрее, чем запускать множество процессов и подоболочек. Кажется, это работает нормально. Протестируйте, уменьшив порог (например, до 5) и изменив запись в crontab на проверку каждые минуты.
проверка_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
решение2
создайте простой скрипт вроде этого
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
затем запустите команду crontab -e
и вставьте строку вроде этой:
0,15,30,45 * * * * /path/to/my/checker/script
сохранить и выйти. Затем выполнить
chmod 755 /path/to/my/checker/script
Я не знаком с ним, zenity
так как я не использовал графический дисплей на сервере Linux некоторое время и никогда не нуждался в нем. Так что, если он по какой-то причине не работает, обратитесь за помощью на man zenity
. Это замена устаревшему исполняемому файлу xdialog
, как я слышал.