Output to files from ps2dot
[khome.git] / home / bin / ps2dot
CommitLineData
77bd540c
SK
1#! /bin/sh
2
059851a9
SK
3set -e
4
77bd540c
SK
5usage() {
6 echo "EXAMPLE (whole tree) : $0 | neato -T png > ps.png && open ps.png"
7 echo "EXAMPLE (user clusters): $0 | sdp -T png > ps.png && open ps.png"
8}
9
10
059851a9 11ps2dot() {
77bd540c
SK
12 awk -v kernel="$(uname -v)" -v whoami="$(whoami)" \
13 '
4a01bf49
SK
14 function num_scale(src_cur, src_max, dst_min, dst_max) {
15 return dst_min + ((src_cur * (dst_max - dst_min)) / src_max)
16 }
17
2940f645 18 function vert_print(v, _color, _fontcolor, _shape, _state, _size, _height, _label, _label_base, _label_ext) {
43061022 19 _state = child2state[v]
182bd2be
SK
20 _style = "filled,solid"
21
22 # -----------------------------------------------------------------
23 # Sleeping/idling
24 # -----------------------------------------------------------------
25 # D uninterruptible sleep (usually IO)
43061022
SK
26 if (_state == "D") {
27 _shape = "circle"
182bd2be 28 # I Idle kernel thread
43061022 29 } else if (_state == "I") {
182bd2be
SK
30 _shape = "circle"
31 # S interruptible sleep (waiting for an event to complete)
43061022 32 } else if (_state == "S") {
182bd2be
SK
33 _shape = "circle"
34 # -----------------------------------------------------------------
35 # Running
36 # -----------------------------------------------------------------
37 # R running or runnable (on run queue)
38 } else if (_state == "R") {
39 _shape = "rarrow"
40 # -----------------------------------------------------------------
41 # Stopped
42 # -----------------------------------------------------------------
43 # T stopped by job control signal
43061022
SK
44 } else if (_state == "T") {
45 _shape = "square"
182bd2be 46 # t stopped by debugger during the tracing
43061022 47 } else if (_state == "t") {
182bd2be
SK
48 _shape = "square"
49 # -----------------------------------------------------------------
50 # Dead
51 # -----------------------------------------------------------------
52 # Z defunct ("zombie") process, terminated but not reaped by its parent
43061022 53 } else if (_state == "Z") {
182bd2be
SK
54 _shape = "Msquare"
55 _style = "solid"
56 # -----------------------------------------------------------------
57 # UNKNOWN STATE
58 # -----------------------------------------------------------------
59 } else {
60 _shape = "doublecircle"
43061022 61 }
182bd2be 62
4a01bf49
SK
63 _color =\
64 num_scale(\
2940f645
SK
65 child2cpu[v],
66 max_cpu,
67 VERT_COLORSCHEME_MAX,
68 VERT_COLORSCHEME_MIN\
4a01bf49 69 )
2940f645
SK
70 _size =\
71 num_scale(\
72 child2mem[v],
73 max_mem,
74 1,
182bd2be
SK
75 4\
76 ) / 4
2940f645 77 _height = _size
182bd2be 78 _width = _size
5259a527 79 _fontcolor = \
2940f645
SK
80 _color == VERT_COLORSCHEME_MAX || _color == VERT_COLORSCHEME_MIN \
81 ? sprintf("/%s/%d", VERT_COLORSCHEME, VERT_COLORSCHEME_MID) \
5259a527 82 : sprintf("/%s/%d", "greys9", 9)
2940f645
SK
83 _fontcolor = \
84 _size < 0.5 \
85 ? sprintf("/%s/%d", "greys9", 9) \
86 : _fontcolor
87 _label_base = \
88 sprintf("%s\n%d", child2comm[v], v)
89 _label_ext = \
90 _size >= 0.5 \
91 ? sprintf("\ncpu: %.1f%%\nmem: %.1f%%", child2cpu[v], child2mem[v]) \
92 : ""
93 _label = _label_base _label_ext
4a01bf49
SK
94 printf(\
95 "\"%d\"\
96 [ fontsize=8 \
2940f645
SK
97 , fixedsize=true \
98 , height=%f \
182bd2be 99 , width=%f \
43061022 100 , border=1 \
182bd2be 101 , style=\"%s\" \
4a01bf49 102 , fontname=Helvetica \
2940f645 103 , label=\"%s\" \
43061022
SK
104 , shape=\"%s\" \
105 , fillcolor=\"/%s/%d\" \
5259a527 106 , fontcolor=\"%s\" \
4a01bf49
SK
107 ];",
108 v,
2940f645 109 _height,
182bd2be
SK
110 _width,
111 _style,
2940f645 112 _label,
43061022 113 _shape,
2940f645 114 VERT_COLORSCHEME,
4a01bf49 115 _color,
5259a527 116 _fontcolor\
4a01bf49
SK
117 )
118 }
119
2940f645 120 function edge_print(child, _parent) {
4a01bf49 121 _parent = child2parent[child]
4a01bf49
SK
122 printf(\
123 "\"%s\" -> \"%s\"\
124 [ fontsize=8 \
125 , fontname=Helvetica \
126 , len=2.0 \
2940f645 127 , color=\"%s\" \
4a01bf49
SK
128 ];\n",
129 _parent,
130 child,
2940f645 131 EDGE_COLOR\
4a01bf49
SK
132 )
133 }
134
77bd540c 135 BEGIN {
5259a527
SK
136 # Hot->Cold gradual colorschemes:
137 # - rdbu11
138 # - rdbu9
139 # - rdbu8
2940f645 140 # - rdylgn10 # 3 - 11
5259a527
SK
141
142 # Light->Dark gradual colorschemes:
143 # - reds9
144 # - blues9
145 # - orrd9
146 # - oranges9
147 # - bupu9
148 # - greys9
149
2940f645
SK
150 VERT_COLORSCHEME_MIN = 1
151 VERT_COLORSCHEME_MID = 4
152 VERT_COLORSCHEME_MAX = 8
153 VERT_COLORSCHEME = "rdylgn10"
154
155 EDGE_COLOR = "/ylorbr9/3"
5259a527 156
43061022 157 child2comm[0] = "swapper/sched"
77bd540c
SK
158 }
159
160 NR > 1 {
4a01bf49
SK
161 parent2child_count[$2]++
162 max_children = \
163 parent2child_count[$2] > max_children\
164 ? parent2child_count[$2]\
165 : max_children
166 child2parent[$1] = $2
167 child2user_id[$1] = $3
168 child2user_name[$1] = $4
5259a527 169 child2nice[$1] = $5
43061022 170 child2state[$1] = $6
2940f645
SK
171 child2cpu[$1] = $7
172 child2mem[$1] = $8
173 child2comm[$1] = $9
4a01bf49 174 user_names[$4] = 1
2940f645
SK
175 max_cpu = $7 > max_cpu ? $7 : max_cpu
176 max_mem = $8 > max_mem ? $8 : max_mem
77bd540c
SK
177 }
178
179 END {
180 print "strict digraph G {";
181
182 print "start=0;";
77bd540c
SK
183 print "fontsize=8;";
184 print "fontname=Helvetica;";
185 print "label=\"" kernel "\";";
af6e57a2 186 print "fontcolor=\"/greys9/9\";"
77bd540c
SK
187
188 ##### Vertices (clustered by user)
4a01bf49
SK
189 for (user_name in user_names) {
190 printf "subgraph \"cluster_%s\" {\n", user_name
191 printf "label=\"%s\"\n", user_name
192 for (c in child2parent)
193 if (child2user_name[c] == user_name)
194 vert_print(c)
77bd540c
SK
195 print "}"
196 }
197
198 ##### Vertices (without a user)
43061022 199 for (c in child2comm)
4a01bf49
SK
200 if (!child2user_name[c])
201 vert_print(c)
77bd540c
SK
202
203 ##### Edges (across clusters)
4a01bf49
SK
204 for (c in child2parent)
205 edge_print(c)
77bd540c
SK
206
207 print "}";
208 }
209 '
210}
211
212
213procs() {
214 if [ "$(uname)" = 'Linux' ]; then
2940f645 215 ps -eo 'pid,ppid,euid,euser,nice,s,%cpu,%mem,comm'
77bd540c 216 else
2940f645 217 ps -eco 'pid,ppid,euid,euser,nice,s,%cpu,%mem,comm'
77bd540c
SK
218 fi
219}
220
221
222main() {
223 case "$1" in
059851a9
SK
224 '--help')
225 usage
77bd540c 226 ;;
059851a9
SK
227 *)
228 timestamp="$(date +'%Y-%m-%d_%H:%M:%S%z')"
229 host="$(hostname)"
230 kernel="$(uname -s | awk '{print tolower($0)}')"
231 filename_base=$(mktemp "ps.$host.$kernel.$timestamp.XXXXX")
232 file_log="$filename_base.log"
233 file_dot="$filename_base.dot"
234 mv "$filename_base" "$file_log"
235 procs | grep "$1" | ps2dot 2> "$file_log" > "$file_dot"
236 time neato -T png "$file_dot" 2> "$file_log" > "$filename_base.neato.png"
237 time fdp -T png "$file_dot" 2> "$file_log" > "$filename_base.fdp.png"
238 time dot -T png "$file_dot" 2> "$file_log" > "$filename_base.dot.png"
239 ls -1 "$filename_base"*
77bd540c
SK
240 ;;
241 esac
242}
243
244
245main "$1"
This page took 0.05317 seconds and 4 git commands to generate.