監視Linux服務器的性能

重要性能監測工具:top、vmstat、w、uptime、ps、free、iostat、netstat、/proc等

需要監視Linux服務器的性能?大多數Linux發行版都集成了一些監視工具。這些工具可以獲取有關係統活動的信息的詳細指標。通過這些工具,你可以發現產生系統性能問題可能存在原因。下面討論的是一些最基本的命令,它涉及到系統分析和調試服務器等一些問題,如:
1.    找出系統瓶頸問題.
2.    磁盤 (儲存) 瓶頸問題.
3.    CPU和內存瓶頸問題.
4.    網絡瓶頸問題.
# 1: top – 查看活動進程的命令########################################

TOP工具能夠實時顯示系統中各個進程的資源佔用狀況。默認情況下,它將顯示系統中CPU最“敏感”的任務列表.該命令可以按CPU/內存的使用情況和執行時間對任務進行排序,並每五秒鐘更新一次。

wKiom1ZmSIGDxVuKAAAzdkYSpFw715.png

常用的快捷鍵

Top命令爲我們提供了很多有用的快捷鍵,如:

快捷鍵    用法

t           切換顯示進程和CPU狀態信息。

m           切換顯示進程和CPU狀態信息。

A           分類顯示各種系統資源的消耗情況。可用於快速識別系統的性能要求極高的任務。

o           改變顯示項目的順序。

r     重新設置進程的優先級別。(系統提示用戶輸入需要改變的進程PID以及需要設置的優先級值。)

k            終止一個進程。(系統將提示用戶輸入需要終止的進程PID)

s            改變刷新的時間間隔。

u            查看指定用戶的進程。


# 2: vmstat – 系統活動、硬件以及系統信息
這個命令用來報告關於內核線程、虛擬內存、磁盤、陷阱和CPU活動的統計信息。

1
2
3
4
5
6
7
8
9
10
11
# vmstat 3                                                           
輸出樣例:
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------           
r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st            
0  0      0 2540988 522188 5130400    0    0     2    32    4    2  4  1 96  0  0          
1  0      0 2540988 522188 5130400    0    0     0   720 1199  665  1  0 99  0  0          
0  0      0 2540956 522188 5130400    0    0     0     0 1151 1569  4  1 95  0  0          
0  0      0 2540956 522188 5130500    0    0     0     6 1117  439  1  0 99  0  0          
0  0      0 2540940 522188 5130512    0    0     0   536 1189  932  1  0 98  0  0          
0  0      0 2538444 522188 5130588    0    0     0     0 1187 1417  4  1 96  0  0          
0  0      0 2490060 522188 5130640    0    0     0    18 1253 1123  5  1 94  0  0

顯示內存使用情況:
# vmstat –m 

# 3: w – 找到已登陸的用戶並且查看他們做了什麼操作
W命令用來顯示機器上最近登陸的用戶信息以及他們的進程信息。

wKioL1ZmSbiAgiptAAARXC22ARE016.png

# 4: uptime – 系統已運行的時間
Uptime命令可以查看系統已經運行了多長時間。截止當前時間日期,系統已經運行了多長時間,當前登錄的用戶有哪些,已經在過去的1,5,15分鐘,系統的平均負載值情況。

1
2
# uptime                                                             
18:02:41 up 41 days, 23:42,  1 user,  load average: 0.00, 0.00, 0.00

通常被認爲是最佳的負載值。系統負載值根據系統的不同而不同。對於單CPU的系統,負載值在1-3爲正常,SMP的系統,負載值在6-10之間也是可以接受的。

# 5: ps – 顯示進程
ps命令用來報告當前進程的快照。要選擇所有進程,使用-ef選項:

wKioL1ZmSm6T-YYaAAAtIpxeHpk719.png

只顯示lighttpd的進程樹:
# pgrep lighttpd                                                  
Or
# pgrep -u vivek php-cgi                                          
顯示pid爲55977的進程名:

# ps -p 55977 -o comm=   
                                         
找出最耗費內存的前10個進程:

# ps -auxf | sort -nr -k 4 | head -10                             
找出最耗費CPU的前10個進程:

# ps -auxf | sort -nr -k 3 | head -10

# 6: free – 查看內存的使用情況
free指令會顯示內存的使用情況,包括實體內存,虛擬的交換文件內存,共享內存區段,以及系統核心使用的緩衝區.

wKioL1ZmSxyw8XcvAAAKlZK6QaI294.png

free的輸出一共有四行,第四行爲交換區的信息,分別是交換的總量(total),使用量(used)和有多少空閒的交換區(free)。
第二行和第三行是比較讓人迷惑的。這兩行都是說明內存使用情況的。第一列是總量(total),第二列是使用量(used),第三列是可用量(free)。第一行的輸出時從操作系統(OS)來看的。

# 7: iostat – 監視CPU平均負載值,I/O狀態
該命令用於報告CPU和輸入/輸出設備,分區和網絡文件系統(NFS)的詳細統計數據。

wKiom1ZmS2Xyc14KAAASBH4v89A694.png

基本使用如下:

wKiom1ZmS7XjBcaUAAAetLrPGig481.png

參數 -d 表示,顯示設備(磁盤)使用狀態;-k某些使用block爲單位的列強制使用Kilobytes爲單位;1 10表示,數據顯示每隔1秒刷新一次,共顯示10次。

# 8: mpstat – 實時系統監視工具

mpstat是MultiProcessor Statistics的縮寫,是實時系統監控工具。其報告與CPU的一些統計信息,這些信息存放在/proc/stat文件中。在多CPUs系統裏,其不但能查看所有CPU的平均狀況信息,而且能夠查看特定CPU的信息。

下面只介紹mpstat與CPU相關的參數,mpstat的語法如下:

Usage: mpstat [ options... ] [ <interval> [ <count> ] ]           

Options are:                                                  

[ -P { <cpu> | ALL } ] [ -V ]                                     

顯示每個進程對CPU的平均利用率:

# mpstat -P ALL

wKiom1ZmTFjguzluAAAawSA15bk972.png

#9: pmap – 查看進程使用內存的情況

pmap命令用來報告進程使用對於的相應內存的情況。使用下面命令可以查出某些內存瓶頸問題的原因。

# pmap -d PID                           

顯示進程號爲47394的進程所用內存的信息,最後一行非常重要。

# pmap -d 47394  

wKioL1ZmTbGxyNimAABUv5MOo2Y482.png#11 & #12 : netstat 和 ss – 查看網絡情況

netstat命令顯示網絡連接,路由表,網絡接口統計,僞裝連接,組播成員身份。ss命令類似netstat命令的信息。            

#13: iptraf – 實時網絡狀況監視工具

iptraf是一款彩色的交互式的IP局域網監控工具。這是一個基於ncurses的IP LAN監視工具,它會統計網絡中產生的各種數據,包括TCP信息,UDP連接數,ICMP和OSPF信息,以太網負載信息,節點統計,IP校驗和錯誤,以及其他信息。並且提供:

Network traffic statistics by TCP connection

IP traffic statistics by network interface

Network traffic statistics by protocol

Network traffic statistics by TCP/UDP port and by packet size

Network traffic statistics by Layer2 address

#14: tcpdump – 網絡狀況分析工具

tcpdump用來抓包的一個的簡單命令。但是,要使用該工具,你需熟悉TCP /IP協議。例如:顯示網絡中有關DNS的信息,請輸入:

# tcpdump -i eth1 'udp port 53'     

                                   

顯示去往202.54.1.5的所有ftp會話信息:

# tcpdump -i eth1 'dst 202.54.1.5 and (port 21 or 20'   


顯示去往192.168.1.5的所有HTTP會話信息:

# tcpdump -ni eth0 'dst 192.168.1.5 and tcp and port http'                


使用Wireshark查看tcpdump抓包文件的詳細信息,輸入:

# tcpdump -n -i eth1 -s 0 -w output.txt src or dst port 80  

#15: strace – 系統調用工具

strace是Linux環境下的一款程序調試工具,用來監察一個應用程序所使用的系統呼叫及它所接收的系統信息。strace是一個有用的小工具,它可以通過跟蹤系統調用來讓你知道一個程序在後臺所做的事情。Strace是一個基礎的調試工具,在大多數 Linux系 統上默認已經安裝;但是即便你不是在跟蹤一個問題的時候它也是一個極好的軟件。它能告訴你很多關於一個Linux程序怎樣工作的信息。

#16: /Proc 文件系統
Linux 內核提供了一種通過 /proc 文件系統,在運行時訪問內核內部數據結構、改變內核設置的機制。幾個例子:

# cat /proc/cpuinfo                                                

# cat /proc/meminfo                                                

# cat /proc/zoneinfo                   

# cat /proc/mounts  

#17: Nagios – 服務器和網絡信息監視工具
Nagios是一款很流行的開源系統和網絡監控應用軟件。你可以很輕鬆地用它監控所有的主機,網絡設備和服務。在系統或服務狀態異常時會第一時間通知網站運維人員(發出郵件或短信報警),在狀態恢復正常後發出郵件或短信通知。
#18: Cacti -基於WEB的監視工具
Cacti是通過 snmpget來獲取數據,使用 RRDtool繪畫圖形,而且你完全可以不需要了解RRDtool複雜的參數。它提供了非常強大的數據和用戶管理功能,可以指定每一個用戶能查看樹狀結構、host以及任何一張圖,還可以與LDAP結合進行用戶驗證,同時也能自己增加模板,功能非常強大完善。界面友好。CACTI軟件Cacti 的發展是基於讓 RRDTool 使用者更方便使用該軟件,除了基本的 Snmp 流量跟系統資訊監控外,Cacti 也可外掛 Scripts 及加上 Templates 來作出各式各樣的監控圖。
#19: KDE System Guard – 圖形化的系統監視工具
KDE System Guard (KSysguard)是KDE的任務管理和性能監控工具。它採用client/server架構,可以監控本機也可以監控遠端主機。
一篇51CTOblog博文,對KDE System Guard的介紹很詳細:http://linuxshow.blog.51cto.com/1572053/371657 

#sar - 收集和報告系統狀態信息

使用 sar -d 可以得到當天磁盤活動的情況彙總

sar -n  DEV 則能給出網絡接口的統計信息

sar -A 可以報告所有的信息

sar 適用於快速粗略瞭解歷史信息。

sar 命令行的常用格式: sar [options] [-o file] t [n]

options 爲命令行選項,sar命令的選項很多,下面只列出常用選項: 

-A:所有報告的總和。        

-u:CPU利用率        

-v:進程、I節點、文件和鎖表狀態。        

-d:硬盤使用報告。        

-r:沒有使用的內存頁面和硬盤塊。        

-g:串口I/O的情況。 

-b:緩衝區使用情況。 

-a:文件讀寫情況。 

-c:系統調用情況。 

-R:進程的活動情況。 

-y:終端設備活動情況。 

-w:系統交換活動。 

可以參考http://linuxtools-rst.readthedocs.org/zh_CN/latest/tool/sar.html 


其他工具:

nmap – 掃描主機的端口開放情況.

lsof - 列出系統當前打開的文件,網絡連接以及更多信息。

ntop web based tool – Ntop是一款監控網絡流量工具,它顯示的網絡狀況更加直觀、詳細。Ntop甚至可以列出每個節點計算機的網絡帶寬利用率。它是一個靈活的、功能齊全的,用來監控和解決局域網問題的工具;可以自動從網絡中識別有用的信息;將截獲的數據包轉換成易於識別的格式;對網絡環境中通信失敗的情況進行分析;探測網絡通信的時間和過程等。

Conky - Conky是x-window下,一款免費的,輕量級系統監控的工具。它能夠監控許多系統環境的狀態,其中包括的CPU,內存,交換空間,磁盤存儲,溫度,進程,網絡接口,電池電量,系統消息,電子郵件收件箱等。

GKrellM – 它來用於監測CPU狀態,內存,硬盤,網絡接口,本地和遠程郵箱,以及其他的東西等。

vnstat – vnstat是一個基於控制檯的網絡流量監控軟件,它會保持每月,每天,每小時,監視並記錄所選定網絡接口的網絡通信狀況。

htop – htop是一個增強版本的top,同時也是一個交互式進程查看器,它可以以樹狀結構來顯示進程列表。

mtr – mtr在單一的網絡診斷工具上,結合了traceroute和ping程序的功能。






性能監控腳本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[root@testredis scripts]# cat performance.sh 
#!/bin/bash
 
#監控cpu系統負載
IP=`ifconfig eth0 | grep "inet addr" cut -f 2 -d ":" cut -f 1 -d " "
cpu_num=`grep -c 'model name' /proc/cpuinfo`
count_uptime=`uptime |wc -w`
load_15=`uptime | awk '{print $'$count_uptime'}'`
average_load=`echo "scale=2;a=$load_15/$cpu_num;if(length(a)==scale(a)) print 0;print a" bc`  
average_int=`echo $average_load | cut -f 1 -d "."`  
load_warn=0.70  
if [ $average_int -gt 0 ]
then
echo "$IP服務器單個核心15分鐘的平均負載爲$average_load,超過警戒值1.0,請立即處理!!!$(date +%Y%m%d/%H:%M:%S)" >>/usr/monitor/performance/performance_$(date +%Y%m%d).log
echo "$IP服務器單個核心15分鐘的平均負載爲$average_load,超過警戒值1.0,請立即處理!!!$(date +%Y%m%d/%H:%M:%S)" | mail -s "$IP服務器系統負載嚴重告警" [email protected] 
else
echo "$IP服務器單個核心15分鐘的平均負載值爲$average_load,負載正常   $(date +%Y%m%d/%H:%M:%S)">>/usr/monitor/performance/performance_$(date +%Y%m%d).log
fi
 
#監控cpu使用率
cpu_idle=`top -b -n 1 | grep Cpu | awk '{print $5}' cut -f 1 -d "."`  
if [ $cpu_idle -lt 20 ]
then
 
echo "$IP服務器cpu剩餘$cpu_idle%,使用率已經超過80%,請及時處理。">>/usr/monitor/performance/performance_$(date +%Y%m%d).log
 
echo "$IP服務器cpu剩餘$cpu_idle%,使用率已經超過80%,請及時處理!!!" | mail -s "$IP服務器cpu告警" [email protected] 
else
 
echo
"$IP服務器cpu剩餘$cpu_idle%,使用率正常">>/usr/monitor/performance/performance_$(date +%Y%m%d).log
fi

進程監控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[root@testredis scripts]# cat process.sh 
#!/bin/bash
IP=`ifconfig eth0 | grep "inet addr" cut -f 2 -d ":" cut -f 1 -d " "`
 
tomcat_dir="/opt/apache-tomcat-7.0.8"
mysql_dir="/usr/local/mysql/bin/mysqld_safe"
vsftp_dir="/usr/sbin/vsftpd"
ssh_dir="/usr/sbin/sshd"
 
for dir in $tomcat_dir $mysql_dir $vsftp_dir  $ssh_dir 
do
process_count=$(ps -ef | grep "$dir" grep -v grep wc -l)
 
        for service in tomcat mysql vsftp ssh 
        do
                echo "$dir" |grep -q "$service"
                if [ $? -eq 0 ]
                then
                        if [ $process_count -eq 0 ]
                        then
                            echo "$service is down at $(date +%Y%m%d%H:%M:%S)" >>/usr/monitor/process/process_$(date +%Y%m%d).log
                            echo "$service is down at $(date +%Y%m%d%H:%M:%S)" | mail -s "$IP服務器 $service服務關閉告警" [email protected] 
                        else
                            echo "$service is running at $(date +%Y%m%d%H:%M:%S)" >>/usr/monitor/process/process_$(date +%Y%m%d).log
                        fi
                else
                        continue
                fi
        done
done

流量監控

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
#
R1=`cat /sys/class/net/eth0/statistics/rx_bytes`
T1=`cat /sys/class/net/eth0/statistics/tx_bytes`
sleep 1
R2=`cat /sys/class/net/eth0/statistics/rx_bytes`
T2=`cat /sys/class/net/eth0/statistics/tx_bytes`
TBPS=`expr $T2 - $T1`
RBPS=`expr $R2 - $R1`
TKBPS=`expr $TBPS / 1024`
RKBPS=`expr $RBPS / 1024`
echo "上傳速率 eth0: $TKBPS kb/s 下載速率 eth0: $RKBPS kb/s at $(date +%Y%m%d%H:%M:%S)" >>/usr/monitor/network/network_$(date +%Y%m%d).log

流量分析統計

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@testredis scripts]# cat tongji.sh 
#!/bin/bash
TX=0;
RX=0;
MAX_TX=0;
MAX_RX=0;
while read line
do
        a=`echo $line | grep "eth0" |awk '{print $3}'`
if [ $a -ge 0 ]
then
        TX=$a
        if [ $TX -ge $MAX_TX ]
        then
                MAX_TX=$TX
        fi
fi
        b=`echo $line | grep "eth0" |awk '{print $7}'`
if [ $b -ge 0 ]
then
        RX=$b
        if [ $RX -ge $MAX_RX ]
        then
                MAX_RX=$RX
        fi
fi
done /usr/monitor/network/network_$(date +%Y%m%d).log 
echo "最高上傳速度爲 $MAX_TX kb/s at $(date +%Y%m%d)">>/usr/monitor/network/tongji.log
echo "最高下載速度爲 $MAX_RX kb/s at $(date +%Y%m%d)">>/usr/monitor/network/tongji.log

內存硬盤登錄用戶數監控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
[root@Test scripts]# cat sys-warning.sh 
#!/bin/bash
#監控系統負載與CPU、內存、硬盤、登錄用戶數,超出警戒值則發郵件告警。
 
#提取本服務器的IP地址信息
IP=`ifconfig eth0 | grep "inter addr" cut -f 2 -d ":" cut -f 1 -d " "`
 
 
 
# 1、監控系統負載的變化情況,超出時發郵件告警:
 
#抓取cpu的總核數
cpu_num=`cat /proc/cpuinfo grep -c "model name"`
 
#抓取當前系統15分鐘的平均負載值
load_15=`uptime | awk '{print $12}'`
 
#計算當前系統單個核心15分鐘的平均負載值,結果小於1.0時前面個位數補0。
average_load=`echo "scale=2;a=$load_15/$cpu_num;if(length(a)==scale(a)) print 0;print a" bc`
 
#取上面平均負載值的個位整數
average_int=`echo $average_load | cut -f 1 -d "."`
 
#設置系統單個核心15分鐘的平均負載的告警值爲0.70(即使用超過70%的時候告警)。
load_warn=0.70
 
#當單個核心15分鐘的平均負載值大於等於1.0(即個位整數大於0) ,直接發郵件告警;如果小於1.0則進行二次比較
if [ $average_int > 0 ]; then
echo "$IP服務器單個核心15分鐘的系統平均負載爲$average_load,超過警戒值1.0,請立即處理." | mutt -s "$IP 服務器系統負載嚴重告警." [email protected]
else
 
#當前系統15分鐘平均負載值與告警值進行比較(當大於告警值0.70時會返回1,小於時會返回0)
load_now=`expr $average_load \> $load_warn`
 
#如果系統單個核心15分鐘的平均負載值大於告警值0.70(返回值爲1),則發郵件給管理員
if [ $load_now == 1 ]; then
echo "$IP服務器單個核心15分鐘的系統平均負載爲$average_load,超過警戒值0.70,請及時處理." | mutt -s "$IP 服務器系統負載告警" [email protected]
fi
fi
 
 
 
 
# 2、監控系統cpu的情況,當使用超過80%的時候發告警郵件:
 
#取當前空閒cpu百份比值(只取整數部分)
cpu_idle=`top -b -n 1 | grep Cpu | awk '{print $5}' cut -f 1 -d "."`
 
#設置空閒cpu的告警值爲20%,如果當前cpu使用超過80%(即剩餘小於20%),立即發郵件告警
if (($cpu_idle < 20)); then
echo "$IP服務器cpu剩餘$cpu_idle%,使用率已經超過80%,請及時處理。" | mutt -s "$IP服務器CPU告警" [email protected]
fi
 
 
 
 
 
# 3、監控系統交換分區swap的情況,當使用超過80%的時候發告警郵件:
 
#系統分配的交換分區總量
swap_total=`free -m | grep Swap | awk '{print $2}'`
 
#當前剩餘的交換分區free大小
swap_free=`free -m | grep Swap | awk '{print $4}'`
 
#當前已使用的交換分區used大小
swap_used=`free -m | grep Swap | awk '{print $3}'`
 
if (($swap_used != 0)); then
#如果交換分區已被使用,則計算當前剩餘交換分區free所佔總量的百分比,用小數來表示,要在小數點前面補一個整數位0
swap_per=0`echo "scale=2;$swap_free/$swap_total" bc`
 
#設置交換分區的告警值爲20%(即使用超過80%的時候告警)。
swap_warn=0.20
 
#當前剩餘交換分區百分比與告警值進行比較(當大於告警值(即剩餘20%以上)時會返回1,小於(即剩餘不足20%)時會返回0 )
swap_now=`expr $swap_per \> $swap_warn`
 
#如果當前交換分區使用超過80%(即剩餘小於20%,上面的返回值等於0),立即發郵件告警
if (($swap_now == 0)); then
echo "$IP服務器swap交換分區只剩下 $swap_free M 未使用,剩餘不足20%,使用率已經超過80%,請及時處理。" | mutt -s "$IP 服務器內存告警" [email protected]
fi
fi
 
 
 
 
# 4、監控系統硬盤根分區使用的情況,當使用超過80%的時候發告警郵件:
 
#取當前根分區(/dev/sda3)已用的百份比值(只取整數部分)
disk_sda3=`df -h | grep /dev/sda3 awk '{print $5}' cut -f 1 -d "%"`
 
#設置空閒硬盤容量的告警值爲80%,如果當前硬盤使用超過80%,立即發郵件告警
if (($disk_sda3 > 80)); then
echo "$IP 服務器 /根分區 使用率已經超過80%,請及時處理." | mutt -s "$IP 服務器硬盤告警" [email protected]
fi
 
 
 
 
 
#5、監控系統用戶登錄的情況,當用戶數超過3個的時候發告警郵件:
 
#取當前用戶登錄數(只取數值部分)
users=`uptime | awk '{print $6}'`
 
#設置登錄用戶數的告警值爲3個,如果當前用戶數超過3個,立即發郵件告警
if (($users >= 3)); then
echo "$IP 服務器用戶數已經達到$users個,請及時處理。" | mutt -s "$IP 服務器用戶數告警" [email protected]
fi



系統初始化腳本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
[root@Test scripts]# cat check_linux.sh 
#!/bin/bash
 
os_check() {
        if [ -e /etc/redhat-release ]; then
                REDHAT=`cat /etc/redhat-release |cut -d' '  -f1`
        else
                DEBIAN=`cat /etc/issue |cut -d' ' -f1`
        fi
 
        if "$REDHAT" == "CentOS" -o "$REDHAT" == "Red" ]; then
                P_M=yum
        elif "$DEBIAN" == "Ubuntu" -o "$DEBIAN" == "ubutnu" ]; then
                P_M=apt-get
        else
                Operating system does not support.
                exit 1
        fi
}
 
if [ $LOGNAME != root ]; then
    echo "Please use the root account operation."
    exit 1
fi
 
if which vmstat &>/dev/nullthen
        echo "vmstat command not found, now the install."
        sleep 1
        os_check
        $P_M install procps -y
        echo "-----------------------------------------------------------------------"
fi
 
if which iostat &>/dev/nullthen
        echo "iostat command not found, now the install."
        sleep 1
        os_check
        $P_M install sysstat -y
        echo "-----------------------------------------------------------------------"
fi
 
  
 
while truedo
    select input in cpu_load disk_load disk_use disk_inode mem_use tcp_status cpu_top10 mem_top10 traffic quit; do
        case $input in
            cpu_load)
                #CPU利用率與負載
                echo "---------------------------------------"
                i=1
                while [[ $i -le 3 ]]; do
                    echo -e "\033[32m  參考值${i}\033[0m"
                    UTIL=`vmstat |awk '{if(NR==3)print 100-$15"%"}'`
                    USER=`vmstat |awk '{if(NR==3)print $13"%"}'`
                    SYS=`vmstat |awk '{if(NR==3)print $14"%"}'`
                    IOWAIT=`vmstat |awk '{if(NR==3)print $16"%"}'`
                    echo "Util: $UTIL"
                    echo "User use: $USER"
                    echo "System use: $SYS"
                    echo "I/O wait: $IOWAIT"
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
 
            disk_load)
                #硬盤I/O負載
                echo "---------------------------------------"
                i=1
                while [[ $i -le 3 ]]; do
                    echo -e "\033[32m  參考值${i}\033[0m"
                    UTIL=`iostat -x -k |awk '/^[v|s]/{OFS=": ";print $1,$NF"%"}'`
                    READ=`iostat -x -k |awk '/^[v|s]/{OFS=": ";print $1,$6"KB"}'`
                    WRITE=`iostat -x -k |awk '/^[v|s]/{OFS=": ";print $1,$7"KB"}'`
                    IOWAIT=`vmstat |awk '{if(NR==3)print $16"%"}'`
                    echo -e "Util:"
                    echo -e "${UTIL}"
                    echo -e "I/O Wait: $IOWAIT"
                    echo -e "Read/s:\n$READ"
                    echo -e "Write/s:\n$WRITE"
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
 
            disk_use)
                #硬盤利用率
                DISK_LOG=/tmp/disk_use.tmp
                DISK_TOTAL=`fdisk -l |awk '/^Disk.*bytes/&&/\/dev/{printf $2" ";printf "%d",$3;print "GB"}'`
                USE_RATE=`df -h |awk '/^\/dev/{print int($5)}'`
                for in $USE_RATE; do
                    if [ $i -gt 90 ];then
                        PART=`df -h |awk '{if(int($5)=='''$i''') print $6}'`
                        echo "$PART = ${i}%" >> $DISK_LOG
                    fi
                done
                echo "---------------------------------------"
                echo -e "Disk total:\n${DISK_TOTAL}"
                if [ -f $DISK_LOG ]; then
                    echo "---------------------------------------"
                    cat $DISK_LOG
                    echo "---------------------------------------"
                    rm -f $DISK_LOG
                else
                    echo "---------------------------------------"
                    echo "Disk use rate no than 90% of the partition."
                    echo "---------------------------------------"
                fi
                break
                ;;
 
            disk_inode)
                #硬盤inode利用率
                INODE_LOG=/tmp/inode_use.tmp
                INODE_USE=`df -i |awk '/^\/dev/{print int($5)}'`
                for in $INODE_USE; do
                    if [ $i -gt 90 ]; then
                        PART=`df -h |awk '{if(int($5)=='''$i''') print $6}'`
                        echo "$PART = ${i}%" >> $INODE_LOG
                    fi
                done
                if [ -f $INODE_LOG ]; then
                    echo "---------------------------------------"
                    rm -f $INODE_LOG
                else
                    echo "---------------------------------------"
                    echo "Inode use rate no than 90% of the partition."
                    echo "---------------------------------------"
                fi
                break
                ;;
 
            mem_use)
                #內存利用率
                echo "---------------------------------------"
                MEM_TOTAL=`free -m |awk '{if(NR==2)printf "%.1f",$2/1024}END{print "G"}'`
                USE=`free -m |awk '{if(NR==3) printf "%.1f",$3/1024}END{print "G"}'`
                FREE=`free -m |awk '{if(NR==3) printf "%.1f",$4/1024}END{print "G"}'`
                CACHE=`free -m |awk '{if(NR==2) printf "%.1f",($6+$7)/1024}END{print "G"}'`
                echo -e "Total: $MEM_TOTAL"
                echo -e "Use: $USE"
                echo -e "Free: $FREE"
                echo -e "Cache: $CACHE"
                echo "---------------------------------------"
                break
                ;;
 
            tcp_status)
                #網絡連接狀態
                echo "---------------------------------------"
                COUNT=`netstat -antp |awk '{status[$6]++}END{for(i in status) print i,status[i]}'`
                echo -e "TCP connection status:\n$COUNT"
                echo "---------------------------------------"
                ;;
 
            cpu_top10)
                #佔用CPU高的前10個進程
                echo "---------------------------------------"
                CPU_LOG=/tmp/cpu_top.tmp
                i=1
                while [[ $i -le 3 ]]; do
                    #ps aux |awk '{if($3>0.1)print "CPU: "$3"% -->",$11,$12,$13,$14,$15,$16,"(PID:"$2")" |"sort -k2 -nr |head -n 10"}' > $CPU_LOG
                    ps aux |awk '{if($3>0.1){{printf "PID: "$2" CPU: "$3"% --> "}for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' |sort -k4 -nr |head -10 > $CPU_LOG
                    #循環從11列(進程名)開始打印,如果i等於最後一行,就打印i的列並換行,否則就打印i的列
                    if [[ -n `cat $CPU_LOG` ]]; then
                       echo -e "\033[32m  參考值${i}\033[0m"
                       cat $CPU_LOG
                       > $CPU_LOG
                    else
                        echo "No process using the CPU." 
                        break
                    fi
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
 
            mem_top10)
                #佔用內存高的前10個進程
                echo "---------------------------------------"
                MEM_LOG=/tmp/mem_top.tmp
                i=1
                while [[ $i -le 3 ]]; do
                    #ps aux |awk '{if($4>0.1)print "Memory: "$4"% -->",$11,$12,$13,$14,$15,$16,"(PID:"$2")" |"sort -k2 -nr |head -n 10"}' > $MEM_LOG
                    ps aux |awk '{if($4>0.1){{printf "PID: "$2" Memory: "$3"% --> "}for(i=11;i<=NF;i++)if(i==NF)printf $i"\n";else printf $i}}' |sort -k4 -nr |head -10 > $MEM_LOG
                    if [[ -n `cat $MEM_LOG` ]]; then
                        echo -e "\033[32m  參考值${i}\033[0m"
                        cat $MEM_LOG
                        > $MEM_LOG
                    else
                        echo "No process using the Memory."
                        break
                    fi
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
 
            traffic)
                #查看網絡流量
                while truedo
                    read -p "Please enter the network card name(eth[0-9] or em[0-9]): " eth
                    #if [[ $eth =~ ^eth[0-9]$ ]] || [[ $eth =~ ^em[0-9]$ ]] && [[ `ifconfig |grep -c "\<$eth\>"` -eq 1 ]]; then
                    if [ `ifconfig |grep -c "\<$eth\>"` -eq 1 ]; then
                        break
                    else
                        echo "Input format error or Don't have the card name, please input again."
                    fi
                done
                echo "---------------------------------------"
                echo -e " In ------ Out"
                i=1
                while [[ $i -le 3 ]]; do
                    #OLD_IN=`ifconfig $eth |awk '/RX bytes/{print $2}' |cut -d: -f2`
                    #OLD_OUT=`ifconfig $eth |awk '/RX bytes/{print $6}' |cut -d: -f2`
                    OLD_IN=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $4;else if(NR==5)print $6}'`
                    #CentOS6和CentOS7 ifconfig輸出進出流量信息位置不同,CentOS6中RX與TX行號等於8,CentOS7中RX行號是5,TX行號是5,所以就做了個判斷.       
 
                    OLD_OUT=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $9;else if(NR==7)print $6}'`
                    sleep 1
                    NEW_IN=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $4;else if(NR==5)print $6}'`
                    NEW_OUT=`ifconfig $eth |awk -F'[: ]+' '/bytes/{if(NR==8)print $9;else if(NR==7)print $6}'`
                    IN=`awk 'BEGIN{printf "%.1f\n",'$((${NEW_IN}-${OLD_IN}))'/1024/128}'`
                    OUT=`awk 'BEGIN{printf "%.1f\n",'$((${NEW_OUT}-${OLD_OUT}))'/1024/128}'`
                    echo "${IN}MB/s ${OUT}MB/s"
                    i=$(($i+1))
                    sleep 1
                done
                echo "---------------------------------------"
                break
                ;;
                        quit)
                                exit 0
                                ;;
               *)
                    echo "---------------------------------------"
                    echo "Please enter the number." 
                    echo "---------------------------------------"
                    break
                    ;;
        esac
    done
done
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章