ネットワーク
今回はDTraceを使ってネットワーク関係のデータを集計するサンプルを紹介します。たとえば、
# dtrace -n 'ip:::receive{@[args[2]->ip_saddr]=count()}' dtrace: description 'ip:::receive' matched 1 probe ^C 192.168.185.2 4 216.58.197.228 5 172.217.27.67 13 96.47.72.132 53 192.168.185.1 612 #
先ほどのサンプルはプローブip:::receiveを指定してデータを集計していますが、
# dtrace -n 'ip:::send{@[args[2]->ip_daddr]=quantize(args[2]->ip_plength)}' dtrace: description 'ip:::send' matched 1 probe ^C 216.58.220.227 value ------------- Distribution ------------- count 8 | 0 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 7 32 |@@@@ 1 64 |@@@@ 1 128 | 0 192.168.185.2 value ------------- Distribution ------------- count 16 | 0 32 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 11 64 | 0 216.58.197.227 value ------------- Distribution ------------- count 8 | 0 16 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14 32 |@@@@ 2 64 |@@@@ 2 128 | 0 96.47.72.132 value ------------- Distribution ------------- count 8 | 0 16 |@@@@@@@@@@@@@@@ 16 32 |@@@@@@@@@@@@@@ 15 64 |@@@@@@ 6 128 | 0 256 |@@ 2 512 |@ 1 1024 |@@ 2 2048 | 0 192.168.185.1 value ------------- Distribution ------------- count 16 | 0 32 |@ 11 64 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 460 128 |@@ 31 256 | 3 512 | 4 1024 | 5 2048 | 3 4096 | 3 8192 | 0 #
これで目的地へのパケットのデータ長の様子がわかります。こんな感じでデータ長をチェックすると、
今度はip:::receiveとip:::sendの双方を使ってやり取りの状況をモニタリングするスクリプトを取り上げます。
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option switchrate=10hz
dtrace:::BEGIN
{
printf(" %3s %10s %15s %15s %8s %6s\n", "CPU", "DELTA(us)",
"SOURCE", "DEST", "INT", "BYTES");
last = timestamp;
}
ip:::send
{
this->delta = (timestamp - last) / 1000;
printf(" %3d %10d %15s -> %15s %8s %6d\n", cpu, this->delta,
args[2]->ip_saddr, args[2]->ip_daddr, args[3]->if_name,
args[2]->ip_plength);
last = timestamp;
}
ip:::receive
{
this->delta = (timestamp - last) / 1000;
printf(" %3d %10d %15s delta,
args[2]->ip_daddr, args[2]->ip_saddr, args[3]->if_name,
args[2]->ip_plength);
last = timestamp;
}
これを実行すると次のような結果が得られます。こんな出力が簡単に得られるところがDTraceのすごいところです。
# ./ipio.d CPU DELTA(us) SOURCE DEST INT BYTES 2 674 192.168.1.101 -> 192.168.1.39 bge0 140 1 4757 192.168.1.101 192.168.1.39 bge0 156 2 13 192.168.1.101 -> 192.168.1.39 bge0 124 1 2788 192.168.1.101 192.168.1.39 bge0 220 2 13 192.168.1.101 -> 192.168.1.39 bge0 124 1 4551 192.168.1.101 192.168.1.39 bge0 204 2 12 192.168.1.101 -> 192.168.1.39 bge0 140 1 1893 192.168.1.101 192.168.1.39 bge0 252 2 13 192.168.1.101 -> 192.168.1.39 bge0 84 1 3389 192.168.1.101 192.168.1.39 bge0 244 2 12 192.168.1.101 -> 192.168.1.39 bge0 100 1 44157 192.168.1.101 192.168.1.39 bge0 244 3 12 192.168.1.101 -> 192.168.1.39 bge0 100 1 2790 192.168.1.101 192.168.1.39 bge0 236 3 13 192.168.1.101 -> 192.168.1.39 bge0 108 1 3684 192.168.1.101 192.168.1.39 bge0 220 3 12 192.168.1.101 -> 192.168.1.39 bge0 124 1 2178 192.168.1.101
同じくip:::receiveとip:::sendを使ってデータを集計して出力するスクリプトを紹介します。こちらは先ほどと違ってCtrl-Cが押されるまでのデータをため込んで、
#!/usr/sbin/dtrace -s
dtrace:::BEGIN
{
printf("Tracing... Hit Ctrl-C to end.\n");
}
ip:::send,
ip:::receive
{
this->protostr = args[2]->ip_ver == 4 ?
args[4]->ipv4_protostr : args[5]->ipv6_nextstr;
@num[args[2]->ip_saddr, args[2]->ip_daddr, this->protostr] = count();
}
dtrace:::END
{
printf("\n");
printf(" %-28s %-28s %6s %8s\n", "SADDR", "DADDR", "PROTO", "COUNT");
printa(" %-28s %-28s %6s %@8d\n", @num);
}
実行すると次のような結果が得られます。
# ./ipproto.d dtrace: script './ipproto.d' matched 4 probes CPU ID FUNCTION:NAME 2 1 :BEGIN Tracing... Hit Ctrl-C to end. ^C 1 2 :END SADDR DADDR PROTO COUNT 192.168.1.10 192.168.1.101 TCP 1 192.168.1.101 192.168.1.10 TCP 1 192.168.1.101 210.173.160.57 UDP 1 0.0.0.0 255.255.255.255 UDP 2 192.168.1.101 202.216.224.66 UDP 3 192.168.1.39 255.255.255.255 UDP 4 192.168.1.53 224.0.0.22 IGMP 4 192.168.1.101 202.216.246.91 UDP 5 202.216.246.91 192.168.1.101 UDP 5 192.168.1.107 239.255.255.250 UDP 6 192.168.1.106 239.255.255.250 UDP 8 192.168.1.39 192.168.1.255 UDP 8 192.168.1.39 239.255.255.250 UDP 8 192.168.1.107 255.255.255.255 UDP 18 192.168.1.10 192.168.1.255 UDP 26 192.168.1.101 96.47.72.132 TCP 27 96.47.72.132 192.168.1.101 TCP 28 192.168.1.53 224.0.0.251 UDP 32 192.168.1.101 192.168.1.39 TCP 83 192.168.1.39 192.168.1.101 TCP 87 #
従来から提供されている*stat系のコマンドでは特定の通信に関して詳細なデータを取得するといったことを行うのが難しい面がありましたが、
※ ここに掲載したサンプルスクリプトは"DTrace Dynamic Tracing In Oracle Solaris, Mac OS X & FreeBSD", by Brendan Gregg and Jim Mauro P.
勉強会
第60回 2月23日(木)19:00~FreeBSD勉強会
発表内容検討中。発表ネタをお持ちの方、
参加申請はこちらから。
第61回 3月23日(木)19:00~FreeBSD勉強会:リキャップ・ザ・AsiaBSDCon 2017 ~日本語でふりかえるABC~
2017年3月9~12日まで東京でAsiaBSDCon 2017が開催される予定です。ぜひこのカンファレンスにご参加いただきたいわけなのですが、
3月のFreeBSD勉強会では、
FreeBSD勉強会 発表者募集
FreeBSD勉強会では発表者を募集しています。FreeBSDに関して発表を行いたい場合、