Fix outstanding bugs
[pkg-ocaml-ocsigen.git] / examples / monitoring.ml
blobf4a15afe983c3d36d4c8010709d480e9be7b299f
1 (* Ocsigen
2 * Copyright (C) 2005 Vincent Balat
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation, with linking exception;
7 * either version 2.1 of the License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 (* A page providing infos about the server (number of sessions, uptime...) *)
21 open Ocsigen_extensions (* for profiling info *)
22 open Eliom_predefmod.Xhtml
23 open Eliom_predefmod
24 open Eliom_services
25 open Eliom_parameters
26 open Eliom_sessions
27 open Unix
28 open Lwt
30 let launchtime = Unix.time ()
32 let _ =
33 register_new_service
34 ~path:[]
35 ~get_params:unit
36 (fun sp () () ->
37 let tm = Unix.gmtime ((Unix.time ()) -. launchtime) in
38 let year = if tm.tm_year>0 then (string_of_int (tm.tm_year - 70))^" years, "
39 else "" in
40 let days = (string_of_int (tm.tm_yday))^" days, " in
41 let hour = (string_of_int (tm.tm_hour))^" hours, " in
42 let min = (string_of_int (tm.tm_min))^" min, " in
43 let sec = (string_of_int (tm.tm_sec))^" seconds" in
44 let uptime = year^days^hour^min^sec in
46 let stat = Gc.quick_stat () in
47 let size = string_of_int (stat.Gc.heap_words) in
48 let maxsize = string_of_int (stat.Gc.top_heap_words) in
49 let compactions = string_of_int stat.Gc.compactions in
50 let mincol = string_of_int stat.Gc.minor_collections in
51 let majcol = string_of_int stat.Gc.major_collections in
52 let top_heap_words = string_of_int stat.Gc.top_heap_words in
53 let pid = string_of_int (Unix.getpid ()) in
54 let fd =
55 try
56 let dir = Unix.opendir
57 ("/proc/"^pid^"/fd") in
58 let rec aux v =
59 try ignore ((* print_endline *) (readdir dir)); aux (v+1)
60 with End_of_file -> v
62 let r =
63 try string_of_int ((aux 0) - 2)
64 with e -> ("(Error: "^(Printexc.to_string e)^")") in
65 Unix.closedir dir;
66 Some r
67 with _ -> None
69 let nssess = Eliom_sessions.number_of_service_sessions sp in
70 let ndsess = Eliom_sessions.number_of_volatile_data_sessions sp in
71 let ntables = Eliom_sessions.number_of_tables () in
72 let ntableselts = Eliom_sessions.number_of_table_elements () in
73 Eliom_sessions.number_of_persistent_data_sessions () >>=
74 (fun nbperssess ->
75 let nbperstab = Eliom_sessions.number_of_persistent_tables () in
76 Eliom_sessions.number_of_persistent_table_elements () >>=
77 (fun nbperstabel ->
78 let dot = <:xmllist< . >> in
79 let list1 a l = <:xmllist< with, respectively
80 $str:List.fold_left
81 (fun deb i -> deb^", "^(string_of_int i))
82 (string_of_int a) l $
83 elements inside. >>
85 let list2 (n,a) l = <:xmllist< with, respectively
86 $str:List.fold_left
87 (fun deb (s, i) -> deb^", "^s^" : "^(string_of_int i))
88 (n^" : "^(string_of_int a)) l$
89 elements inside. >>
91 Eliommod_sessiongroups.Pers.length () >>= fun persgrplength ->
92 Lwt.return
94 <html>
95 <head>
96 </head>
97 <body>
98 <h1>Ocsigen server monitoring</h1>
99 <p>Version of Ocsigen: $str:Ocsigen_config.version_number$</p>
100 <p>Uptime: $str:uptime$.</p>
101 <p>The number of sessions is not available in this version of Eliom.</p>
102 <p>Number of clients connected:
103 $str:(string_of_int (get_number_of_connected ()))$.</p>
104 <p>PID : $str:pid$</p>
105 <p>$str:match fd with
106 None -> "Information on file descriptors not accessible in /proc."
107 | Some fd -> fd^" file descriptors opened."$</p>
108 <h2>GC</h2>
109 <p>Size of major heap: $str:size$ words (max: $str:maxsize$).</p>
110 <p>Since the beginning:</p>
111 <ul><li>$str:mincol$ minor garbage collections,</li>
112 <li> $str:majcol$ major collections,</li>
113 <li>$str:compactions$ compactions of the heap.</li>
114 <li>Maximum size reached by the major heap: $str:top_heap_words$ words.</li>
115 </ul>
116 <h2>Lwt threads</h2>
117 <p> </p>
118 <h2>Preemptive threads</h2>
119 <p>There are currently $str:(string_of_int (Lwt_preemptive.nbthreads ()))$
120 detached threads running
121 (min $str:(string_of_int (Ocsigen_config.get_minthreads ()))$,
122 max $str:(string_of_int (Ocsigen_config.get_maxthreads ()))$),
123 from which $str:(string_of_int (Lwt_preemptive.nbthreadsbusy ()))$ are busy.
124 $str:(string_of_int (Lwt_preemptive.nbthreadsqueued ()))$ computations
125 queued (max
126 $str:(string_of_int (Ocsigen_config.get_max_number_of_threads_queued ()))$).</p>
127 <h2>HTTP connexions</h2>
128 <p>Number of
129 $str:"" (* string_of_int
130 (Ocsigen_http_com.Timeout.nb_threads_waiting_timeout ()) *)$
131 connexions waiting for timeout: not implemented in that version</p>
132 <h2>Eliom sessions</h2>
133 <p>There are $str:string_of_int nssess$ Eliom service sessions opened,
134 $str:string_of_int ndsess$ Eliom in memory data sessions opened.<br/>
135 There are $str:string_of_int ntables$ Eliom in memory tables created $list:
136 (match ntableselts with
137 | [] -> dot
138 | a::l -> list1 a l)
140 </p>
141 <p>There are $str:string_of_int nbperssess$
142 Eliom persistent sessions opened.<br/>
143 and $str:string_of_int nbperstab$ Eliom
144 persistent tables created $list:
145 (match nbperstabel with
146 | [] -> dot
147 | a::l -> list2 a l)
148 $</p>
149 <p>Number of session groups:</p>
150 <ul>
151 <li>Service sessions: $str: string_of_int (Eliommod_sessiongroups.Serv.length ())$</li>
152 <li>Volatile data sessions: $str: string_of_int (Eliommod_sessiongroups.Data.length ())$</li>
153 <li>Persistent data sessions: $str: string_of_int persgrplength$</li>
154 </ul>
155 </body>
156 </html>
157 >>)))