123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206(* Ocsigen
* http://www.ocsigen.org
* Copyright (C) 2014 Hugo Heuzard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, with linking exception;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*)(* provides infos about the server (number of sessions, uptime...) *)letuptime=letlaunchtime=Unix.time()infun()->Unix.time()-.launchtimeletpid()=Unix.getpid()letfd~pid=tryleta=Array.length(Sys.readdir(Printf.sprintf"/proc/%d/fd"pid))-2in`Okawithe->`Error(Printexc.to_stringe)letppffmt=Printf.ksprintfEliom_content.Html.D.txtfmtletformat_durationt=letopenUnixinlettm=gmtimetinletyear=iftm.tm_year>0thenstring_of_int(tm.tm_year-70)^" years, "else""inletdays=string_of_inttm.tm_yday^" days, "inlethour=string_of_inttm.tm_hour^" hours, "inletmin=string_of_inttm.tm_min^" min, "inletsec=string_of_inttm.tm_sec^" seconds"inyear^days^hour^min^secopenEliom_content.Html.Fletgeneral_stats()=letpid=pid()indiv[dl[dt[ppf"Version of Ocsigen"];dd[ppf"%s"Ocsigen_config.version_number];dt[ppf"Uptime"];dd[ppf"%s"(format_duration(uptime()))];dt[ppf"PID"];dd[ppf"%d"pid];dt[ppf"Numbers of file descriptors"];dd[(matchfd~pidwith|`Errors->ppf"Information on file descriptors not accessible (%s)."s|`Okfd->ppf"%d file descriptors opened."fd)]]]letgc_stats()=letstat=Gc.quick_stat()indiv[ul[li[ppf"%d minor garbage collections."stat.Gc.minor_collections];li[ppf"%d major collections."stat.Gc.major_collections];li[ppf"%d compactions of the heap."stat.Gc.compactions];li[ppf"%d words in the the major heap (max %d)."stat.Gc.heap_wordsstat.Gc.top_heap_words]]]letlwt_stats()=div[ul[li[ppf"%d lwt threads waiting for inputs"(Lwt_engine.readable_count())];li[ppf"%d lwt threads waiting for outputs"(Lwt_engine.writable_count())];li[ppf"%d sleeping lwt threads"(Lwt_engine.timer_count())]]]letpreemptive_thread_stats()=div[ul[li[ppf"%d detached threads (min %d,max %d)."(Lwt_preemptive.nbthreads())(Ocsigen_config.get_minthreads())(Ocsigen_config.get_maxthreads())];li[ppf"%d are busy threads."(Lwt_preemptive.nbthreadsbusy())];li[ppf"%d computations queued (max %d)."(Lwt_preemptive.nbthreadsqueued())(Ocsigen_config.get_max_number_of_threads_queued())]]]lethttp_stats()=lethosts=Ocsigen_extensions.get_hosts()indiv[ul[li[ppf"%d open connection"(Ocsigen_extensions.get_number_of_connected())]];h3[txt"Hosts"];ul(List.map(fun(vhosts,config,_)->letall_vhost=String.concat", "(List.map(fun(vhost,_,vport)->letoptport=matchvportwith|None->""|Somep->Printf.sprintf":%d"pinPrintf.sprintf"%s%s ( default: %s, http: %d, https: %d )"vhostoptportconfig.Ocsigen_extensions.default_hostnameconfig.Ocsigen_extensions.default_httpportconfig.Ocsigen_extensions.default_httpsport)vhosts)inli[txt(all_vhost:string)])hosts)]leteliom_stats()=let%lwtpersist_nb_of_groups=Eliommod_sessiongroups.Pers.nb_of_groups()inlet%lwtnumber_of_persistent_data_cookies=Eliom_state.number_of_persistent_data_cookies()inLwt.return(div[h3[ppf"Sessions"];ul[li[ppf"%d service cookies."(Eliom_state.number_of_service_cookies())];li[ppf"%d volatile data cookies."(Eliom_state.number_of_volatile_data_cookies())];li[ppf"%d volatile data tables (volatile Eliom references)."(Eliom_state.number_of_tables())];li[ppf"%d persistent data cookies."number_of_persistent_data_cookies];li[ppf"%d persistent data tables (persistent data reference)."(Eliom_state.number_of_persistent_tables())]];h3[ppf"Client processes"];p[em[txt"Not implemented yet"]];h3[ppf"Session groups"];ul[li[ppf"%d service session groups."(Eliommod_sessiongroups.Serv.nb_of_groups())];li[ppf"%d volatile data session groups."(Eliommod_sessiongroups.Data.nb_of_groups())];li[ppf"%d persistent data session groups."persist_nb_of_groups];li[ppf"Session groups: %s"(String.concat", "(Eliom_state.Ext.get_session_group_list()))]]])letcontent_div()=let%lwteliom_stats=eliom_stats()inLwt.return(div[h1[ppf"Ocsigen server monitoring"];general_stats();h2[ppf"HTTP connexions"];http_stats();h2[ppf"Eliom sessions"];eliom_stats;h2[ppf"GC"];gc_stats();h2[ppf"Lwt threads"];lwt_stats();h2[ppf"Preemptive threads"];preemptive_thread_stats()])letcontent_html()=let%lwtcontent_div=content_div()inLwt.return(html(head(title(txt"Server monitoring"))[link~rel:[`Stylesheet]~href:(uri_of_string(fun()->"//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css"))();link~rel:[`Stylesheet]~href:(uri_of_string(fun()->"//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap-theme.min.css"))()])(body[div~a:[a_class["container"]][content_div]]))