A few recipes and starting blueprints for using B0_std
.
Note. Some of the code snippets here assume they are done after:
open B0_std
You can use the spawn tracing facility. At initialization time a tracer that logs spawns on level Debug
is installed. So setting your level to Debug
will trace the process spawns on stderr
.
If you want them to be traced at another level use B0_std.Os.Cmd.spawn_tracer_log
. For example this traces process spawns at the B0_std.Log.level.Stderr
level:
let main () =
Os.Cmd.set_spawn_tracer (Os.Cmd.spawn_tracer_log Stderr);
…
ANSI text styling is controlled globally on all formatters by the B0_std.Fmt.set_styler
function. The initial value depends on a bunch of conditions which are documented here. Text styling can be selectively stripped on strings and formatters with the B0_std.String.strip_ansi_escapes
and B0_std.Fmt.strip_styles
functions.
If you are using Cmdliner
the recommended way to let users control ANSI text styling is to use the More_cli.set_no_color
term which sets the styler by side side effect. The term allows to set the styler to Plain
with the --no-color
command line flag or the NO_COLOR
environment variable (which also happens at initialization time). See More_cli.no_color
for more information and this blueprint for an example.
We advise against changing the styler according to Unix.isatty
. Think about your outputs as being styled text rather than plain text. Users often pipe styled text and and expect it to survive. For example when they page your outputs or redirect messages to a log file. This doesn't mean that you should not support a --no-color
option; only that Unix.isatty
should not be used as signifier for plain text.
The log level is controlled by the B0_std.Log.set_level
function. The initial value is B0_std.Log.level.Warning
.
If you are using Cmdliner
the recommended way to let users control the log level is to use the More_cli.set_log_level
term which sets the log level by side effect. The term allows to set the log level with the --log-level
command line option and a few other flags or the LOG_LEVEL
environment variable. See More_cli.log_level
for more information and this blueprint for an example.
Simply wrap the body of your main
function by a call to B0_std.Log.time
. The call respects the reporting level even if changed in the wrapped function itself. See this this blueprint for an example.
It depends.
The B0_std.Log
module has two specific levels before Quiet
that allow to directly output to stdout
and stderr
by using B0_std.Log.stdout
and B0_std.Log.stderr
.
Using these functions is useful to flush newline ended messages on standard outputs without them being prefixed by the executable name or a log level header and retain the ability to suppress these messages when the reporting level is set to B0_std.Log.level.Quiet
.
For example if you are writing data on your standard output, you should likely not use B0_std.Log.stdout
for that unless you want to prevent it from being output when B0_std.Log.level.Quiet
is set.
This blueprint setups ANSI text styling and the log level by side effect. It also reports the total time taken by the tool when the log level is set to Info
.
open B0_std
let tool () =
Log.stdout (fun m -> m "Invoke with %a to silence me" Fmt.code "--quiet");
Cmdliner.Cmd.Exit.ok
open Cmdliner
open Cmdliner.Term.Syntax
let tool_cmd =
Cmd.make (Cmd.info "TODO" ~version:"%%VERSION%%") @@
let+ () = More_cli.set_no_color () in
let+ () = More_cli.set_log_level () in
tool ()
let main () =
Log.time (fun _ m -> m "total time %%VERSION%%") @@ fun () ->
Cmd.eval' tool_cmd
let () = if !Sys.interactive then () else exit (main ())