Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file batLogger.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214(* -*- Mode: Caml; indent-tabs-mode: nil -*- *)(******************************************************************************)(* Copyright (c) 2009, Metaweb Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY METAWEB TECHNOLOGIES ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL METAWEB TECHNOLOGIES BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************)openBatPrintftypelog={name:string;mutablelevel:int;}typelevel=NONE|FATAL|ERROR|WARN|NOTICE|INFO|DEBUGtypeevent =string *(string*string)listtypeformatter=log->level->event->float->unit(******************************************************************************)(** log utilities *)letint_of_level=function|NONE->0|FATAL->1|ERROR->2|WARN->3|NOTICE->4|INFO->5|DEBUG->6letlevel_of_int=function|0->NONE |1->FATAL|2->ERROR|3->WARN|4->NOTICE|5->INFO|6->DEBUG|i->failwith("invalidlevel: "^string_of_inti)letname_of_level=function|NONE->"NONE"|FATAL->"FATAL"|ERROR->"ERROR"|WARN->"WARN"|NOTICE->"NOTICE"|INFO->"INFO"|DEBUG->"DEBUG"letlevel_of_name=function|"NONE"->NONE|"FATAL"->FATAL|"ERROR"->ERROR|"WARN"->WARN|"NOTICE"->NOTICE|"INFO"->INFO|"DEBUG"->DEBUG|n->failwith("invalidlevel: "^n)letformat_timestampoutts=lettm=Unix.gmtime tsinletus,_=modf tsinfprintfout"%04d-%02d-%02dT%02d:%02d:%02d.%06dZ"(1900+tm.Unix.tm_year)(1+tm.Unix.tm_mon)(tm.Unix.tm_mday)(tm.Unix.tm_hour)(tm.Unix.tm_min)(tm.Unix.tm_sec)(int_of_float(1_000_000.*.us))(******************************************************************************)(** log modules *)letlogs=Hashtbl.create16letdefault_level=ref(int_of_levelINFO)let make_logname=tryHashtbl.findlogsnamewithNot_found ->letlm={name=name;level=!default_level}inHashtbl.replacelogsnamelm;lmletlog_enablelmlev=lm.level<-int_of_levellevletlog_enabledlmlev =letlev_no=int_of_level levinlev_no<=lm.levelletlog_name lm=lm.nameletlog_levellm=level_of_intlm.level(******************************************************************************)(** log formatters *)letdepth=ref0letformatters:(string *formatter)listref=ref[]letregister_formatternamef=formatters:=(name,f)::!formattersletunregister_formattername=formatters:=List.remove_assocname!formattersletrecformat_kvloc=function|[]->()|(k,v)::rest->fprintfoc"\t%s:%s"kv;format_kvlocrestletmake_std_formatteroclmlev(event_name,event_args)timestamp=fprintfoc"D:%a\tE:%s.%s\tL:%s%a\n%!"(*D:*)format_timestamptimestamp(*E:*)lm.nameevent_name(*L:*)(name_of_levellev)format_kvlevent_argsletstderr_formatter=make_std_formatterBatIO.stderrletnull_formatter_lm_lev_event_timestamp=()letformat_indent ocdepth=for_i=0todepth dofprintfoc"| "doneletmake_dbg_formatter oclmlev(event_name,event_args)_timestamp =letindent =tryint_of_string (List.assoc"I"event_args)with_->0inletargs=List.remove_assoc"I"event_argsinfprintfoc"### %a%s.%s %a [%s]\n%!" format_indentindent(log_namelm)event_nameformat_kvlargs(name_of_levellev)let dbg_formatterlmlevepts=make_dbg_formatterBatIO.stderrlmlevepts(******************************************************************************)(** log events *)letloglmlevevent_fun=iflog_enabled lmlevthenlettime=Unix.gettimeofday()inletevent_name,event_args=event_fun ()inletevent=event_name,("I",string_of_int!depth)::event_argsinList.iter(fun(_name,fmt)->fmt lmleveventtime)!formattersletwith_loglmlevevent_fun?resultbody=iflog_enabledlmlevthenbegintryloglmlevevent_fun;incr depth;letrv=body()indecrdepth;loglmlev(fun()->letevent_name,event_args=event_fun ()inletresult_str =matchresultwith|Somef->frv|None->"-"inevent_name,("RESULT",result_str)::event_args);rvwithexn ->decrdepth;loglmlev(fun()->letevent_name,event_args=event_fun ()inevent_name,("EXN",Printexc.to_stringexn)::event_args);raiseexnendelsebody()(******************************************************************************)(** logger initialization *)letinitname_level_listformatter=List.iter(fun(name,level)->letlm=make_log nameinlog_enablelmlevel)name_level_list;register_formatter"default"formatterletinit_from_stringname_level_stringformatter=letinit_key_valuess=tryletname_ss,level_ss=BatSubstring.splitl(func->c<>':')ssinletname =BatSubstring.to_stringname_ssinletlevel =level_of_name (BatSubstring.to_stringlevel_ss)inletlm=make_log nameinlog_enablelmlevelwithNot_found->tryletlevel=level_of_name(BatSubstring.to_stringss)indefault_level :=int_of_levellevel;Hashtbl.iter(fun_namelm->log_enable lmlevel)logswithFailure_->failwith("invalid log initialization: "^BatSubstring.to_stringss)inList.iterinit_key_value (BatSubstring.split_on_comma (BatSubstring.of_string name_level_string));register_formatter "default"formatter(******************************************************************************)(*
let test =
let lm = make_log "test" in
let direct () =
log lm NOTICE (fun () -> "hello", []);
log lm DEBUG (fun () -> "debug msg1", []);
log lm ERROR (fun () -> "error msg1", []);
log lm ERROR (fun () -> "ok", ["ARG1", string_of_int 234]);
in
let rec run () =
direct ();
Unix.sleep 3;
run ()
in run ()
*)(******************************************************************************)