The logging module in Python gives you everything you need to report progress
and problems in your code. It would be nice if developers and machines were
100% reliable... but let's be honest. Life is messy. You're expecting an integer -
someone hands you a float. You call a cloud API - the service is down for maintenance.
A wide range of problems can happen that are out of your control. With logging, you
can leave a trail of breadcrumbs, so when something goes wrong, you can determine the
cause. Hope for the best, but plan for the worst - with logging.
Logging allows you to write status messages to a file
or other output streams. These messages contain
information on which parts of your code have executed, and what problems may have
arisen. Each log message has a level. The five built-in levels are debug, info,
warning, error, and critical. If you want, you can create additional levels, but
these should suffice for most cases. Let's now write a program and use
Python's logging module to help us track down bugs and leave a record of how our
code was used. First, import the logging module. Now look inside. This module is
packed with features. It can be a bit overwhelming. The entries in all caps are
constants. The capitalized items are classes. And the items that start with a
lowercase letter are methods. Today, we will keep things simple by setting up
the logging system using the basic config method. Next, we will create a logger
using the get logger method. We will then use the logger and adjust its features
until it works the way we want. Let's now switch to input/output mode.
Import the logging module. Let's first configure the logging system and create
a logger. Call the basic config method, and pass in a file name. Python will
write all the log messages to this file. If the file does not exist, Python will
create it. Next, call the get logger method to create a logger object. You can
give your logger a name if you wish, but there are some subtle issues with
logging names so today we will keep things simple and work with one logger
without a name. This is known as the root logger.
Let's now test it. To write an info message, call the info method and pass in
a string. Run. You can see that the lumberjack dot log file was created.
Let's look inside. This is...disappointing. Our log message is nowhere to be found.
Why is this? The reason lies in how we configured the logger. Let's print the
level of our logger and run again. 30. What does this mean?
In the logging module, the six built-in level constants are not set, debug, info, warning, error, and
critical. These constants are integers with values of 0, 10, 20, 30, 40, and 50,
respectively. Loggers will only write messages with a level greater than or
equal to the set level. Our test log message was an info message which has a
value of 20, but basic config sets the level of the root logger to warning by
default. To fix this, update the basic config call and set the level to debug.
This will guarantee that we will see all log messages. Now run again.
if you open the log file once more, you will now see our test message.
Notice that the log message displays the level, the name of the logger (in our case, root), and then the
message. This format is OK, but it's missing an important piece of data:
the time when the log message was created. Let's now change the format of the log
message. To do this, we will create a format string. Python gives you a wide
selection of information you can include in your log messages. You can view these
log attributes on the Python.org website. In this video, we are mainly interested
in the level, time, and message.
To change the logging format,
create a string with the desired attributes. Let's display the level name,
a space, the log time, a dash, then the message.
Now pass the format string to the basic config call.
Run. If you open the log file, you will see the message
now appears in the new format. Notice that the first message is still there.
This is because by default, the log file is created in append mode. If you want
the log file to be overwritten, each time change the file mode to W. Let's also
change the message... then run. If you look at the log file again, you will see the
old log messages have been overwritten, and only our most recent message appears.
You can log messages of any level, by calling the method with the level name.
For example, let's create messages of all five levels: debug, info, warning, error, and critical.
Now run. If you open the log file, you will see all five messages.
But if you change the log level to error and rerun, you will now only see the error
and critical messages. Let's set the level back to debug. Now that we know how
to configure and use the logging module, let's see it in action.
We'll write a function implementing the quadratic formula.
This formula allows you to solve any quadratic equation.
First import the math module, since we need the square root
function. Call the function quadratic formula. In the future, people will write
songs about our creative function names. The inputs to this function are A, B, and C.
Write a quick docstring. I'm sure you never skip the step. This is a good place
for a log message. Let's generate an info message with the details of the function
call. Next, let's compute the discriminant. This is just the number under the square
root sign. If you're writing a comment for a block of code, it might be a good
place for a debug message. I'll use the same text as the comment.
This may seem repetitive, but once we are confident the code is working properly,
we may want to remove the debug logs, while keeping the comments.
Next, compute the two roots.
And for our last block, return the two roots as a tuple.
Let's test our function by solving the equation x squared minus 4 equals 0.
Run.
The function gave us the correct answer, and if you look at the log file, you will
see the info message with the details of the method call and all three debug
messages. Let's test this function one last time by solving x squared plus 1
equals zero.
Run.
We have a problem. If you look at the log file, you'll see
only the first two debug statements. So the problem must have occurred when we
tried to compute the roots. Can you determine the problem?
Legend tells of a programmer who never made any mistakes;
who anticipated every problem, and
consequently never had to use the logging module.
But not everyone is like me, so please use logging in your code.
And if you have requests for future Python videos,
leave an info message in the comments below.
And one last critical message:
Our channel is powered by subscribers.
You can feel the power by pressing the subscribe button.