Library
Module
Module type
Parameter
Class
Class type
Logging library inspired by the Python logging module.
Easy_logging allows fine-grained tuning of of when and where and how log messages are printed, with relatively low configuration, and simple logger configuration and usage.
It has the following features :
string
or string lazy_t
messageopen Easy_logging
logger = Logging.make_logger "my_logger" (Some Debug) [Cli Debug]
logger#info "log_message"
will output to the stdout a message of the form
1.306 my_logger Info log_message
Easy_logging
)defaults
Easy_logging__Handlers
)Easy_logging.Logging.logger
)Easy_logging.Logging
)Easy_logging__Make_logging.MakeLogging
)The logging infrastructure is based on four concepts:
loggers, handlers, log items and logging tree.
A call to logger will create a log item, which it will pass to its handlers. Each handler will treats the item (e.g. transform it to a string, and then outputs to stdout or to a file).
___________ | handler 1 | _______________ |-----------| | logger | ==> | ( * ) | |---------------| |___________| (message) ==> | -> log item | ___________ [_______________| ==> | handler 2 | | ... |
Loggers are stored in a tree structure, with the following properties :
set_propagate
method).A (Info, Cli Debug) / \ A.B A.C / \ A.B.D (Warning) A.C.E (Debug, (File "f", Debug), propagate=false)
For example, with the above logging tree
A
, A.B
or A.C
of level Info
or more are written to the stdout.A.B.D
of level Warning
or above are written the stdout.A.C.E
are only written to the file "f"
To each logger and log message are associated a level, which will be used to filter the messages going through the logging infrastructure.
The predefined levels are, in increasing order of precedence :
A log item has type
type log_item = {
level : level; (* the level of the log item *)
logger_name : string; (* the name of the logger to which the log call was passed *)
msg : string; (* the actual log message *)
tags : string list (* a list of tags *)
}
Four handler creation helper function are provided. They instantiate handlers with a level of their own to filter messages :
Cli handler: outputs colored messages to stdout.
let h = Handlers.make (Cli Debug)
CliErr handler: outputs colored messages to stderr.
let h = Handlers.make (CliErr Debug)
File handler : outputs messages to a given file.
let h = Handlers.make (File ("filename", Debug))
RotatingFile handler : outputs messages to a given file. Takes as argument the max number of kb per log file, and the number of backup log files.
let h = Handlers.make (RotatingFile ("filename", Debug, 65536, 3))
Log file creation is governed by configuration values (setting up file name prefix/suffix, folder, file creation mode, etc...). The configuration can be specified when creating the handlers explicitely (like above), and a default configuration can be set in the Logging module.
See more at Easy_logging.Handlers
See complete class documentation at Easy_logging.Logging.logger
A logger object can be created directly (in which case it will not be part of the logging tree)
let logger1 = new Logging.logger "my_logger1"
or through helper functions of the The Logging module module.
A logger object has three methods for each of the log levels:
one that takes a formatting string and parameters (printf like)
logger1#debug "Myvar : %s" (to_string myvar);
one that takes a string lazy_t
logger1#ldebug (lazy (heavy_calculation ()));
one that takes a string
logger1#sdebug (to_string myvar);
The Easy_logging.Logging
module is the application of MakeLogging
over Handlers
. It provides two functions :
val make_logger :
?propagate:bool -> string -> log_level -> Handlers.desc list
Instantiates a logger with some paramters, and adds it to the logging tree.
val get_logger : string -> logger
Returns a registered logger, or creates a new one if it doesn't exist.
val set_handlers_config : Handlers.config -> unit
Sets the default handlers configuration, used when creating new handlers via make_logger
.
The MakeLogging functor takes a Easy_logging__.Easy_logging_types.HandlersT
typed module, and creates a Logging module.
When declaring your Handlers module, do not coerce it the type HandlersT
, because then its internal types t
and desc
won't be accessible.
See the examples page for more examples.