LINUX.ORG.RU

Скрипт - us и sy в файл

 , ,


0

1

Пишу скрипт, который пишет в текстовый файл через равные промежутки времени некоторую диагностическую информацию.

Сейчас в файл пишется CPU из PS по конкретному процессу:

#!/bin/bash

delay=15
pid=939445
log="/root/myPerfLog/2008.txt"

echo "Time pcpu" >> $log

for (( i=0; i <= 960; i++ ))
do

	currTime=$(date +%H:%M:%S)
	psData=$(ps -p $pid --no-headers -o pcpu)

	echo "$currTime $psData" >> $log
	echo $strps

	sleep $gDelay

done

Теперь мне нужны %us и %sy которые я вижу в top.

%Cpu(s): 4,0 us, 1,5 sy, 0,0 ni, 94,2 id, 0,0 wa, 0,0 hi, 0,3 si, 0,0 st

• %us показывает использование отдельного процессора (пользовательскими процессами, такими, как apache, mysql и т.д.) до максимального значения, составляющего 100%. Таким образом, если в четырехъядерном процессоре 1 процесс использует 100% CPU, это даст значение %us, равное 25%. Значение 12,5% для 8-ядерного процессора означает, что занято одно ядро.

• %sy означает использование CPU системой. Обычно это значение невысоко, высокие его значения могут свидетельствовать о проблеме с конфигами ядра, проблему со стороны драйвера, или целый ряд других вещей.

Как мне их достать из top или другого места с тем, чтобы записать в файл?

Хотел уже было вытащить us и sy из шапки top вот таким образом:

us=$(top -n 1 | grep Cpu | awk '{print $2}')
sy=$(top -n 1 | grep Cpu | awk '{print $4}')

Но решил проверить. Запустил «stress --cpu 4» на все ядра. И первая итерация top дает некорректное значения.

me@pc1:~$ top -n 1 | grep Cpu
%Cpu(s):  6,7 us,  3,3 sy,  0,0 ni, 89,5 id,  0,3 wa,  0,0 hi,  0,2 si,  0,0 st
me@pc1:~$ top -n 1 | grep Cpu
%Cpu(s):  6,7 us,  3,3 sy,  0,0 ni, 89,5 id,  0,3 wa,  0,0 hi,  0,2 si,  0,0 st
me@pc1:~$ top -n 1 | grep Cpu
%Cpu(s):  6,7 us,  3,3 sy,  0,0 ni, 89,4 id,  0,3 wa,  0,0 hi,  0,2 si,  0,0 st
me@pc1:~$ top -n 1 | grep Cpu
%Cpu(s):  6,7 us,  3,3 sy,  0,0 ni, 89,4 id,  0,3 wa,  0,0 hi,  0,2 si,  0,0 st
me@pc1:~$ top -n 4 | grep Cpu
%Cpu(s):  6,7 us,  3,3 sy,  0,0 ni, 89,4 id,  0,3 wa,  0,0 hi,  0,2 si,  0,0 st
%Cpu(s): 99,8 us,  0,2 sy,  0,0 ni,  0,0 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
%Cpu(s): 99,8 us,  0,2 sy,  0,0 ni,  0,0 id,  0,0 wa,  0,0 hi,  0,1 si,  0,0 st
%Cpu(s): 99,8 us,  0,2 sy,  0,0 ni,  0,0 id,  0,0 wa,  0,0 hi,  0,0 si,  0,0 st
GoKerze ()

Пока остановился на таком варианте. Жду от вас более изящное решение. (:

#!/bin/bash

# Header time pcpu us su
path="/root/mihPerfLog"

# $1 = pid $2 = file
function doNothing {

	timeData=$(date +%H:%M:%S)
	psData=$(ps -p $1 --no-headers -o pcpu)
	ussyData=$(top -n 2 -d 0,1 | grep Cpu | awk '{print $2,$4}' | tail -n 1)

	echo "$timeData $psData $ussyData" >> $2

}

for (( i=0; i <= 2880; i++ ))
do

	pid=2604
	file="$path/2008.txt"
	doNothing $pid $file

	pid=2605
	file="$path/2012.txt"
	doNothing $pid $file

	pid=2606
	file="$path/2016.txt"
	doNothing $pid $file

	sleep 4
	echo "Write to $path iteration $i"

done
GoKerze ()
Ответ на: комментарий от GoKerze

1. В строке top поля разделяются запятыми, пробелы там могут исчезнуть при 100%, grep и tail не нужны, если есть awk, ещё, ИМХО, лучше ставить LC_ALL=C и десятичную точну, чтобы не возникло проблем с десятичной запятой

top -n 2 -d 0.1 | awk -F':|,' '/Cpu/{a=$2" "$3}END{print a}'

более изящное

А с двумя циклами top вы ничего не сделает, на первом показывает как бы среднее с момента запуска системы значение. top проходит по данным всех процессов в /proc и суммирует их, хотите это реализовать скриптом? Точно изящнее не станет.

mky ★★★★★ ()
Последнее исправление: mky (всего исправлений: 1)
top -n 2 -d 0,1 | awk -F':|us,|sy,|ni,|id,' '/Cpu/{a=$2" "$3}END{print a}'

При таком подходе в файл пишется какой-то лютый в кавычках «UNICODE». Много символов. Но значащие цифры тоже есть. Хотя при выводе в терминал крокозябры выглядят как пробелы.

top -n 2 -d 0,1 | awk '/Cpu/{a=$2" "$4}END{print a}')

А во втором случае при 100% попадают в вывод не цифры, а подписи.

Ща посмотрим vmstat. Никогда им не пользовался. У него есть ключи, чтоб сразу us sy отдельно получить? (:

GoKerze ()
Ответ на: комментарий от GoKerze

top выводит «жирным» числа отображающие проценты. cat читает их жирными, а gedit не понимает разметки и пишет кракозябры. Есть способ упростить форматирование? (:

top -n 2 -d 0,1 | awk -F':|us,|sy,|ni,|id,' '/Cpu/{a=$2" "$3}END{print a}'
GoKerze ()
Ответ на: комментарий от Yorween

mpstat как и top при первом запуске показывает среднее значение жирности молока с 1 января 1970 года. mpstat не понимает задержки между итерациями менее секунды. Будем использовать его как лимитер вместо sleep.

#!/bin/bash

path="/root/log.txt"
echo "n time pcpu8 pcpu12 pcpu16 us su" >> $path

for (( i=0; i <= 14400; i++ ))
do

	#topData=$(top -n 2 -d 0,1 | awk -F':|us,|sy,|ni,|id,' '/Cpu/{a=$2" "$3}END{print a}')
	topData=$(mpstat 1 1 | awk '/all/ {a=$3" "$5}END{print a}')
	timeData=$(date +%H:%M:%S)

	pid=8210
	pcpu8=$(ps -p $pid --no-headers -o pcpu)

	pid=8211
	pcpu12=$(ps -p $pid --no-headers -o pcpu)

	pid=8212
	pcpu16=$(ps -p $pid --no-headers -o pcpu)

	echo "$i $timeData $pcpu8 $pcpu12 $pcpu16 $topData" >> $path

done
GoKerze ()

http://www.regatta.cs.msu.su/doc/usr/share/man/info/ru_RU/a_doc_lib/aixbman/p...

Применение команды ps
***
Значение %CPU указывает, какой процент процессорного времени был потрачен на выполнение процесса с момента его запуска.
Это значение подсчитывается по следующей формуле:

(время CPU, затраченное на выполнение процесса / время выполнения процесса) * 100

GoKerze ()

Потребление CPU процессами быстро меняется. Могут быть миллисекундные пики под 100% времени CPU, а между ними 100ms «тишины». Если мы своим измерятором будем попадать в «тихие» периоды, то никогда не узнаем, что процесс чем-то занимается.В любом случае, измерятор должен показывать среднее значение за человекоосознаваемый период.

GoKerze ()

Вытащил CPU из TOP. TOP выдает среднее за секунду сразу по трем PID. Парсю по команде запуска - там в моем случае есть ID. Однако! AWK по-разному нумерует колонки в зависимости от длины PID и погоды на Марсе. Не стал докапываться до истины, подогнал под свой случай.

#!/bin/bash

path="/root/mihPerfLog/log.txt"
echo "n time cpu8 mem8 cpu12 mem12 cpu16 mem16 %usr %sys %iowait %soft %quest %idle" >> $path

for (( i=0; i <= 14400; i++ ))
do
	mpstatData=$(mpstat 1 1 | awk '/all/ {a=$3" "$5" "$6" "$8" "$10" "$12}END{print a}')
	timeData=$(date +%H:%M:%S)
	topData=$(top -c -n 2 -d 1 -p 1331584 -p 1330208 -p 1330700 | awk '/instance-00000ad2/ {a=$9" "$10} /instance-00000ac8/ {b=$9" "$10} /instance-00000ac9/ {c=$9" "$10} END {print a,b,c}')

	echo "$i $timeData $topData $topData" >> $path
	echo "$i $timeData $topData $topData"

done

Таким образом мы приходим к выводу - надо более нормальный мониторинг. Какими-нибудь умными софтами.

GoKerze ()
Ответ на: комментарий от GoKerze

Держи порцию говн критики.

echo «n time cpu8 mem8 cpu12 mem12 cpu16 mem16 %usr %sys %iowait %soft %quest %idle» есть column

awk ‘/all/ {a=$3" «$5» «$6» «$8» «$10» "$12}END{print a}’ зачем лишний раз присваивать переменную, да еще и ДО END, если можно сделать END и вывод по столбцам

awk ‘/instance-00000ad2/ {a=$9" «$10} /instance-00000ac8/ {b=$9» «$10} /instance-00000ac9/ {c=$9» "$10} END {print a,b,c}’) тоже самое

Ну и в целом это откровенный говнокод. Все что тебе нужно - одна функция, вывод который ты будешь перенаправлять в файл. Это 6-7 простых строчек.

anonymous ()
Ответ на: комментарий от anonymous

echo «n time cpu8 mem8 cpu12 mem12 cpu16 mem16 %usr %sys %iowait %soft %quest %idle» есть column

Для чего есть? Чтобы что? Column осуществляет выравнивание уже существующей таблицы дабы ровно выглядела в консоли? Мне нужна таблица с элементами разделенными одним пробелом для вставки её в Excel.

awk ‘/all/ {a=$3" «$5» «$6» «$8» «$10» «$12}END{print a}’ зачем лишний раз присваивать переменную, да еще и ДО END, если можно сделать END и вывод по столбцам

Я AWK'ов не знаю. Нашел пример - адаптировал под себя. Как ты это видишь?

Все что тебе нужно - одна функция, вывод который ты будешь перенаправлять в файл.

Функция? Спрятать текущий говнокод под ковер в функцию? Инкапсуляция? (: Я не понял. Этот код никогда не будет переиспользоваться. Не нужно нам переиспользуемых документированных изящных функций.

GoKerze ()