2018-06-29 16:08:08 +04:00
|
|
|
(*****************************************************************************)
|
|
|
|
(* *)
|
|
|
|
(* Open Source License *)
|
|
|
|
(* Copyright (c) 2018 Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* Permission is hereby granted, free of charge, to any person obtaining a *)
|
|
|
|
(* copy of this software and associated documentation files (the "Software"),*)
|
|
|
|
(* to deal in the Software without restriction, including without limitation *)
|
|
|
|
(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)
|
|
|
|
(* and/or sell copies of the Software, and to permit persons to whom the *)
|
|
|
|
(* Software is furnished to do so, subject to the following conditions: *)
|
|
|
|
(* *)
|
|
|
|
(* The above copyright notice and this permission notice shall be included *)
|
|
|
|
(* in all copies or substantial portions of the Software. *)
|
|
|
|
(* *)
|
|
|
|
(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)
|
|
|
|
(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)
|
|
|
|
(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)
|
|
|
|
(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)
|
|
|
|
(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)
|
|
|
|
(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)
|
|
|
|
(* DEALINGS IN THE SOFTWARE. *)
|
|
|
|
(* *)
|
|
|
|
(*****************************************************************************)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2018-06-08 05:17:23 +04:00
|
|
|
type ('a, 'b) msgf =
|
|
|
|
(('a, Format.formatter, unit, 'b) format4 -> ?tags:Tag.set -> 'a) -> ?tags:Tag.set -> 'b
|
|
|
|
|
|
|
|
type ('a, 'b) log = ('a, 'b) msgf -> 'b
|
|
|
|
|
|
|
|
module type MESSAGE = sig
|
|
|
|
val name: string
|
|
|
|
end
|
|
|
|
|
2018-06-16 01:26:51 +04:00
|
|
|
type level = Lwt_log_core.level =
|
|
|
|
| Debug
|
|
|
|
(** Debugging message. They can be automatically removed by the
|
|
|
|
syntax extension. *)
|
|
|
|
| Info
|
|
|
|
(** Informational message. Suitable to be displayed when the
|
|
|
|
program is in verbose mode. *)
|
|
|
|
| Notice
|
|
|
|
(** Same as {!Info}, but is displayed by default. *)
|
|
|
|
| Warning
|
|
|
|
(** Something strange happend *)
|
|
|
|
| Error
|
|
|
|
(** An error message, which should not means the end of the
|
|
|
|
program. *)
|
|
|
|
| Fatal
|
|
|
|
|
2018-06-08 05:17:23 +04:00
|
|
|
type log_section = ..
|
|
|
|
|
|
|
|
type log_message = {
|
|
|
|
section : log_section ;
|
2018-06-16 01:26:51 +04:00
|
|
|
level : level ;
|
2018-06-29 07:00:19 +04:00
|
|
|
text : string option ;
|
2018-06-08 05:17:23 +04:00
|
|
|
tags : Tag.set ;
|
|
|
|
}
|
|
|
|
|
2018-06-14 02:22:17 +04:00
|
|
|
type tap_id = int
|
|
|
|
let next_tap : int ref = ref 0
|
2018-06-08 05:17:23 +04:00
|
|
|
|
2018-06-14 02:22:17 +04:00
|
|
|
type tap = {
|
|
|
|
id : tap_id ;
|
|
|
|
process : log_message -> unit ;
|
|
|
|
}
|
|
|
|
|
|
|
|
let taps : tap list ref = ref []
|
|
|
|
|
|
|
|
let tap process = let id = !next_tap in
|
|
|
|
begin
|
|
|
|
next_tap := id + 1 ;
|
|
|
|
taps := { id ; process } :: !taps ;
|
|
|
|
id
|
|
|
|
end
|
|
|
|
|
|
|
|
let untap x = taps := List.filter (fun tap -> tap.id <> x) !taps
|
2018-06-08 05:17:23 +04:00
|
|
|
|
2018-06-14 02:22:17 +04:00
|
|
|
let call_taps v = List.iter (fun tap -> tap.process v) !taps
|
2018-06-08 05:17:23 +04:00
|
|
|
|
|
|
|
module type SEMLOG = sig
|
|
|
|
|
|
|
|
type log_section += Section
|
|
|
|
|
|
|
|
module Tag = Tag
|
|
|
|
|
|
|
|
val debug: ('a, unit) log
|
|
|
|
val log_info: ('a, unit) log
|
|
|
|
val log_notice: ('a, unit) log
|
|
|
|
val warn: ('a, unit) log
|
|
|
|
val log_error: ('a, unit) log
|
|
|
|
val fatal_error: ('a, unit) log
|
|
|
|
|
|
|
|
val lwt_debug: ('a, unit Lwt.t) log
|
|
|
|
val lwt_log_info: ('a, unit Lwt.t) log
|
|
|
|
val lwt_log_notice: ('a, unit Lwt.t) log
|
|
|
|
val lwt_warn: ('a, unit Lwt.t) log
|
|
|
|
val lwt_log_error: ('a, unit Lwt.t) log
|
|
|
|
val lwt_fatal_error: ('a, unit Lwt.t) log
|
|
|
|
|
|
|
|
val event : string Tag.def
|
|
|
|
val exn : exn Tag.def
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
let sections = ref []
|
|
|
|
|
|
|
|
let event = Tag.def ~doc:"String identifier for the class of event being logged" "event" Format.pp_print_text
|
|
|
|
let exn = Tag.def ~doc:"Exception which was detected" "exception" (fun f e -> Format.pp_print_text f (Printexc.to_string e))
|
|
|
|
|
|
|
|
module Make_semantic(S : MESSAGE) : SEMLOG = struct
|
|
|
|
|
|
|
|
include S
|
|
|
|
|
|
|
|
type log_section += Section
|
|
|
|
|
|
|
|
module Tag = Tag
|
|
|
|
|
|
|
|
let () = sections := S.name :: !sections
|
|
|
|
let section = Lwt_log_core.Section.make S.name
|
|
|
|
|
|
|
|
|
|
|
|
let log_f ~level =
|
2018-06-29 07:24:39 +04:00
|
|
|
if level < Lwt_log_core.Section.level section then
|
|
|
|
fun format ?(tags=Tag.empty) ->
|
|
|
|
Format.ikfprintf
|
|
|
|
(fun _ -> call_taps { section = Section ; level ; text = None ; tags }; Lwt.return_unit)
|
|
|
|
Format.std_formatter
|
|
|
|
format
|
|
|
|
else
|
2018-06-08 05:17:23 +04:00
|
|
|
fun format ?(tags=Tag.empty) ->
|
|
|
|
Format.kasprintf
|
|
|
|
(fun text ->
|
2018-06-29 07:00:19 +04:00
|
|
|
call_taps { section = Section ; level ; text = Some text ; tags };
|
2018-06-08 05:17:23 +04:00
|
|
|
Lwt_log_core.log ~section ~level text)
|
|
|
|
format
|
2018-06-29 07:24:39 +04:00
|
|
|
|
|
|
|
let ign_log_f ~level =
|
|
|
|
if level < Lwt_log_core.Section.level section then
|
2018-06-08 05:17:23 +04:00
|
|
|
fun format ?(tags=Tag.empty) ->
|
|
|
|
Format.ikfprintf
|
2018-06-29 07:24:39 +04:00
|
|
|
(fun _ -> call_taps { section = Section ; level ; text = None ; tags })
|
2018-06-08 05:17:23 +04:00
|
|
|
Format.std_formatter
|
|
|
|
format
|
2018-06-29 07:24:39 +04:00
|
|
|
else
|
2018-06-08 05:17:23 +04:00
|
|
|
fun format ?(tags=Tag.empty) ->
|
|
|
|
Format.kasprintf
|
|
|
|
(fun text ->
|
2018-06-29 07:00:19 +04:00
|
|
|
call_taps { section = Section ; level ; text = Some text ; tags };
|
2018-06-08 05:17:23 +04:00
|
|
|
Lwt_log_core.ign_log ~section ~level text)
|
|
|
|
format
|
|
|
|
|
|
|
|
let debug f = f (ign_log_f ~level:Lwt_log_core.Debug) ?tags:(Some Tag.empty)
|
|
|
|
let log_info f = f (ign_log_f ~level:Lwt_log_core.Info) ?tags:(Some Tag.empty)
|
|
|
|
let log_notice f = f (ign_log_f ~level:Lwt_log_core.Notice) ?tags:(Some Tag.empty)
|
|
|
|
let warn f = f (ign_log_f ~level:Lwt_log_core.Warning) ?tags:(Some Tag.empty)
|
|
|
|
let log_error f = f (ign_log_f ~level:Lwt_log_core.Error) ?tags:(Some Tag.empty)
|
|
|
|
let fatal_error f = f (ign_log_f ~level:Lwt_log_core.Fatal) ?tags:(Some Tag.empty)
|
|
|
|
|
|
|
|
let lwt_debug f = f (log_f ~level:Lwt_log_core.Debug) ?tags:(Some Tag.empty)
|
|
|
|
let lwt_log_info f = f (log_f ~level:Lwt_log_core.Info) ?tags:(Some Tag.empty)
|
|
|
|
let lwt_log_notice f = f (log_f ~level:Lwt_log_core.Notice) ?tags:(Some Tag.empty)
|
|
|
|
let lwt_warn f = f (log_f ~level:Lwt_log_core.Warning) ?tags:(Some Tag.empty)
|
|
|
|
let lwt_log_error f = f (log_f ~level:Lwt_log_core.Error) ?tags:(Some Tag.empty)
|
|
|
|
let lwt_fatal_error f = f (log_f ~level:Lwt_log_core.Fatal) ?tags:(Some Tag.empty)
|
|
|
|
|
|
|
|
let event = event
|
|
|
|
let exn = exn
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
module type LOG = sig
|
|
|
|
|
2018-06-08 05:17:23 +04:00
|
|
|
type log_section += Section
|
|
|
|
|
2016-09-08 21:13:10 +04:00
|
|
|
val debug: ('a, Format.formatter, unit, unit) format4 -> 'a
|
|
|
|
val log_info: ('a, Format.formatter, unit, unit) format4 -> 'a
|
|
|
|
val log_notice: ('a, Format.formatter, unit, unit) format4 -> 'a
|
|
|
|
val warn: ('a, Format.formatter, unit, unit) format4 -> 'a
|
|
|
|
val log_error: ('a, Format.formatter, unit, unit) format4 -> 'a
|
2017-11-08 19:02:19 +04:00
|
|
|
val fatal_error: ('a, Format.formatter, unit, unit) format4 -> 'a
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
val lwt_debug: ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a
|
|
|
|
val lwt_log_info: ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a
|
|
|
|
val lwt_log_notice: ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a
|
|
|
|
val lwt_warn: ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a
|
|
|
|
val lwt_log_error: ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a
|
2018-01-22 18:25:48 +04:00
|
|
|
val lwt_fatal_error: ('a, Format.formatter, unit, unit Lwt.t) format4 -> 'a
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2017-01-30 22:10:16 +04:00
|
|
|
let sections = ref []
|
|
|
|
|
2018-06-29 07:08:14 +04:00
|
|
|
module Make_unregistered(S : MESSAGE) : LOG = struct
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2018-02-08 13:51:01 +04:00
|
|
|
let section = Lwt_log_core.Section.make S.name
|
2018-06-08 05:17:23 +04:00
|
|
|
type log_section += Section
|
|
|
|
|
|
|
|
let log_f
|
|
|
|
?exn ?(section = Lwt_log_core.Section.main) ?location ?logger ~level format =
|
|
|
|
if level < Lwt_log_core.Section.level section then
|
|
|
|
Format.ikfprintf (fun _ -> Lwt.return_unit) Format.std_formatter format
|
|
|
|
else
|
|
|
|
Format.kasprintf
|
|
|
|
(fun msg ->
|
2018-06-29 07:00:19 +04:00
|
|
|
call_taps { section = Section ; level ; text = Some msg ; tags = Tag.empty };
|
2018-06-08 05:17:23 +04:00
|
|
|
Lwt_log_core.log ?exn ~section ?location ?logger ~level msg)
|
|
|
|
format
|
|
|
|
|
|
|
|
let ign_log_f
|
|
|
|
?exn ?(section = Lwt_log_core.Section.main) ?location ?logger ~level format =
|
|
|
|
if level < Lwt_log_core.Section.level section then
|
|
|
|
Format.ikfprintf (fun _ -> ()) Format.std_formatter format
|
|
|
|
else
|
|
|
|
Format.kasprintf
|
|
|
|
(fun msg ->
|
2018-06-29 07:00:19 +04:00
|
|
|
call_taps { section = Section ; level ; text = Some msg ; tags = Tag.empty };
|
2018-06-08 05:17:23 +04:00
|
|
|
Lwt_log_core.ign_log ?exn ~section ?location ?logger ~level msg)
|
|
|
|
format
|
2018-02-08 13:51:01 +04:00
|
|
|
|
|
|
|
let debug fmt = ign_log_f ~section ~level:Lwt_log_core.Debug fmt
|
|
|
|
let log_info fmt = ign_log_f ~section ~level:Lwt_log_core.Info fmt
|
|
|
|
let log_notice fmt = ign_log_f ~section ~level:Lwt_log_core.Notice fmt
|
|
|
|
let warn fmt = ign_log_f ~section ~level:Lwt_log_core.Warning fmt
|
|
|
|
let log_error fmt = ign_log_f ~section ~level:Lwt_log_core.Error fmt
|
|
|
|
let fatal_error fmt = ign_log_f ~section ~level:Lwt_log_core.Fatal fmt
|
|
|
|
|
|
|
|
let lwt_debug fmt = log_f ~section ~level:Lwt_log_core.Debug fmt
|
|
|
|
let lwt_log_info fmt = log_f ~section ~level:Lwt_log_core.Info fmt
|
|
|
|
let lwt_log_notice fmt = log_f ~section ~level:Lwt_log_core.Notice fmt
|
|
|
|
let lwt_warn fmt = log_f ~section ~level:Lwt_log_core.Warning fmt
|
|
|
|
let lwt_log_error fmt = log_f ~section ~level:Lwt_log_core.Error fmt
|
|
|
|
let lwt_fatal_error fmt = log_f ~section ~level:Lwt_log_core.Fatal fmt
|
2016-09-08 21:13:10 +04:00
|
|
|
|
|
|
|
end
|
|
|
|
|
2018-06-29 07:08:14 +04:00
|
|
|
module Make(S : MESSAGE) : LOG = struct
|
2018-06-27 04:06:09 +04:00
|
|
|
|
|
|
|
let () = sections := S.name :: !sections
|
|
|
|
include Make_unregistered(S)
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2018-06-08 05:17:23 +04:00
|
|
|
module Core = struct
|
|
|
|
include Make_semantic(struct let name = "core" end)
|
|
|
|
|
|
|
|
let worker = Tag.def ~doc:"Name of affected worker" "worker" Format.pp_print_text
|
|
|
|
end
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2018-02-08 13:51:01 +04:00
|
|
|
type template = Lwt_log_core.template
|
|
|
|
let default_template = "$(date) - $(section): $(message)"
|