123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111moduleLevel=struct(* Lowest to highest severity. Silent isn't really a level, but a nice way to
print absolutely no messages. *)typet=Trace|Debug|Info|Warning|Error|Fatal|Unknown|Silentletof_strings=matchString.lowercase_asciiswith|"silent"->SomeSilent|"unknown"->SomeUnknown|"fatal"->SomeFatal|"error"->SomeError|"warning"->SomeWarning|"info"->SomeInfo|"debug"->SomeDebug|"trace"->SomeTrace|_->Noneletto_string=function|Silent->"SILENT"|Unknown->"UNKNOWN"|Fatal->"FATAL"|Error->"ERROR"|Warning->"WARN"|Info->"INFO"|Debug->"DEBUG"|Trace->"TRACE"letto_char=function|Silent->'S'|Unknown->'U'|Fatal->'F'|Error->'E'|Warning->'W'|Info->'I'|Debug->'D'|Trace->'T'endletlog_level=refLevel.Warningletprinter=refprerr_endlineletset_log_levellevel=log_level:=levelletget_log_level()=!log_levelletset_printernew_printer=printer:=new_printertypeprinter=string->unittypemessage=unit->stringletmake_log_messagemsg_levelmsg=letnow=letptime=Ptime_clock.now()inlettz_offset_s=Ptime_clock.current_tz_offset_s()inTime_convert.to_string_humtz_offset_sptimeinletpid=string_of_int@@Unix.getpid()inletcode=Level.to_charmsg_levelinPrintf.sprintf"%c, [%s #%s] %s -- %s"codenowpid(Level.to_stringmsg_level)msgletshould_logmsg_levellogger_threshold=msg_level>=logger_thresholdletlog_messagemsg_levelmsg=ifshould_logmsg_level!log_levelthen!printer@@make_log_messagemsg_level@@msg()letlog_message_stringmsg_levelmsg=ifshould_logmsg_level!log_levelthen!printer@@make_log_messagemsg_levelmsgletunknownmsg=log_messageUnknownmsgletfatalmsg=log_messageFatalmsgleterrormsg=log_messageErrormsgletwarningmsg=log_messageWarningmsgletinfomsg=log_messageInfomsgletdebugmsg=log_messageDebugmsglettracemsg=log_messageTracemsgletsunknownmsg=log_message_stringUnknownmsgletsfatalmsg=log_message_stringFatalmsgletserrormsg=log_message_stringErrormsgletswarningmsg=log_message_stringWarningmsgletsinfomsg=log_message_stringInfomsgletsdebugmsg=log_message_stringDebugmsgletstracemsg=log_message_stringTracemsg