package b0
Software construction and deployment kit
Install
dune-project
Dependency
Authors
Maintainers
Sources
b0-0.0.6.tbz
sha512=e9aa779e66c08fc763019f16d4706f465d16c05d6400b58fbd0313317ef33ddea51952e2b058db28e65f7ddb7012f328c8bf02d8f1da17bb543348541a2587f0
doc/src/b0.std/b0__log.ml.html
Source file b0__log.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 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
(*--------------------------------------------------------------------------- Copyright (c) 2025 The more programmers. All rights reserved. SPDX-License-Identifier: ISC ---------------------------------------------------------------------------*) (* Reporting levels *) type level = Quiet | Stdout | Stderr | Error | Warning | Info | Debug let current_level = Atomic.make Warning let level () = Atomic.get current_level let set_level l = Atomic.set current_level l let level_to_string = function | Quiet -> "quiet" | Stdout -> "stdout" | Stderr -> "stderr" | Error -> "error" | Warning -> "warning" | Info -> "info" | Debug -> "debug" let level_of_string s = match String.trim s with | "quiet" -> Ok Quiet | "stdout" -> Ok Stdout | "stderr" -> Ok Stderr | "error" -> Ok Error | "warning" -> Ok Warning | "info" -> Ok Info | "debug" -> Ok Debug | e -> let pp_level = B0__fmt.code in let kind = B0__fmt.any "log level" in let dom = ["quiet"; "stdout"; "stderr"; "error"; "warning"; "info"; "debug"] in let unknown = B0__fmt.(unknown' ~kind pp_level ~hint:must_be) in B0__fmt.error "%a" unknown (e, dom) (* Default reporter *) let header_stdout_style = [`Fg `Cyan] let header_stderr_style = [`Fg `Cyan] let header_err_style = [`Fg `Red] let header_warn_style = [`Fg `Yellow] let header_info_style = [`Fg `Blue] let header_debug_style = [`Faint; `Fg `Magenta] let error_style = `Bold :: header_err_style let warning_style = `Bold :: header_warn_style let info_style = `Bold :: header_info_style let debug_style = `Bold :: header_debug_style let pp_level_header level ppf header = match level with | Stdout -> B0__fmt.st header_stdout_style ppf header | Stderr -> B0__fmt.st header_stderr_style ppf header | Error -> B0__fmt.st header_err_style ppf header | Warning -> B0__fmt.st header_warn_style ppf header | Info -> B0__fmt.st header_info_style ppf header | Debug -> B0__fmt.st header_debug_style ppf header | Quiet -> () let pp_level ppf level = match level with | Stdout | Stderr -> () | Error -> B0__fmt.st error_style ppf "Error" | Warning -> B0__fmt.st warning_style ppf "Warning" | Info -> B0__fmt.st info_style ppf "Info" | Debug -> B0__fmt.st debug_style ppf "Debug" | Quiet -> () let exec = (* We use the name as given to execv because sometimes executables masquerade as others by execv'ing. We want to use the name of the program not of the masquerade (which may be meaningless). *) (* assert (Array.length Sys.argv > 0) *) Filename.basename Sys.argv.(0) let default_kmsg k level msgf = msgf @@ fun ?header fmt -> let ppf = if level = Stdout then B0__fmt.stdout else B0__fmt.stderr in let finish ppf = Format.pp_close_box ppf (); Format.pp_close_box ppf (); B0__fmt.flush_nl ppf (); k () in Format.pp_open_box ppf 0; begin match header with | None -> begin match level with | Stderr | Stdout -> Format.pp_open_box ppf 0 | level -> (* "%s: @[%a: " *) B0__fmt.string ppf exec; B0__fmt.string ppf ": "; Format.pp_open_box ppf 0; pp_level ppf level; B0__fmt.string ppf ": "; end | Some header -> if header = "" then Format.pp_open_box ppf 0 else begin (* "%s: @[[%s] " *) B0__fmt.string ppf exec; B0__fmt.string ppf ": "; Format.pp_open_box ppf 0; B0__fmt.char ppf '['; pp_level_header level ppf header; B0__fmt.string ppf "] "; end end; B0__fmt.kpf finish ppf fmt (* Log monitoring *) let err_count' = Atomic.make 0 let err_count () = Atomic.get err_count' let warn_count' = Atomic.make 0 let warn_count () = Atomic.get warn_count' (* Log functions *) type ('a, 'b) msgf = (?header:string -> ('a, Format.formatter, unit, 'b) format4 -> 'a) -> 'b type 'a log = ('a, unit) msgf -> unit type reporter = { kmsg : 'a 'b. (unit -> 'b) -> level -> ('a, 'b) msgf -> 'b } let reporter_default = { kmsg = default_kmsg } let reporter = Atomic.make reporter_default let kmsg k level msgf = match level with | Error -> Atomic.incr err_count'; if Atomic.get current_level < Error then k () else (Atomic.get reporter).kmsg k level msgf | Warning -> Atomic.incr warn_count'; if Atomic.get current_level < Warning then k () else (Atomic.get reporter).kmsg k level msgf | _ -> let current_level = Atomic.get current_level in if current_level = Quiet || current_level < level then k () else (Atomic.get reporter).kmsg k level msgf let kunit _ = () let msg level msgf = kmsg kunit level msgf let quiet msgf = kmsg kunit Quiet msgf let stdout msgf = kmsg kunit Stdout msgf let stderr msgf = kmsg kunit Stderr msgf let err msgf = kmsg kunit Error msgf let warn msgf = kmsg kunit Warning msgf let info msgf = kmsg kunit Info msgf let debug msgf = kmsg kunit Debug msgf (* Logging result errors *) let pp_err = B0__fmt.lines let if_error ?(level = Error) ?header ~use = function | Ok v -> v | Error msg -> kmsg (fun _ -> use) level (fun m -> m ?header "%a" pp_err msg) let if_error' ?(level = Error) ?header ~use = function | Ok _ as v -> v | Error msg -> kmsg (fun _ -> Ok use) level (fun m -> m ?header "%a" pp_err msg) let if_error_pp pp ?(level = Error) ?header ~use = function | Ok v -> v | Error e -> kmsg (fun _ -> use) level (fun m -> m ?header "%a" pp e) let if_error_pp' pp ?(level = Error) ?header ~use = function | Ok _ as v -> v | Error e -> kmsg (fun _ -> Ok use) level (fun m -> m ?header "%a" pp e) (* Logging timings *) (* The churn here is because we have a recursive dep on Os.Mtime *) type time_func = { time : 'a 'b. ?level:level -> ('a -> (('b, Format.formatter, unit, 'a) format4 -> 'b) -> 'a) -> (unit -> 'a) -> 'a } let time_func_init = { time = fun ?(level = Info) m f -> assert false } let time_func = Atomic.make time_func_init let set_time_func time = Atomic.set time_func time let time ?level fmt f = (Atomic.get time_func).time ?level fmt f (* Values *) let value ?(level = Stderr) ?id pp v = match id with | None -> kmsg (fun _ -> v) level (fun m -> m "%a" pp v) | Some id -> kmsg (fun _ -> v) level (fun m -> m "id: @[%a@]" pp v) (* Module reporter *) module Reporter = struct type t = reporter = { kmsg : 'a 'b. (unit -> 'b) -> level -> ('a, 'b) msgf -> 'b } let nop = let kmsg k level msgf = k () in { kmsg } let default = reporter_default let get () = Atomic.get reporter let set r = Atomic.set reporter r end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>