pidstat - 行程(任務)資源統計

介紹


pidstat是Linux 裡面一套統計/監控目前被kernel所管理的任務(task)的軟體。使用前必須先掛載proc。主要有底下幾種方式顯示統計數據:

  1. 顯示區間和顯示筆數。
  2. 根據特定task為單位。
  3. 根據IO。
  4. 根據PID。
  5. CPU使用量。
  6. 分頁錯誤(page faults)和記憶體使用量(memory utilization)。
  7. 堆疊(stack utilization)。
  8. task切換分頁。

(這文章並不是在同一天,同一台主機內寫的,所以顯示數據的hostname, CPU,還有裡面的例子等等資訊可能會不太一樣,並且以下內容都是以版本11.2.0所撰寫)

語法


pidstat  [  -d ] [ -h ] [ -I ] [ -l ] [ -R ] [ -r ] [ -s ] [ -t ] [ -U [ username ] ] [ -u ] [ -V ] [ -v ] [ -w ] [ -C comm ] [ -G process_name ] [ -p { pid [,...] | SELF | ALL } ] [ -T { TASK | CHILD | ALL } ] [ interval [ count ] ]

安裝

Ubuntu

apt install sysstat

Redhat/CentOs

yum install sysstat

顯示區間和顯示筆數


習慣在linux上顯示統計數據的人就會知道,通常參數都會搭配兩個數字 -「interval」和「count」,來代表你多久要統計一次和總共要統計幾次,以下面的例子來說:

    pidstat -U -C pidstat 2 5

情境就是,我想要顯示在系統裡的task - pidstat的統計資料,每2秒統計1次,總共顯示5筆,並且把UID給置換成user name,數據顯示如下:

root@hugh-MS:/home/hugh# pidstat -U -C pidstat 2 5
Linux 4.4.0-45-generic (hugh-MS)     10/25/2016      _x86_64_        (1 CPU)

09:09:08 AM     USER       PID    %usr %system  %guest    %CPU   CPU  Command    
09:09:10 AM     USER       PID    %usr %system  %guest    %CPU   CPU  Command
09:09:12 AM     root      4097    0.00    0.50    0.00    0.50     0  pidstat
09:09:12 AM     USER       PID    %usr %system  %guest    %CPU   CPU  Command
09:09:14 AM     USER       PID    %usr %system  %guest    %CPU   CPU  Command
09:09:16 AM     root      4097    0.00    0.51    0.00    0.51     0  pidstat
09:09:16 AM     USER       PID    %usr %system  %guest    %CPU   CPU  Command
09:09:18 AM     root      4097    0.50    0.00    0.00    0.50     0  pidstat

Average:        USER       PID    %usr %system  %guest    %CPU   CPU  Command
Average:        root      4097    0.10    0.20    0.00    0.30     -  pidstat

上面可以很清楚的看到,只有三筆資料,而且前兩筆是分別花了0.50和0.52的system time,最後一筆花了0.50的user space time,最後還有全部的平均時間。

這邊要特別注意的是,如果沒有特別指定task,像是:

pidstat -U 2 5

這樣子的用法,它並不會顯示所有的Task,而是只會顯示在統計期間裡,有活動的所有task才會顯示。

如果不指定「interval」或是指定「0」的話,統計預設就會從系統開機就開始計算。

根據特定task為單位


Task name

pidstat -U -C bash

root@hugh-MS:/home/hugh# pidstat -U -C bash
Linux 4.4.0-45-generic (hugh-MS)         10/23/2016         _x86_64_        (8 CPU)

    05:10:32 PM     USER       PID    %usr %system  %guest    %CPU   CPU  Command
    05:10:32 PM     hugh      5834    0.00    0.00    0.00    0.00     4  bash
    05:10:32 PM     hugh      9384    0.00    0.00    0.00    0.00     5  bash
    05:10:32 PM     root      9402    0.00    0.00    0.00    0.00     1  bash

因為參數有加『-U』,所以顯示的是real user name 而不是預設的UID,在這個例子我想要看的是統計目前所有bash的CPU使用率,所以使用參數『-C』後面加task的名字。

底下簡單介紹一下欄位資訊:

第一行顯示的分別是『kernel版本資訊』,『hostname』,『今天日期』,『OS位元數』,『CPU數』。 第二行開始,第一,二,三欄分別是『統計的時間』,『啟動這個task的user name(如果沒有加-U的話就會變成顯示UID)』,『這個task的process ID』。接下來的欄位如下:

%usr

這個task在user level執行的CPU百分比,這個欄位並沒有紀錄包含跑虛擬處理器的時間。

%system

這個task在system level執行的CPU百分比。

%guest

這個task在虛擬機(虛擬處理器)上的CPU百分比。

%CPU

這個task的全部CPU時間,如果是在SMP的環境上,並且你有使用『-I』參數的話,這個task的CPU使用量將會被除以全部CPU的總數。

CPU

這個task總共用到幾個CPU。

顯示所有參數

有時候執行一個參數時,後面不同的參數也會造成不同的CPU使用率,所以如果你想要看每個task後面有什麼參數的話,可以加一個「-l」:

pidstat -U -C bash -l

複數特定task

如果是要顯示複數的task,就可以用底下的做法:

pidstat -C "fox|bird" -r -p ALL

Task id

如果想要根據pid來統計資料,可以針對底下這個語法:

pidstat -p {<pid>[,....] | SELF | ALL }

基本上

pidstat

pidstat -p ALL

pidstat -u

是同一件事,都是列出所有的task。 但是如果你要列出一些特定的pid的話,可以參考底下的例子:

pidstat -p 5834,9384,9402

就只會列出你想要看的資料:

    root@hugh-MS:/home/hugh# pidstat -p 5834,9384,9402
    Linux 4.4.0-45-generic (hugh-MS)         10/23/2016         _x86_64_        (8 CPU)

    08:53:30 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
    08:53:30 PM  1000      5834    0.00    0.00    0.00    0.00     4  bash
    08:53:30 PM  1000      9384    0.00    0.00    0.00    0.00     5  bash
    08:53:30 PM     0      9402    0.00    0.00    0.00    0.00     0  bash

顯示所有相關執行序(thread)和檔案描述子(file discription)的總數

下面這個例子會列出所有這個task所相關的執行序和檔案描述子(使用參數「-v」):

    root@hugh-MS:/home/hugh# pidstat -C sshd -v
    Linux 4.4.0-45-generic (hugh-MS)     10/25/2016      _x86_64_        (1 CPU)

    09:41:37 AM   UID       PID threads   fd-nr  Command
    09:41:37 AM     0       914       1       5  sshd
    09:41:37 AM     0      2897       1       8  sshd
    09:41:37 AM  1000      2931       1      12  sshd

以上面的例子,可以看到兩個欄位「threads」,「fd-nr」:

threads: 和這個task所繫結(associated)的所有執行緒總數。

fd-nr: 和這個task所繫結(associated)的所有檔案描述子總數。

子行程

pidstat [ -T { TASK | CHILD | ALL } ]

這個參數可以顯示更多子行程的資訊,但是只適用於『記憶體』和『CPU模式』,官方文件是稱作這個資料叫做『global statistics』,以下直接舉兩個例子來看:

    root@hugh-MS:/home/hugh# pidstat  -C bash -T TASK
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    10:33:04 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
    10:33:04 PM  1000      6104    0.00    0.00    0.00    0.00     5  bash
    10:33:04 PM     0      6724    0.00    0.00    0.00    0.00     5  bash


    root@hugh-MS:/home/hugh# pidstat  -C bash -T CHILD
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    10:33:07 PM   UID       PID    usr-ms system-ms  guest-ms  Command
    10:33:07 PM  1000      6104       410       100         0  bash
    10:33:07 PM     0      6724       170       160         0  bash


    root@hugh-MS:/home/hugh# pidstat  -C bash -T ALL
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    10:33:12 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
    10:33:12 PM  1000      6104    0.00    0.00    0.00    0.00     5  bash
    10:33:12 PM     0      6724    0.00    0.00    0.00    0.00     5  bash

    10:33:12 PM   UID       PID    usr-ms system-ms  guest-ms  Command
    10:33:12 PM  1000      6104       410       100         0  bash
    10:33:12 PM     0      6724       170       180         0  bash

上面可以清楚看到一樣是根據task - bash來列出CPU相關統計訊息,使用參數『-T TASK』時,輸出內容就跟沒有加一樣,所以代表預設本來就是有『-T TASK』,但是如果參數變成『-T CHILD』,你就會發現內容不太一樣了,不一樣的欄位解釋如下:

usr-ms

顯示這個Task和他的所有子行程在user level下所花費的時間(millisesonds),這個欄位並沒有包含在 虛擬機(Virtual machine)所處理的時間。

system-ms

同usr-ms,只是是統計system level底下的時間(millisesonds)。

guest-ms

同usr-ms,只是是統計Virtual machine底下的時間(millisesonds)。

而『-T ALL』則是同時顯示兩個『-T TASK + CHILD』。

上面的例子是說明『TASK』在CPU上面的顯示數據,下面的例子則是換個參數『-r』來看看記憶體的統計數據:

    root@hugh-MS:/home/hugh# pidstat  -C bash -r -T TASK
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    10:53:23 PM   UID       PID  minflt/s  majflt/s     VSZ     RSS   %MEM  Command
    10:53:23 PM  1000      6104      0.20      0.00   30244    5680   0.03  bash
    10:53:23 PM     0      6724      0.17      0.00   28680    4052   0.02  bash
    root@hugh-MS:/home/hugh# pidstat  -C bash -r -T CHILD
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    10:53:26 PM   UID       PID minflt-nr majflt-nr  Command
    10:53:26 PM  1000      6104     13867        47  bash
    10:53:26 PM     0      6724     14926         1  bash
    root@hugh-MS:/home/hugh# pidstat  -C bash -r -T ALL
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    10:53:29 PM   UID       PID  minflt/s  majflt/s     VSZ     RSS   %MEM  Command
    10:53:29 PM  1000      6104      0.20      0.00   30244    5680   0.03  bash
    10:53:29 PM     0      6724      0.18      0.00   28684    4056   0.02  bash

    10:53:29 PM   UID       PID minflt-nr majflt-nr  Command
    10:53:29 PM  1000      6104     13867        47  bash
    10:53:29 PM     0      6724     15176         1  bash

如同CPU一樣,只有在加了『-T CHILD』的資料會顯示出兩筆不一樣的數據:

minflt-nr

這個task和其子行程所造成的minor faults總數。

majflt-nr

這個task和其子行程所造成的major faults總數。

TID and TGID

如果想要看這個Task的TID和TGID可以用參數『-t』。

    root@hugh-MS:/home/hugh# pidstat -C bash -t 
    Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

    11:01:56 PM   UID      TGID       TID    %usr %system  %guest    %CPU   CPU  Command
    11:01:56 PM  1000      6104         -    0.00    0.00    0.00    0.00     5  bash
    11:01:56 PM  1000         -      6104    0.00    0.00    0.00    0.00     5  |__bash
    11:01:56 PM     0      6724         -    0.00    0.00    0.00    0.00     3  bash
    11:01:56 PM     0         -      6724    0.00    0.00    0.00    0.00     3  |__bash

Task切換分頁


根據記憶體管理的paging,每個process在執行過程中間,總是會有很多的context switch,這個參數就是主要統計這個部份,這個功能在kernel 2.6.23之後才支援。如下語法:

    pidstat -C sshd -w 


    root@hugh-MS:/home/hugh# pidstat -C sshd -w
    Linux 4.4.0-45-generic (hugh-MS)     10/25/2016      _x86_64_        (1 CPU)

    09:15:25 AM   UID       PID   cswch/s nvcswch/s  Command
    09:15:25 AM     0       914      0.02      0.01  sshd
    09:15:25 AM     0      2897      0.03      0.01  sshd
    09:15:25 AM  1000      2931      0.86      0.03  sshd

以上重複的欄位就不再追述,有差異的主要是兩個「cswch/s」,「nvcswch/s」

cswch/s:

每秒這個task所做的自主性(voluntary) context switch總數,通常一個自主性的context switch都是因為這個Task需要的資源無法取得,所以自動進入睡眠後等待再次進入排程,或是主動將資源讓給其他的process。

nvcswch/s:

每秒這個task所做的非自主性(non voluntary) context switch 總數,通常是這個task的time slice 已經用完了,所以被強制的context switch 給其他task使用。

根據IO


想要根據IO來顯示report的資料(kernel 2.6.20以後的版本才支援),可以使用底下語法:

pidstat -C bash -d

結果如底下所示:

    root@hugh-MS:/home/hugh# pidstat -C bash -d
    Linux 4.4.0-45-generic (hugh-MS)     10/25/2016      _x86_64_        (1 CPU)

    09:17:41 AM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
    09:17:41 AM  1000      1585      0.84      0.00      0.00      60  bash
    09:17:41 AM     0      1624     55.10     32.99      0.88       3  bash
    09:17:41 AM  1000      2932      0.10      0.00      0.00      15  bash
    09:17:41 AM     0      2962      2.51      0.00      0.00       5  bash

主要為三個欄位「KB_rd/s」,「KB_rd/s」,「KB_ccwr/s」:

KB_rd/s

每秒這個Task從disk所讀取的資料量,單位是kilobytes。

KB_wr/s

每秒這個Task所寫到disk的資料量,單位是kilobytes。

KB_ccwr/s

如果有資料要寫到disk裡,但是又被這個Task所取消的話,就會記錄到這邊。通常是這個task去truncate一些dirty的pagecache才會發生。

分頁錯誤(page faults)和記憶體使用量(memory utilization)


如果沒有特別加參數的話,通常這個指令會列出的是CPU使用量,但是如果你要看記憶體使用量就必須要另加參數「-r」,這個參數會顯示出所有分頁錯誤和記憶體使用量。

相關範例如下:

    root@hugh-MS:/home/hugh# pidstat  -r -C bash
    Linux 4.4.0-45-generic (hugh-MS)         10/23/2016         _x86_64_        (8 CPU)

    05:17:52 PM   UID       PID  minflt/s  majflt/s     VSZ     RSS   %MEM  Command
    05:17:52 PM  1000      5834      0.03      0.00   29984    5384   0.03  bash
    05:17:52 PM  1000      9384      0.03      0.00   29984    5328   0.03  bash
    05:17:52 PM     0      9402      0.04      0.00   28668    4016   0.02  bash

minflt/s

每秒這個task所造成的minor faults的總數,而且這些是在沒有從disk那邊讀取memory page的狀態下所統計的。

majflt/s

同上,只是是每秒的major faults。

VSZ

Virtual Size的縮寫,代表這整個task的虛擬記憶體使用量(單位為kilobytes)。

RSS

Resident Set Size的縮寫,這個task所使用的實際實體記憶體(單位為kilobytes)。

%MEM

這個task所使用的實體記憶體量。

堆疊(stack utilization)


每個process之中都會有規劃記憶體來當成stack,這部份博大精深,所以不在這邊介紹, pid的指令有辦法去看到系統分配給這個task的stack size和已經用了多少的size,只要如下面一樣, 加個『-s』 就好。

    root@hugh-MS:/home/hugh# pidstat -p 5834,9384,9402 -s
    Linux 4.4.0-45-generic (hugh-MS)         10/23/2016         _x86_64_        (8 CPU)

    09:24:15 PM   UID       PID StkSize  StkRef  Command
    09:24:15 PM  1000      5834     136      20  bash
    09:24:15 PM  1000      9384     136      20  bash
    09:24:15 PM     0      9402     136      24  bash


主要是兩個欄位:

### StkSize:
系統分配給這個process的保留stack,單位是kilobytes,但是不一定會使用到。

### StkRef:
這個task已經使用了多少的記憶體來當stack,單位一樣是kilobytes。


## Priority and scheduling policy
----------
列出排程的real priority 和其policy,這部份有興趣者,請參考Robert Love 的Linux Kernel Development 的章節 - Process Scheduling。
root@hugh-MS:/home/hugh# pidstat -C watchdog -R
Linux 4.4.0-45-generic (hugh-MS)         10/26/2016         _x86_64_        (8 CPU)

10:56:35 PM   UID       PID prio policy  Command
10:56:35 PM     0        10   99   FIFO  watchdog/0
10:56:35 PM     0        11   99   FIFO  watchdog/1
10:56:35 PM     0        16   99   FIFO  watchdog/2
10:56:35 PM     0        21   99   FIFO  watchdog/3
10:56:35 PM     0        26   99   FIFO  watchdog/4
10:56:35 PM     0        31   99   FIFO  watchdog/5
10:56:35 PM     0        36   99   FIFO  watchdog/6
10:56:35 PM     0        41   99   FIFO  watchdog/7

```

使用環境變數


pidstat這個指令因為會輸出一些時間數據,所以會用到『S_TIME_FORMAT』這個環境變數,如果這個變數不存在的話,就會直接抓『locale』底下的LC_TIME來用,但是如果有這個變數,而且也符合格式的話,就會忽略locale的資訊,直接採用ISO 8601的格式(YYYY-MM-DD)。

Ref


  1. man pidstat

results matching ""

    No results matching ""