How to use goatlog ################## The log manager is the main class you will use in your program to send information to whoever needs it (the master?):: import goatlog.log log_manager = goatlog.log.LogManager("execution") `LogManager` needs one parameter, the name of the logger to be created. `LogManager` also accepts an arbitrary number of handlers which will be added to the logger. Existing logging.handlers works, but goatlog provides more useful handlers: * `RichLogHandler` is an advanced log handler able to deal with contexts. This handler produces nothing, but facilitates the creation of other rich log handler like `JsonHandler`. * `JsonHandler`, inherits from `RichLogHandler` and produce json. For instance, if you want to produce both json and display log to stdout:: import sys import logging from goatlog.log import LogManager, JsonHandler log_manager = LogManager("execution", logging.StreamHandler(sys.stdout), JsonHandler(open("log.json"))) Using it ======== In the next examples, the log_manager will be instantiated like this:: from goatlog.log import LogManager, JsonHandler log = LogManager("execution", JsonHandler(open("log.json", "w"))) Simple logging -------------- The Log manager api is very similar to the one in the :wlogging module, so you can use it easily:: log.debug('Debug message') log.info('Info message') log.warning('Warning message') It will produce this json file:: { "contents": [ { "message": "Debug message", "type": "log.message", "severity": "DEBUG" }, { "message": "Info message", "type": "log.message", "severity": "INFO" }, { "message": "Warning message", "type": "log.message", "severity": "WARNING" } ] } Context logging --------------- There are two ways to log contexts, one is using the python context manager (with statement) and the other one is more functional: Context manager approach ________________________ Python provides a context manager (with statement), so this is a natural approach to use it with context logging:: with log.context("step1", "step"): log.info("Message before task execution") with log.context("task1", "task") log.info("Message during task execution") log.info("Message after task execution") Functional approach ___________________ Now let's see how to log some contexts with the functional approach:: log.open_context("step1", "step") log.info("Message before task execution") log.open_context("task1", "task") log.info("Message during task execution") log.close_context("task1", "task") log.info("Message after task execution") log.close_context("step1", "step") With this approach, you need to close the context yourself, so be sure that you close the last opened context just as you do with xml markers. Json log file _____________ They both produce this json log file:: { "contents": [ { "type": "step", "id": "step1", "contents": [ { "message": "Message before task execution", "type": "log.message", "severity": "INFO" }, { "type": "task", "id": "task1", "contents": [ { "message": "Message during task execution", "type": "log.message", "severity": "INFO" } ] }, { "message": "Message after task execution", "type": "log.message", "severity": "INFO" } ] } ] } When to use each approach? __________________________ First one is the recommended one, it's easy to use and it will make your logging statements more readable. But sometimes, it is difficult to use the context manager approach, for instance with a context opened in one method and closed in another one, you should use the second approach in this case. Finally, you have the choice between the two dependending on the situation, they they do the same thing anyway. More specific informations __________________________ LogManager also contains some additional methods to report more specific informations, they are detailed in the :doc:`api` page.