12345678910111213141516171819202122232425262728293031323334353637383940414243444546openLogs_syslogletsyslog_report_commonfacilityhostlennowsend(encode:?len:int->Syslog_message.t->string)=letreporting=reffalsein(* This is local mutable state to avoid reporting log messages while
reporting a log message, which leads to out of memory (if the new log
message is created before the reported one) or busy logging (if the new log
message is created after the reported one) in cases where the code path
is always the same (used to happen in tcpip where IPv4.write logged, which
is used by the syslog reporters in `send` below).
Avoiding this busy loop behaviour is done in an unsafe way: (local) mutable
state (a bool ref), which is read and written without any lock. This works
well in Lwt since there is no bind / blocking operation between the read
and write of `reporting`. Should be revised with a mutex to guard the
access to `reporting`. *)letreportsrclevel~overkmsgf=if!reportingthenbeginover();k()endelsebeginreporting:=true;letsource=Logs.Src.namesrcinlettimestamp=now()inletktags?header_=letfacility=matchLogs.Tag.findLogs_syslog.facilitytagswith|None->facility|facility->facilityinletmsg=message?facility~host~source~tags?headerleveltimestamp(flush())inletbytes=encode~lenmsginletunblock()=over();Lwt.return_unitinLwt.finalize(fun()->sendbytes)unblock|>Lwt.ignore_result;reporting:=false;k()inmsgf@@fun?header?(tags=Logs.Tag.empty)fmt->Format.kfprintf(ktags?header)ppffmtendin{Logs.report}