Wie kann man erkennen und warnen, wenn ein Prozess über einen längeren Zeitraum 100 % der CPU nutzt?

Wie kann man erkennen und warnen, wenn ein Prozess über einen längeren Zeitraum 100 % der CPU nutzt?

Hin und wieder (alle paar Tage) stelle ich fest, dass ein Prozess 100 % der CPU-Auslastung nutzt. Der Prozess wird avrdudevon der Arduino IDE gestartet, die unter bestimmten Umständen, die ich nicht reproduzieren konnte, einfach bei 100 % der CPU-Auslastung bleibt, wie in gezeigt top.

Möglicherweise liegt es daran, dass ein Upload auf das Arduino-Board beginnt und das Board während des Vorgangs getrennt wird.

Ich habe 8 Kerne im Prozessor, daher ist es nicht sofort offensichtlich, dass einer davon voll ausgelastet ist. Tatsächlich fällt es nur auf, wenn es ein paar Mal hintereinander passiert und ich dann vielleicht 3 Kerne mit 100 % CPU-Auslastung habe.

Gibt es eine Möglichkeit, dies im Hintergrund zu überprüfen (sagen wir alle 15 Minuten) und mich dann irgendwie zu benachrichtigen (z. B. durch ein Popup-Dialogfeld)? Ich verwende Ubuntu 14.04 LTS.


Vielen Dank an MelBurslan für seine Antwort, aber ich bin ratlos, warum es nicht richtig funktioniert. Mein aktuelles Skript ist folgendes:

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

Ich habe den Schwellenwert zum Testen gesenkt. Wie Sie jedoch sehen, werden die einzelnen Prozesse ordnungsgemäß erfasst, aber der letzte Test (zum Anzeigen des Dialogfelds) schlägt fehl, da pstring aus Gründen, die ich nicht erkennen kann, plötzlich leer geworden ist:

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

Antwort1

Nachdem ich die Antwort von MelBurslan und verschiedene Kommentare gelesen hatte, beschloss ich (inspiriert von ihren Vorschlägen), eine Version in Lua zu erstellen. Dies geschah inLua 5.1.5– Ich bin nicht sicher, ob es mit dem neuesten Lua funktioniert.

Die Grundidee besteht darin, Luas popen(öffnen Sie eine Pipe) zu verwenden, um topdie resultierenden Daten auszuführen und dann mit einem regulären Ausdruck zu verarbeiten (oderMuster, wie es in Lua genannt wird). Übereinstimmende Zeilen (das wären die meisten) werden dann dahingehend ausgewertet, ob sie den prozentualen Schwellenwert überschreiten. Wenn dies der Fall ist, werden sie einer Tabelle hinzugefügt.

Wenn die Tabelle nicht leer ist, zenitywird aufgerufen, um dem Benutzer eine Meldung anzuzeigen. Einige Fallstricke, die ich während der Entwicklung gefunden habe:

  • Ich habe Zenity ein Timeout von 60 Sekunden hinzugefügt, damit der Bildschirm nicht mit Warndialogen gefüllt wird, wenn Sie zu diesem Zeitpunkt nicht am PC sind.
  • Ich habe es hinzugefügt --display=:0.0, damit beim Ausführen unter ein Anzeigebildschirm gefunden wird cron.
  • Ich habe den Test für „alle 15 Minuten“ in der Crontab wie folgt vereinfacht:

    */15 * * * * /home/nick/check_cpu_usage.lua
    
  • Der reguläre Ausdruck erfasst alles, topfalls Sie andere Tests durchführen möchten (z. B. bei zu großer Speichernutzung).

Ich denke, das wäre schneller, als viele Prozesse und Subshells zu starten. Es scheint gut zu funktionieren. Testen Sie, indem Sie den Schwellenwert reduzieren (z. B. auf 5) und den Crontab-Eintrag so ändern, dass er alle Minuten überprüft wird.


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

Antwort2

Erstellen Sie ein einfaches Skript wie dieses

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

Führen Sie dann den Befehl aus crontab -eund fügen Sie eine Zeile wie diese ein:

0,15,30,45 * * * * /path/to/my/checker/script 

speichern und beenden. Dann ausführen

chmod 755 /path/to/my/checker/script

Ich bin nicht vertraut damit, zenityda ich schon eine Weile keine grafische Anzeige auf einem Linux-Server verwendet habe und sie auch nie gebraucht habe. Wenn es also aus irgendeinem Grund fehlschlägt, suchen Sie nach Hilfe auf man zenity. Wie ich gehört habe, ist es der Ersatz für die alte ausführbare Datei xdialog.

verwandte Informationen