Distinguish process states by shape
[khome.git] / home / bin / ps2dot
1 #! /bin/sh
2
3 usage() {
4 echo "EXAMPLE (whole tree) : $0 | neato -T png > ps.png && open ps.png"
5 echo "EXAMPLE (user clusters): $0 | sdp -T png > ps.png && open ps.png"
6 }
7
8
9 compile() {
10 awk -v kernel="$(uname -v)" -v whoami="$(whoami)" \
11 '
12 function num_scale(src_cur, src_max, dst_min, dst_max) {
13 return dst_min + ((src_cur * (dst_max - dst_min)) / src_max)
14 }
15
16 function vert_print(v, _color, _fontcolor, _shape, _state) {
17 _shape = "rectangle"
18 _state = child2state[v]
19 if (_state == "D") {
20 _shape = "circle"
21 } else if (_state == "I") {
22 _shape = "octagon"
23 } else if (_state == "R") {
24 _shape = "star"
25 } else if (_state == "S") {
26 _shape = "oval"
27 } else if (_state == "T") {
28 _shape = "square"
29 } else if (_state == "t") {
30 _shape = "Msquare"
31 } else if (_state == "Z") {
32 _shape = "diamond"
33 }
34 _color =\
35 num_scale(\
36 child2nice[v] + 20,
37 20 + 20,
38 COLORSCHEME_MIN,
39 COLORSCHEME_MAX\
40 )
41 _fontcolor = \
42 _color == COLORSCHEME_MAX || _color == COLORSCHEME_MIN \
43 ? sprintf("/%s/%d", COLORSCHEME, COLORSCHEME_MID) \
44 : sprintf("/%s/%d", "greys9", 9)
45 printf(\
46 "\"%d\"\
47 [ fontsize=8 \
48 , border=1 \
49 , style=\"filled,solid\" \
50 , fontname=Helvetica \
51 , label=\"%s\n%d\" \
52 , shape=\"%s\" \
53 , fillcolor=\"/%s/%d\" \
54 , fontcolor=\"%s\" \
55 ];",
56 v,
57 child2comm[v],
58 v,
59 _shape,
60 COLORSCHEME,
61 _color,
62 _fontcolor\
63 )
64 }
65
66 function edge_print(child, _parent, _color, _colorscheme) {
67 _parent = child2parent[child]
68 _colorscheme = COLORSCHEME
69 _color = COLORSCHEME_MID
70 printf(\
71 "\"%s\" -> \"%s\"\
72 [ fontsize=8 \
73 , fontname=Helvetica \
74 , len=2.0 \
75 , colorscheme=%s \
76 , color=%d \
77 ];\n",
78 _parent,
79 child,
80 _colorscheme,
81 _color\
82 )
83 }
84
85 BEGIN {
86 # Hot->Cold gradual colorschemes:
87 # - rdbu11
88 # - rdbu9
89 # - rdbu8
90
91 # Light->Dark gradual colorschemes:
92 # - reds9
93 # - blues9
94 # - orrd9
95 # - oranges9
96 # - bupu9
97 # - greys9
98
99 COLORSCHEME_MIN = 1
100 COLORSCHEME_MID = 5
101 COLORSCHEME_MAX = 10
102 COLORSCHEME = sprintf("rdylgn%d", COLORSCHEME_MAX)
103
104 child2comm[0] = "swapper/sched"
105 }
106
107 NR > 1 {
108 parent2child_count[$2]++
109 max_children = \
110 parent2child_count[$2] > max_children\
111 ? parent2child_count[$2]\
112 : max_children
113 child2parent[$1] = $2
114 child2user_id[$1] = $3
115 child2user_name[$1] = $4
116 child2nice[$1] = $5
117 child2state[$1] = $6
118 child2comm[$1] = $7
119 user_names[$4] = 1
120 }
121
122 END {
123 print "strict digraph G {";
124
125 print "start=0;";
126 print "fontsize=8;";
127 print "fontname=Helvetica;";
128 print "label=\"" kernel "\";";
129 print "fontcolor=\"/greys9/9\";"
130
131 ##### Vertices (clustered by user)
132 for (user_name in user_names) {
133 printf "subgraph \"cluster_%s\" {\n", user_name
134 printf "label=\"%s\"\n", user_name
135 for (c in child2parent)
136 if (child2user_name[c] == user_name)
137 vert_print(c)
138 print "}"
139 }
140
141 ##### Vertices (without a user)
142 for (c in child2comm)
143 if (!child2user_name[c])
144 vert_print(c)
145
146 ##### Edges (across clusters)
147 for (c in child2parent)
148 edge_print(c)
149
150 print "}";
151 }
152 '
153 }
154
155
156 procs() {
157 if [ "$(uname)" = 'Linux' ]; then
158 ps -eo 'pid,ppid,euid,euser,nice,s,comm'
159 else
160 ps -eco 'pid,ppid,euid,euser,nice,s,comm'
161 fi
162 }
163
164
165 main() {
166 case "$1" in
167 '--help') usage
168 ;;
169 *) procs | grep "$1" | compile
170 ;;
171 esac
172 }
173
174
175 main "$1"
This page took 0.089986 seconds and 4 git commands to generate.