package easy_logging

  1. Overview
  2. Docs

Easy logging

Logging infrastructure inspired by the Python logging module. The aim of this module is to provide a quick and easy to use logging infrastructure.

It has the following features :

  • one line logger creation
  • log messages are either string or string lazy_t
  • log level adaptable at runtime from anywhere in the program
  • handlers associated to each logger will format and treat the message independantly
  • use the infrastructure with your own handlers with the MakeLogging functor.
Basic example
open 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


  1. Overall description (Easy_logging)
  2. Defaults

    1. Default Handlers ( Easy_logging__Default_handlers)
    2. Loggers ( Easy_logging.Logging.logger )
    3. The Logging module (Easy_logging.Logging)
  3. The MakeLogging functor ( Easy_logging.MakeLogging )
  4. Examples

Overall description


Like in the python logging module, this logging infrastructure is based on three concepts:

loggers, handlers and log items.

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 |
                                  |   ...     |

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 :

  1. Debug : used for debugging.
  2. Info : used to trace program execution.
  3. Warning : used for warnings.
  4. Error : used for errors.
  5. Flash : used for one-shot debugging: displays an easy to spot message.
Log items

A log item has type

type log_item = {
    level : level;
    logger_name : string;
    msg : string;
    tags : tag list

where the tag type if defined by the Handlers module.


Default Handlers

By default, two handlers are provided. They are instantiated with a level of their own to filter messages :

  • Cli handler: outputs colored messages to stdout.

    let h = Default_handlers.make (Cli Debug) 
  • File handler : outputs messages to a given file.

    let h = Default_handlers.make (File ("filename", Debug)) 

Note that file handlers will write to files in the logs folder in the current path, creating it if it doesn't exist. See more about default handlers at Easy_logging__Default_handlers.


See complete class documentation at Easy_logging.Logging.logger


A logger object can be created directly :

let logger1 = new Logging.logger "my_logger1" (Some Warning) [Cli Debug] 

or through the make_logger function :

let logger2 = Logging.make_logger "my_logger2" (Some Debug) [Cli Debug] 

The make_logger function will register the logger instance internaly so that it will be possible to access and modify it from anywhere in the program.


A logger object has two methods for each of the log levels: one that takes a string, and one that takes a string lazy_t.

logger1#debug "x is alive";
logger1#ldebug (lazy (heavy_calculation ())); 

The Logging module

The Easy_logging.Logging module is that application of MakeLogging over DefaultHandlers. It provides three functions :

  • val make_logger :
    string -> log_level option -> Default_handlers.desc list 

    to instantiate and register a logger

  • val set_level : string -> log_level option -> unit

    set_level prefix level sets the level of all registered loggers whose name begins by prefix to level.

  • val get_logger : string -> logger 

    Returns a registered logger.

The MakeLogging functor

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 give it the type HandlersT, because then its internal types t and desc won't be accessible.


Here is a very simple example :

module MyHandlers =
    type t = string -> unit
    type desc = string list ref
    let set_formatter _ _ = ()
    let set_level _ _ = ()
    let apply h (item : log_item) = h item.msg
    let make (_internal : desc) =

      fun s -> _internal := s::!_internal

module MyLogging = MakeLogging(MyHandlers)

let l = ref [];;
let mylogger = MyLogging.make_logger "mylogger" (Some Debug) [l];;
mylogger#info "this is a message";

Innovation. Community. Security.