systemtap的網路監控指令碼
stap自帶的與網路相關的probe如下,可用於檢測一系列網路活動
netdev.close/open--關閉開啟裝置時呼叫;dev_name--涉及的裝置名
netdev.receive--從網路裝置接收的資料;引數:protocl--資料包的協議;dev_name--裝置名,諸如eth0;length--接收buffer的長度
netdev.rx--當裝置即將接收資料包時呼叫;引數:protocol--資料包協議;dev_name--接收的裝置名
netdev.transmit--傳送資料的網路裝置;protocol/dev_name/length/truesize--傳送的資料大小
socket.aio_read--透過sock_aio_read接收資訊時呼叫;size資訊大小type套接字型別protocol協議名
socket.aio_write--透過sock_aio_write傳送資訊時呼叫;size資訊大小type套接字型別protocol協議名
socket.create--建立套接字;type套接字型別protocol協議名
socket.receive--套接字接收資訊;success傳送是否成功1失敗0size資訊大小type套接字型別protocol協議名
socket.send--傳送資訊;success傳送是否成功1失敗0size資訊大小type套接字型別protocol協議名
socket.sendmsg--正在傳送資訊的套接字;
tcp.disconnect--退出TCP連線;dport/sport目標/源埠;saddr/daddr源IP/目標IP;
tcp.disconnect.return
tcp.receive--接收TCP包;protocol協議名dport/sport/saddr/daddr/ack/fin/syn
tcp.recvmsg--正在接收TCP資訊;
tcp.sendmsg--正在傳送TCP資訊;
netfilter.ip.local_in--Called on an incoming IP packet addressed to the local computer
netfilter.ip.local_out-- Called on an outgoing IP packet
netfilter.ip.forward - Called on an incoming IP packet addressed to some other computer
例1
network/netfilter_drop.stp
丟棄接收的TCP/UDP前N個包
# stap -g netfilter_drop.stp TCP 1 -c "sleep 2"
#! /usr/bin/env stap
global drop_count
#將網路協議從數字轉換為等義字串,6=TCP 17=UDP
function convert_protocol(proto_n) {
proto_s="Other"
if (proto_n==6)
proto_s="TCP"
else if(proto_n==17)
proto_s="UDP"
return proto_s
}
probe netfilter.ipv4.local_in {
#傳入引數length--包長度 nf_stop--將此包定義為stop, verdict--該包最終處理決定
if(convert_protocol(protocol) || @1=="ALL") {
if(@count(drop_count[@1])>=$2 && $2 !=0)
exit()
else {
$verdict=nf_stop
drop_count[@1]<<
}
}
}
probe begin {
#判斷引數1引數2是否符合標準
if (@1 !='TCP' || @1 !='UDP' && @1 !='ALL') || ($2<0) {
printf("Please enter \"TCP\", \"UDP\" or \"ALL\" on the command line, followed by the number of packets to drop.\n")
exit()
}
else
printf("Dropping packets! Ctrl+C to stop")
}
probe end{
foreach(proto in drop_count)
printf("%d %s packets drop, total %d bytes\n",@count(drop_count[proto]),proto,@sum(drop_count[proto]))
}
例2
在後臺執行,將核心的tcp cwnd覆蓋為10,用於改善web server的延遲
#! /usr/bin/stap -g
probe kernel.function("tcp_init_cwnd").return {
r = $return
if( r>0 && r<10)
$return =10;
counts[r,$return] <<< 1
}
global counts # will be automatically summarized at shutdown
該指令碼起始於http://blog.yufeng.info/archives/1173
tcp_init_cwnd.stp
probe kernel.function("tcp_init_cwnd").return
{
$return = $1
}
#設成7個mss
$ sudo stap -p4 -g -m initcwnd tcp_init_cwnd.stp 7
initcwnd.ko
載入到遠端機器
$ sudo insmod initcwnd.ko
例3
network/netdev.stp
跟蹤網路卡活動,提交和接收包以及更改配置
#! /usr/bin/env stap
probe netdev.get_stats ? {
printf("%s was asked for stats structure\n", dev)
}
probe netdev.register {
printf("registering netdev_name\n",dev_name)
}
probe netdev.unregister{
printf("unregistering netdev_name\n",dev_name)
}
probe netdev.ioctl{
printf("netdev ioctl raised with param:%d and arg:%s\n",cmd,arg)
}
probe netdev.set_promiscuity {
if (enable)
printf("Device %s entering in promiscuous mode\n", dev_name)
else
printf("Device %s leaving promiscuous mode\n", dev_name)
}
probe netdev.change_rx_flag ? {
printf("Device %s is changing its RX flags to %d\n", dev_name, flags)
}
probe netdev.change_mtu {
printf("Changing MTU on device %s from %d to %d\n", dev_name,
old_mtu, new_mtu)
}
probe netdev.change_mac {
printf("Changing MAC address on device %s from %s to %s\n",
dev_name, old_mac, new_mac)
}
probe netdev.transmit {
printf("Device %s is sending (queued) a packet with protocol %d\n", dev_name, protocol)
}
probe netdev.hard_transmit {
printf("Device %s is sending (hard) a packet with protocol %d\n", dev_name, protocol)
}
probe netdev.rx {
printf("Device %s received a packet with protocol %d\n", dev_name, protocol)
}
例4
nettop.stp
按照網路接收或傳送次數降序排列,每5秒列印一次
global ifxmit,ifrecv
global ifmerged
probe netdev.transmit {
ifxmit[pid(),dev_name,execname(),uid()] <<< length --將傳送的包長度存放到ifxmit
}
probe netdev.receive {
ifrecv[pid(),dev_name,execname(),uid()] <<< length --將接受的包長度存放到ifrecv
}
function print_activity {
printf("%5s %5s %-7s %7s %7s %7s %7s %-15s\n",
"PID", "UID", "DEV", "XMIT_PK", "RECV_PK",
"XMIT_KB", "RECV_KB", "COMMAND")
foreach ([pid,dev,exec,uid] in ifxmit) {--遍歷ifxmit,計算相同屬性程式傳送和接受包的總次數
ifmerged[pid,dev,exec,uid] += @count(ifxmit[pid,dev,exec,uid]);
}
foreach ([pid,dev,exec,uid] in ifrecv) {
ifmerge[pid,dev,exec,uid] += @count(ifrecv[pid,dev,exec,uid]);
}
foreach ([pid,dev,exec,uid] in ifmerge -) {--按傳送+接收次數降序排列
n_xmit = @count(ifxmit[pid,dev,exec,uid]);--傳送次數
n_recv = @count(ifrecv[pid,dev,exec,uid]);--接收次數
printf("%5d %5d %-7s %7d %7d %7d %7d %-15s\n",
pid, uid, dev, n_xmit, n_recv,
n_xmit ? @sum(ifxmit[pid, dev, exec, uid])/1024 : 0,
n_recv ? @sum(ifrecv[pid, dev, exec, uid])/1024 : 0,
exec)
}
delete ifmerged
delete ifxmit
delete ifrecv
}
probe timer,ms(5000), end, error {
print_activity()
}
以下為輸出
PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND
2886 4 eth0 79 0 5 0 cups-polld
11362 0 eth0 0 61 0 5 firefox
0 0 eth0 3 32 0 3 swapper
2886 4 lo 4 4 0 0 cups-polld
11178 0 eth0 3 0 0 0 synergyc
PID UID DEV XMIT_PK RECV_PK XMIT_KB RECV_KB COMMAND
0 0 eth0 0 6 0 0 swapper
2886 4 lo 2 2 0 0 cups-polld
11178 0 eth0 3 0 0 0 synergyc
3611 0 eth0 0 1 0 0 Xorg
例5
socket-trace.stp
跟蹤有關net/socket.c的核心呼叫
#! /usr/bin/env stap
probe kernel.function(" {
printf ("%s -> %s\n", thread_indent(1), ppfunc())
}
probe kernel.function(" {
printf ("%s }
輸出如下
0 Xorg(3611): -> sock_poll
3 Xorg(3611): 0 Xorg(3611): -> sock_poll
3 Xorg(3611): 0 gnome-terminal(11106): -> sock_poll
5 gnome-terminal(11106): 0 scim-bridge(3883): -> sock_poll
3 scim-bridge(3883): 0 scim-bridge(3883): -> sys_socketcall
4 scim-bridge(3883): -> sys_recv
8 scim-bridge(3883): -> sys_recvfrom
例6
監控接受到的TCP資料包
#! /usr/bin/env stap
// A TCP dump like example
probe begin, timer.s(1) {
printf("-----------------------------------------------------------------\n")
printf(" Source IP Dest IP SPort DPort U A P R S F \n")
printf("-----------------------------------------------------------------\n")
}
probe tcp.receive {
printf(" %15s %15s %5d %5d %d %d %d %d %d %d\n",
saddr, daddr, sport, dport, urg, ack, psh, rst, syn, fin)
}
輸出如下
-----------------------------------------------------------------
Source IP Dest IP SPort DPort U A P R S F
-----------------------------------------------------------------
209.85.229.147 10.0.2.15 80 20373 0 1 1 0 0 0
92.122.126.240 10.0.2.15 80 53214 0 1 0 0 1 0
92.122.126.240 10.0.2.15 80 53214 0 1 0 0 0 0
209.85.229.118 10.0.2.15 80 63433 0 1 0 0 1 0
例7
監控核心丟棄的網路包
dropwatch.stp
#! /usr/bin/env stap
global locations
probe begin { printf("Monitoring for dropped packets\n") }
probe end { printf("Stopping dropped packet monitor\n") }
probe kernel.trace("kfree_skb") { locations[$location] <<< 1}
probe timer.sec(5) {
foreach(l in locations-) {
printf("%d packets dropped at %s\n", @count(loactions[l]),symname(l))
}
}
--kfree_skb跟蹤核心丟棄網路包,有2個引數:$skb指向被釋放的buffer的指標;$location被釋放的核心程式碼位置;
執行stap --all-modules dropwatch.stp
注:如果--all-modules不可用,則symname只會列印出raw地址,此時可以使用/boot/System.map-`uname -r`檢視其對應的function
Monitoring for dropped packets
1762 packets dropped at unix_stream_recvmsg
4 packets dropped at tun_do_read
2 packets dropped at nf_hook_slow
例8
監控新建的TCP連線
#! /usr/bin/env stap
probe begin {
printf("%6s %16s %6s %6s %16s\n",
"UID", "CMD", "PID", "PORT", "IP_SOURCE")
}
probe kernel.function("tcp_accept").return?,
kernel.function("inet_csk_accept").return? {
sock = $return
if (sock != 0)
printf("%6d %16s %6d %6d %16s\n", uid(), execname(), pid(),
inet_get_local_port(sock), inet_get_ip_source(sock))
}
輸出如下
UID CMD PID PORT IP_SOURCE
0 sshd 3165 22 10.64.0.227
0 sshd 3165 22 10.64.0.227
/usr/share/systemtap/testsuite/systemtap.examples/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-762002/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- linux網路流量實時監控指令碼Linux指令碼
- 監控指令碼指令碼
- 【SQL監控】SQL完全監控的指令碼SQL指令碼
- mysql 的一個監控指令碼,監控heartbeatMySql指令碼
- mysql監控指令碼MySql指令碼
- DBA監控指令碼指令碼
- session指令碼監控Session指令碼
- 埠監控指令碼指令碼
- oracle 監控指令碼Oracle指令碼
- listener監聽監控指令碼指令碼
- mysql mon 的一個監控指令碼,監控heartbeatMySql指令碼
- 利用shell指令碼監控網站狀態指令碼網站
- linux_監控網路卡流量指令碼Linux指令碼
- ogg監控指令碼指令碼
- stap監控IO指令碼指令碼
- 【shell】磁碟監控指令碼指令碼
- 網路卡流量監控指令碼,python實現指令碼Python
- PostgreSQL之鎖監控指令碼SQL指令碼
- Oracle DBA常用監控指令碼Oracle指令碼
- memcached程式埠監控指令碼指令碼
- Nagios 監控ESXI指令碼iOS指令碼
- 監控cpu與memory指令碼指令碼
- 資料庫監控指令碼資料庫指令碼
- (Datagurad)監控指令碼指令碼
- 監控session數量指令碼Session指令碼
- 監控硬碟空間指令碼硬碟指令碼
- 監控sqlldr執行指令碼SQL指令碼
- 監控資料庫指令碼資料庫指令碼
- cacti自定義監控指令碼指令碼
- 《boot分割槽監控的小指令碼》boot指令碼
- 常用的主機監控shell指令碼指令碼
- 監控mysql索引使用效率的指令碼MySql索引指令碼
- OpManager:網路監控的利器
- 使用Shell指令碼程式監控網站URL是否正常指令碼網站
- 監控系統告警指令碼集合指令碼
- 監控oracle表空間指令碼Oracle指令碼
- Goldengate for nrpe監控指令碼Go指令碼
- stap監控cpu指令碼小結指令碼