Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
logger_impl.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
module type S = sig module IO : Types.IO type addr type handler = addr Handler.Make(IO).t type clock val set_level : Logs.level -> unit val logger : clock -> handler -> handler val debug : 'a Logs.log val info : 'a Logs.log val warning : 'a Logs.log val error : 'a Logs.log end module Make (Clock : Types.PCLOCK) (IO : sig include Types.IO val finally : (unit -> 'a t) -> ('a -> 'b t) -> (exn -> 'b t) -> 'b t end) (Addr : Types.ADDR) : S with module IO = IO and type addr = Addr.t and type clock = Clock.t = struct module IO = IO type addr = Addr.t type handler = addr Handler.Make(IO).t type clock = Clock.t let src = Logs.Src.create "mehari.log" module Log = (val Logs.src_log src) let debug = Log.debug let info = Log.info let warning = Log.warn let error = Log.err let set_level lvl = Logs.Src.set_level src (Some lvl) let iter_backtrace f backtrace = String.split_on_char '\n' backtrace |> List.iter (function "" -> () | l -> f l) let now clock = Clock.now_d_ps clock |> Ptime.v |> Ptime.to_float_s let logger clock handler req = let start = now clock in IO.finally (fun () -> handler req) (fun resp -> Log.info (fun log -> log "Serve '%s' %a" (Request.uri req |> Uri.path_and_query) Addr.pp (Request.ip req)); (match resp.Response.status with | None -> () | Some code -> let elapsed = now clock -. start in Log.info (fun log -> log "%i in %f µs" code (elapsed *. 1e6))); IO.return resp) (fun exn -> let backtrace = Printexc.get_backtrace () in Log.warn (fun log -> log "Aborted by: %s" (Printexc.to_string exn)); iter_backtrace (fun line -> Log.warn (fun log -> log "%s" line)) backtrace; raise exn) end