我还是很喜欢用awk,简单。大部分人用awk只是作为shell脚本的一部分,嵌在里面用。
我则更喜欢直接用awk写脚本,因为awk的语法更类似C语言。gawk增加了对双向管道
和网络的支持,功能更强大了。可以多个awk脚本在多台机器上协同工作。以后有时间
了我会用例子介绍一下gawk的强大功能,不要以为awk只能当配角。
这个工具是随手写的,但是框架已经建立了,要添加其他数据,修改起来很方便。
这个工具最终会生成一个csv报表,每列为一个进程,每行为一个统计指标。
1 #!/usr/bin/gawk -f
2
3 BEGIN {
4 RS="\r\n";
5
6 while ( "adb shell ps"|getline) {
7 if ( $9 ~ /debuggerd/ ) {
8 ok = 0;
9 continue;
10 }
11 if ( $9 ~ /^dhd_/ )
12 continue;
13 if ( $9 ~ /^sleep$/ )
14 continue;
15 if ( $9 ~ /^\/system\/bin\/sh$/ )
16 continue;
17 if ( $9 ~ /^flush-/ )
18 continue;
19
20 if ( ok || $1 ~ /^app_/ ) {
21 n = split($9, a, "/");
22 p=a[n]"."$2;
23 pid[p]=$2;
24 }
25 if ( $9 ~ /open_ttyNK/ )
26 ok = 1;
27 }
28
29 for ( p in pid ) {
30 cmd = sprintf("adb shell cat /proc/%1d/smaps",pid[p]);
31 print cmd;
32 while ( cmd|getline ) {
33 if ( $1 ~/^[0-9a-f]+-[0-9a-f]+$/ ) {
34 if ( NF < 6 )
35 c = "ANON";
36 else {
37 c = $6;
38 if ( !vp[p]["AppName"] )
39 vp[p]["AppName"] = c;
40 }
41 }
42 else if ( $1 == "Referenced:" || $1 == "Swap:" || $1 == "KernelPageSize:" || $1 == "MMUPageSize:") {
43 continue;
44 }
45 else {
46 split($1,a,":");
47 v = a[1];
48 unit=$3;
49 pc[p][c][v] += $2;
50 vp[p][v] += $2;
51 if ( c != "ANON" && c != "[heap]" && c!="[stack]" )
52 component[c] += 1;
53 }
54 }
55
56 cmd = sprintf("adb shell cat /proc/%1d/status",pid[p]);
57 while ( cmd|getline) {
58 if ( vmHWM[p] )
59 break;
60 if ( $1 == "VmHWM:" ) {
61 vmHWM[p] = $2;
62 vp[p]["Peak-Rss"] = $2;
63 }
64 }
65
66 cmd = sprintf("adb shell cat /proc/%1d/oom_adj", pid[p]);
67 cmd|getline;
68 vp[p]["oom_adj"] = $1;
69 printf("%s Ok!\n",p);
70 }
71
72 for ( c in component )
73 print c > "component";
74
75 printf("Generating Process and Components Matrix in CSV format\n");
76 OFS=",";
77 ORS="\r\n";
78
79 report="report.csv";
80 head = "Item";
81 for ( p in vmHWM )
82 head = head","p;
83 print head > report;
84
85 i=0;
86 item[++i] = "AppName";
87 item[++i] = "oom_adj";
88 item[++i] = "Peak-Rss";
89 item[++i] = "Rss";
90 item[++i] = "Pss";
91 item[++i] = "Shared_Clean";
92 item[++i] = "Shared_Dirty";
93 item[++i] = "Private_Clean";
94 item[++i] = "Private_Dirty";
95
96 sc["[heap]"]=1;
97 sc["[stack]"]=1;
98 sc["ANON"]=1;
99 for ( c in sc ) {
100 item[++i] = c"#Rss";
101 item[++i] = c"#Pss";
102 item[++i] = c"#Shared_Clean";
103 item[++i] = c"#Shared_Dirty";
104 item[++i] = c"#Private_Clean";
105 item[++i] = c"#Private_Dirty";
106 }
107
108 for ( c in component ) {
109 item[++i] = c"#Rss";
110 item[++i] = c"#Pss";
111 item[++i] = c"#Shared_Clean";
112 item[++i] = c"#Shared_Dirty";
113 item[++i] = c"#Private_Clean";
114 item[++i] = c"#Private_Dirty";
115 }
116
117 for ( n = 1; n <= i; n ++ ) {
118 row=item[n];
119 for ( p in vmHWM ) {
120 f = split(item[n],x,"#");
121 if ( f < 2 ) {
122 row = sprintf("%s,%s",row,vp[p][item[n]]);
123 }
124 else {
125 c = x[1];
126 for ( j = 2; j < f; j ++ )
127 c = c"#"x[j];
128 row= sprintf("%s,%s",row,pc[p][c][x[f]]);
129 }
130 }
131 print row > report;
132 }
133
134 print "Completed!";
135 }
~