Как отслеживать использование ЦП процесса с помощью PowerShell?
Я пытаюсь написать сценарий PowerShell для мониторинга использования % CPU процесса SQL Server. Я хотел бы записывать снимки этого числа каждый день, чтобы мы могли отслеживать его с течением времени и следить за тенденциями.
мои исследования в интернете сказали, что этот запрос WMI должен дать мне то, что я хочу:
Get-WmiObject -Query "SELECT PercentProcessorTime FROM win32_PerfFormattedData_PerfProc_Process WHERE Name='SqlServr'"
когда я запускаю запрос WMI, я обычно получаю значение где-то между 30-50%
однако, когда я наблюдаю за процессом в Resource Monitor, он обычно усредняется на менее 1% использования ЦП
Я знаю, что запрос WMI просто возвращает снимок использования ЦП, а не среднее значение в течение длительного периода времени, поэтому я знаю, что они напрямую не сопоставимы. Тем не менее, я думаю, что снимок обычно должен быть меньше 1%, так как среднее значение монитора ресурсов меньше 1%.
3 ответов
все, что я узнал о WMI и счетчиках производительности за последние пару дней.
WMI означает инструментарий управления Windows. WMI-это набор классов, зарегистрированных в системе WMI и подсистеме Windows COM. Эти классы известны как поставщики и имеют любое количество открытых свойств, возвращающих динамические данные при запросе.
Windows поставляется с предустановленным большим количеством поставщиков WMI, которые дают вам информацию о среда Windows. Для этого вопроса нас интересует Win32_PerfRawData* поставщики и две обертки, которые строятся из него.
при запросе любой Win32_PerfRawData* провайдер сразу вы заметите, что цифры его возвращение страшно смотреть. Это потому, что эти поставщики дают необработанные данные, которые вы можете использовать для вычисления того, что вы хотите.
чтобы упростить работу с поставщиками Win32_PerfRawData * Microsoft предоставила две оболочки, которые возвращайте более приятные ответы при запросе, perfmon и win32_perfformatteddata* провайдеров.
Ok, Итак, как мы получаем % загрузки процессора процесса? У нас есть три варианта:
- получите красиво отформатированный номер от поставщика Win32_PerfFormattedData_PerfProc_process
- получить красиво отформатированный номер от PerfMon
- рассчитать % загрузки процессора для себя с помощью Win32_PerfRawData_PerfProc_Process
мы увидим что есть ошибка с вариантом 1, так что он не работает во всех случаях, хотя это ответ, обычно данный в интернете.
Если вы хотите получить это значение из Win32_PerfFormattedData_PerfProc_process вы можете использовать запрос, упомянутый в вопросе. Это даст вам сумму значения PercentProcessorTime для всех потоков этого процесса. Проблема в том, что эта сумма может быть >100, если существует более 1 ядра, но это свойство максимизируется на 100. Так, покуда сумма всех потоков этого процесса меньше 100 вы можете получить ответ, разделив свойство percentprocessortime процесса на количество ядер машины.
Если вы хотите получить это значение от PerfMon в PowerShell, вы можете использовать Get-Counter "\Process(SqlServr)\% Processor Time"
. Это вернет число между 0 - (CoreCount * 100).
Если вы хотите вычислить это значение для себя, свойство PercentProcessorTime поставщика Win32_PerfRawData_PerfProc_Process возвращает время процессора это процесс использовал. Итак, вам нужно сделать два снимка, мы назовем их s1 и s2. Затем мы сделаем (s2.PercentProcessorTime-s1.PercentProcessorTime) / (s2.TimeStamp_Sys100NS-s1.TimeStamp_Sys100NS).
и это последнее слово. Надеюсь, это вам поможет.
ваша гипотеза почти верна. Один нить (и процесс всегда будет иметь хотя бы один поток) может иметь не более 100% для PercentProcessorTime
но:
- процесс может иметь несколько потоков.
- система может иметь несколько (логических) ядра процессора.
следовательно, здесь (процессор Intel i7 с hyperthreading on) у меня есть 8 логических ядер, а верхние 20 потоков (фильтрация итогов) показывает (с небольшой уборкой, чтобы сделать это читаемый):
PS > gwmi Win32_PerfFormattedData_PerfProc_Thread | ?{$_.Name -notmatch '_Total'} | sort PercentProcessorTime -desc | select -first 20 | ft -auto Name,IDProcess,IDThread,PercentProcessorTime Name IDProcess IDThread PercentProcessorTime ---- --------- -------- -------------------- Idle/6 0 0 100 Idle/3 0 0 100 Idle/5 0 0 100 Idle/1 0 0 100 Idle/7 0 0 96 Idle/4 0 0 96 Idle/0 0 0 86 Idle/2 0 0 68 WmiPrvSE/7#1 7420 6548 43 dwm/4 2260 6776 7 mstsc/2#1 3444 2416 3 powershell/7#2 6352 6552 0 conhost/0#2 6360 6368 0 powershell/5#2 6352 6416 0 powershell/6#2 6352 6420 0 iexplore/7#1 4560 3300 0 Foxit Reader/1 736 5304 0 Foxit Reader/2 736 6252 0 conhost/1#2 6360 1508 0 Foxit Reader/0 736 6164 0
все это должно составлять около 800 для последнего столбца.
но обратите внимание, что все это округлено до целых чисел. Сравните со столбцом CPU Process Explorer (который не округляется, когда выбран просмотр | отображение дробного процессора) в течение нескольких процессов. Обратите внимание, как win32_PerfFormattedData_PerfProc_Process
процентное значение нормализуется для основного количества (и это только часть дисплея):
много процессов через несколько сотен тысяч циклов, но не настолько, чтобы округлить до одного процента.
ты пробовал Get-Counter
?
PS PS:\> Get-Counter "\Processus(iexplor*)\% temps processeur"
Timestamp CounterSamples
--------- --------------
17/07/2012 22:39:25 \jpbhpp2\processus(iexplore#8)\% temps processeur :
1,5568026751287
\jpbhpp2\processus(iexplore#7)\% temps processeur :
4,6704080253861
\jpbhpp2\processus(iexplore#6)\% temps processeur :
0
\jpbhpp2\processus(iexplore#5)\% temps processeur :
4,6704080253861
\jpbhpp2\processus(iexplore#4)\% temps processeur :
0
\jpbhpp2\processus(iexplore#3)\% temps processeur :
0
\jpbhpp2\processus(iexplore#2)\% temps processeur :
0
\jpbhpp2\processus(iexplore#1)\% temps processeur :
1,5568026751287
\jpbhpp2\processus(iexplore)\% temps processeur :
0
будьте осторожны, это зависит от вас locale test:
PS PS:\> Get-Counter -ListSet * | where {$_.CounterSetName -contains "processus"}