Logging module is one of most useful modules out of the box. In every single software development, there is a chance the program runs into an error. And that's a reason we should prevent the case with this.
All programmers are familiar with
Logging module because we may need to debug from somewhere more persistent than console log.
For more info please follow the link below to read the module's detail, but we're gonna see some basic use cases of this module through this blog.
Just a baby step. We can start from this.
There are 5 levels of log there + 1 "NOTSET" which I never use it as there is no use cases for me. Learn more about levels by this link.
The result will be messages from
And what if we want more info of the message such as time or formatting level? We can add argument
format into the object like this.
And it will produce the message based on the given format.
Wanna try more advance? Let's make a logger that perform logging on both console and file writing.
For this requirement, we are going to review two main handlers for injecting log records to these displays.
Other than using
basicConfig() as above, we will use
StreamHandler(). The example is below:
And let's see what happen when we run it.
We can parse the log outputs to a file via
See the output file here.
Of course, we can mix both handlers together to inject logs through console and file at the same time. Try this:
Now run it and there are console log along with file log. Yes!
More fancy examples
dynamic level per message
We can supply the message level by calling
.log() instead of
.info() or other level-specific methods.
Date time format
We would add argument
logging.Formatter(). Visit this link to learn more about format codes.
How to manage multiple loggers?
We can create many loggers as we want but we need to make sure we named each logger distinguishly. Let's see the case.
- Firstly, program calls
outercreate a logger name "outer" to write logs in file "outer.log". The messages are "[outer] start" and "[outer] done".
- Between both messages from
innerthrough a loop.
- There are 2 items and it will call
- First item is a text "abc" that
innerwill log in the filepath "msg1/inner.log" with "[inner]" beginning the line.
- Second is a text "def" that
innerwill log in the filepath "msg2/inner.log" with "[inner]" beginning the line as well.
innerhas a logger name "inner".
Looking good but the result was not as expected. The log file "msg1/inner.log" should have only "[inner] abc" but it inproperly has "[inner] def".
What we missed? We had given the same log name for
inner so that the first
inner call receive the consequent logs.
We have to fix by giving different name. One solution is to use
UUID to generate a random UUID (line 27) for each
And this time we got the correct logs.
All examples are in my repo below.