1 structure Stats
:> STATS
=
3 val webbw
= "/etc/stats/webbw"
4 val webbw_last
= "/etc/stats/webbw.last"
5 val webbw_last2
= "/etc/stats/webbw.last2"
7 type host
= {ssl
: bool,
11 fun checkSsl (node
, host
) =
13 val id
= case String.tokens (fn ch
=> ch
= #
".") host
of
14 [] => node ^
"/" ^ host
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
21 case String.fields (fn ch
=> ch
= #
".") host
of
23 (case String.fields (fn ch
=> ch
= #
"_") first
of
24 [first
, "ssl"] => {ssl
= true, hostname
= String.concatWith
"." (first
::rest
),
26 | _
=> {ssl
= false, hostname
= host
, id
= id
})
27 | _
=> {ssl
= false, hostname
= host
, id
= id
}
37 | _
=> raise Fail
"Asked for too old of a bandwidth file"
39 val inf
= TextIO.openIn fname
41 val sum
= case TextIO.inputLine inf
of
42 NONE
=> raise Fail
"Can't read webbw"
45 case String.tokens
Char.isSpace l
of
46 [_
, n
] => valOf (Int.fromString n
)
47 | _
=> raise Fail
"Bad total in webbw"
50 case TextIO.inputLine inf
of
51 (NONE | SOME
"\n") => List.rev L
53 case String.tokens (fn ch
=> Char.isSpace ch
orelse ch
= #
":") l
of
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
)
60 fun splitLast
[] = raise Fail
"Not enough items for splitLast"
61 | splitLast
[x
] = ([], x
)
64 val (l
, x
) = splitLast t
70 case TextIO.inputLine inf
of
73 case String.tokens (fn ch
=> Char.isSpace ch
orelse ch
= #
":" orelse ch
= #
"[" orelse ch
= #
"]" orelse ch
= #
",") l
of
76 val (l
, x
) = splitLast rest
79 case String.tokens (fn ch
=> ch
= #
"@") s
of
80 [host
, node
] => (node
, host
)
81 | _
=> raise Fail ("Bad row in webbw [3]: " ^ s
)
83 readGroups ({user
= d
, hosts
= map (checkSsl
o split
) l
, size
= valOf (Int.fromString x
)} :: L
)
85 | _
=> raise Fail ("Bad row in webbw [4]: " ^ l
)
88 {total
= sum
, vhosts
= readEm
[], users
= readGroups
[]}
89 before TextIO.closeIn inf
92 fun getWebbwUser
{user
, last
} =
94 val {vhosts
, users
, ...} = getWebbw last
96 case List.find (fn {user
= u
, ...} => u
= user
) users
of
97 NONE
=> {total
= 0, vhosts
= []}
98 | SOME
{hosts
, size
, ...} =>
99 {total
= size
, vhosts
= List.filter (fn {host
, ...} => List.exists (fn host
' => host
' = host
) hosts
) vhosts
}
103 type disk
= {uname
: string,
106 structure StringKey
= struct
107 type ord_key
= string
108 val compare
= String.compare
111 structure SM
= BinaryMapFn(StringKey
)
113 fun getDiskUsage () =
115 val proc
= Unix
.execute ("/bin/sh", ["-c", "/usr/bin/vos listvol deleuze"])
116 val inf
= Unix
.textInstreamOf proc
119 case TextIO.inputLine inf
of
122 case String.tokens
Char.isSpace line
of
123 [vol
, _
, _
, kbs
, _
, _
] =>
125 val kbsOld
= case SM
.find (acc
, vol
) of
129 val uname
= case String.tokens (fn ch
=> ch
= #
".") vol
of
131 ((Posix
.SysDB
.getpwnam uname
;
133 handle OS
.SysErr _
=> NONE
)
136 val acc
= case uname
of
138 | SOME uname
=> SM
.insert (acc
, uname
, valOf (Int.fromString kbs
) + kbsOld
)
144 val _
= TextIO.inputLine inf
145 val users
= map (fn (uname
, kbs
) => {uname
= uname
, kbs
= kbs
}) (SM
.listItemsi (loop SM
.empty
))
147 ignore (Unix
.reap proc
);
148 ListMergeSort
.sort (fn ({kbs
= kbs1
, ...}, {kbs
= kbs2
, ...}) => kbs1
< kbs2
) users