topの概要
語り尽くされてますし、manにもすごく丁寧に説明がありますので、見た目だけ。
top - 10:12:59 up 42 min, 3 users, load average: 0.00, 0.01, 0.05 Tasks: 159 total, 1 running, 158 sleeping, 0 stopped, 0 zombie Cpu(s): 0.6%us, 0.4%sy, 0.0%ni, 96.8%id, 2.1%wa, 0.0%hi, 0.0%si, 0.0%st Mem: 4048536k total, 1446716k used, 2601820k free, 36404k buffers Swap: 4194300k total, 0k used, 4194300k free, 1124068k cached PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 2965 root 200 158m 27m 9572 S 2.0 0.7 0:09.76 Xorg 1 root 2001940815281228 S 0.0 0.0 0:01.51 init 2 root 200000 S 0.0 0.0 0:00.00 kthreadd 3 root 200000 S 0.0 0.0 0:00.01 ksoftirqd/05 root 0-20000 S 0.0 0.0 0:00.00 kworker/0:0H 6 root 200000 S 0.0 0.0 0:00.00 kworker/u:07 root 0-20000 S 0.0 0.0 0:00.00 kworker/u:0H (以下略)
こんな感じで出力されるので、ただファイルに蓄積していっても、時間推移を見るのも一苦労。
後で集計しやすいように、監視対象カテゴリに絞って出力させる。
色々加工するにはなんだかんだExcelが便利なんだけど、このtopのフォーマットってそのままではとても扱いにくい。
やっぱりExcelに取り込むなら、CSVとかTSVとか固定長とか、そういったものが相性がいい。
なので、それを目指してゴニョゴニョします。
サマリ部
file=には任意の出力先を、Sleepには任意の更新間隔(秒)を。あとはいじる必要は特に無いです。
ワンライナーにしてますが、読みにくい&スクリプトとして保存する際は、素直に見やすい改行形式でどうぞ。
なお、ここでawkがやっていることは、「各行の1つ目の要素が***のものに絞り込む」ってことだけ。この程度だったらgrepでもよいのかな?今回はあえてawk使いたかったのでawkでやってみました。
# top - ロードアベレージ監視while true;dofile="/tmp/TOP_top.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S');top=$(echo -n $(top -b -n 1 -c -d 0| awk '$1 == "top"'));echo"${date}${top}">>$file;sleep15;done; # Tasks監視while true;dofile="/tmp/TOP_tasks.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S');top=$(echo -n $(top -b -n 1 -c -d 0| awk '$1 == "Tasks"'));echo"${date}${top}">>$file;sleep15;done; # CPU監視while true;dofile="/tmp/TOP_cpus.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S');top=$(echo -n $(top -b -n 1 -c -d 0| awk '$1 == "Cpu(s):"'));echo"${date}${top}">>$file;sleep15;done; # メモリ監視while true;dofile="/tmp/TOP_mem.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S');top=$(echo -n $(top -b -n 1 -c -d 0| awk '$1 == "Mem:"'));echo"${date}${top}">>$file;sleep15;done; # swap監視while true;dofile="/tmp/TOP_swap.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S');top=$(echo -n $(top -b -n 1 -c -d 0| awk '$1 == "Swap:"'));echo"${date}${top}">>$file;sleep15;done;
なお、topのデフォルト起動時は「1」を押すと複数CPUの場合にそれぞれの情報に分かれて表示されるのですが、topのコマンドライン引数としてはサポートされていません。
代わりに設定ファイルで起動時デフォルトを設定できるので、必要に応じてそれを使うことになります。
今回は、「環境やたらにいじれないところで、突発的に短時間の性能監視してくれと言われた時に、さっと実行できるもの」という想定(ていうか現実)の元で使えるものが欲しかったため、あえてその辺りはいじりません。
カスタムする場合は、ここにもmanの日本語訳がおいてあるので、「5. ファイル」の章をしっかり読んで下さい。
Man page of TOP
プロセス部
サンプルは以下となります。
プロセスを特定するもので絞り込みが必要ですので、そのための情報を事前に確認しておく必要があります。
プロセスIDで絞り込む場合、先にtopかpsで監視対象のプロセスIDを確認した後に実行することになります。
# プロセスID - PID=2965の場合while true;dofile="/tmp/TOP_pid.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S');top=$(echo -n $(top -b -n 1 -c -d 0 -p 2965| awk '$1 == 2965'));echo"${date}${top}">>$file;sleep15;done; # ユーザーID - USER=rootの場合。複数行抽出される可能性が高いので、sedを使っています。while true;dofile="/tmp/TOP_uid.$(date '+%Y%m%d')";date=$(date '+%Y%m%d %H:%M:%S'); top -b-n1-c-d0-u root |sed-n-e /root/p |sed-e"s/^/$date/">>$file;sleep15;done;
絞込の結果が複数になってしまう場合、1行で出力されると非常に扱いにくいので、
1:冒頭の日付を各行に追加
2:改行含めて出力
という要件を加えた結果、こうなりました。
sedの1つ目は、「root」が含まれる行だけを抽出。これもawk、grepと大差ないか。
sedn2つ目は、各行の先頭に日付を追加。先にdateで日付を変数$dateに詰めておき、「^=行頭」に置換させる命令になってます。
echoをかませると、複数行が条件に引っかかった時に1行出力になってしまうようなので、echoはやめてsedの結果をファイルに直接リダイレクトしています。
これで取得したファイルをexcelにでも取り込んであげれば、フィルタもソートもグラフ化もラク。
パワフルなツール、sed& awk
今までなぜか触れる機会がまったくなかったsed&awkですが、ネット検索しながらここまで作れました。
どこでもたいてい使えて非常に強力なツールなので、もっと使い込みたいです。

sed & awkプログラミング 改訂版 (A nutshell handbook)
- 作者: Dale Dougherty,Arnold Robbins,福崎俊博
- 出版社/メーカー:オライリー・ジャパン
- 発売日: 1997/10/01
- メディア:大型本
- 購入: 2人 クリック: 48回
- この商品を含むブログ (34件) を見る
*1:元DB屋。もう業界離れて10年超