cvsimport
[hcoop/zz_old/portal.git] / stats.sml
CommitLineData
a41f8250 1structure Stats :> STATS =
2struct
3 val webbw = "/etc/stats/webbw"
4 val webbw_last = "/etc/stats/webbw.last"
5 val webbw_last2 = "/etc/stats/webbw.last2"
6
7 type host = {ssl : bool,
8 hostname : string,
9 id : string}
10
3d439ebe 11 fun checkSsl (node, host) =
12 let
13 val id = case String.tokens (fn ch => ch = #".") host of
14 [] => node ^ "/" ^ host
15 | first :: rest =>
16 case rev (String.tokens (fn ch => ch = #"_") first) of
17 "ssl" :: rest' => node ^ "/" ^ String.concatWith "_" (rev rest')
18 ^ "." ^ String.concatWith "." rest ^ ".ssl"
19 | _ => node ^ "/" ^ host
20 in
21 case String.fields (fn ch => ch = #".") host of
22 first::rest =>
23 (case String.fields (fn ch => ch = #"_") first of
24 [first, "ssl"] => {ssl = true, hostname = String.concatWith "." (first::rest),
25 id = id}
26 | _ => {ssl = false, hostname = host, id = id})
27 | _ => {ssl = false, hostname = host, id = id}
28 end
a41f8250 29
30 fun getWebbw last =
31 let
32 val fname =
33 case last of
34 2 => webbw_last2
35 | 1 => webbw_last
36 | 0 => webbw
37 | _ => raise Fail "Asked for too old of a bandwidth file"
38
39 val inf = TextIO.openIn fname
40
41 val sum = case TextIO.inputLine inf of
42 NONE => raise Fail "Can't read webbw"
43 | SOME l =>
44
45 case String.tokens Char.isSpace l of
46 [_, n] => valOf (Int.fromString n)
47 | _ => raise Fail "Bad total in webbw"
48
49 fun readEm L =
50 case TextIO.inputLine inf of
51 (NONE | SOME "\n") => List.rev L
52 | SOME l =>
53 case String.tokens (fn ch => Char.isSpace ch orelse ch = #":") l of
3d439ebe 54 [d, n] =>
55 (case String.tokens (fn ch => ch = #"@") d of
56 [d, node] => readEm ({host = checkSsl (node, d), size = valOf (Int.fromString n)} :: L)
57 | _ => raise Fail ("Bad row in webbw [2]: " ^ l))
58 | _ => raise Fail ("Bad row in webbw [1]: " ^ l)
a41f8250 59
60 fun splitLast [] = raise Fail "Not enough items for splitLast"
61 | splitLast [x] = ([], x)
62 | splitLast (h::t) =
63 let
64 val (l, x) = splitLast t
65 in
66 (h::l, x)
67 end
68
69 fun readGroups L =
70 case TextIO.inputLine inf of
71 NONE => List.rev L
72 | SOME l =>
73 case String.tokens (fn ch => Char.isSpace ch orelse ch = #":" orelse ch = #"[" orelse ch = #"]" orelse ch = #",") l of
74 d :: rest =>
75 let
76 val (l, x) = splitLast rest
3d439ebe 77
78 fun split s =
79 case String.tokens (fn ch => ch = #"@") s of
80 [host, node] => (node, host)
81 | _ => raise Fail ("Bad row in webbw [3]: " ^ s)
a41f8250 82 in
3d439ebe 83 readGroups ({user = d, hosts = map (checkSsl o split) l, size = valOf (Int.fromString x)} :: L)
a41f8250 84 end
3d439ebe 85 | _ => raise Fail ("Bad row in webbw [4]: " ^ l)
a41f8250 86 in
87 TextIO.inputLine inf;
3d439ebe 88 {total = sum, vhosts = readEm [], users = readGroups []}
a41f8250 89 before TextIO.closeIn inf
90 end
91
92 type disk = {uname : string,
744be417 93 kbs : int}
a41f8250 94
4bbdb10e 95 structure StringKey = struct
96 type ord_key = string
97 val compare = String.compare
98 end
99
100 structure SM = BinaryMapFn(StringKey)
101
a41f8250 102 fun getDiskUsage () =
103 let
4bbdb10e 104 val proc = Unix.execute ("/bin/sh", ["-c", "/usr/bin/vos listvol deleuze"])
a41f8250 105 val inf = Unix.textInstreamOf proc
106
744be417 107 fun loop acc =
108 case TextIO.inputLine inf of
109 NONE => acc
110 | SOME line =>
111 case String.tokens Char.isSpace line of
4bbdb10e 112 [vol, _, _, kbs, _, _] =>
113 let
114 val kbsOld = case SM.find (acc, vol) of
115 NONE => 0
116 | SOME n => n
117
118 val uname = case String.tokens (fn ch => ch = #".") vol of
119 [_, uname] =>
120 ((Posix.SysDB.getpwnam uname;
121 SOME uname)
122 handle OS.SysErr _ => NONE)
123 | _ => NONE
124
125 val acc = case uname of
126 NONE => acc
127 | SOME uname => SM.insert (acc, uname, valOf (Int.fromString kbs) + kbsOld)
128 in
744be417 129 loop acc
4bbdb10e 130 end
131 | _ => acc
132
133 val _ = TextIO.inputLine inf
134 val users = map (fn (uname, kbs) => {uname = uname, kbs = kbs}) (SM.listItemsi (loop SM.empty))
a41f8250 135 in
4bbdb10e 136 ignore (Unix.reap proc);
137 ListMergeSort.sort (fn ({kbs = kbs1, ...}, {kbs = kbs2, ...}) => kbs1 < kbs2) users
a41f8250 138 end
139
140end