In this tutorial, we will research the fundamentals of the popular logging module.
What is logging?
Logging is a Python module in the general library that gives the facility to work with the framework for releasing log messages from the Python programs. Logging is used to tracking occasions that appear when the software program runs.
This module is extensively used by using the developers when they work to logging. It is very vital device which used in software development, running, and debugging.
Logging is advisable to keep the logging records. Suppose there is no logging record, and the software is interrupted all through its execution, we will be unable to locate the actual cause of the problem.
Somehow, we realize the reason of the crash but it will eat a lot of time to unravel this. Using the logging, we can leave a hint of breadcrumbs so that if the hassle happens in the program, we can locate the purpose of the trouble easily.
We can face many issues whilst running purposes such as we suppose an integer, and we have been given a float, the provider is beneath protection and many more. These problems are tough to decide and time-consuming.
How Logging Works
The logging is a powerful module used by means of the novices as well as enterprises. This module presents a proficiency to organize special manipulate handlers and a switch log messages to these handlers.
To releasing a log message, we need to import the logging module as follows.
import logging
Now, we will call the logger to log messages that we prefer to see. The logging module presents the five levels that specify the severity of events. Each event incorporates the parallel techniques that can be used to log events at the degree of severity. Let’s apprehend the following activities and their working.
DEBUG - It is used to provide detailed information and only use it when there is diagnosing problems.
INFO - It provides the information regarding that things are working as we want.
WARNING - It is used to warn that something happened unexpectedly, or we will face the problem in the upcoming time.
ERROR - It is used to inform when we are in some serious trouble, the software hasn't executed some programs.
CRITICAL - It specifies the serious error, the program itself may be incapable of remaining executing.
The above ranges are adequate to handle any types of problems. These corresponding numerical values of the tiers are given below.
Level | Numeric Values |
---|---|
NOTSET | 0 |
DEBUG | 10 |
INFO | 20 |
WARNING | 30 |
ERROR | 40 |
CRITICAL | 50 |
The logging module offers many features. It consists of numerous constants, classes, and methods. The constants are represented by way of the all caps latter; the instructions are represented by way of capital letters. The gadgets with lowercase symbolize methods.
Let’s have a seem to be at the several logger objects provided via the module itself.
Logger.info(msg) : It is used to log a message with level INFO on this logger.
Logger.warning(msg) : It is used to log a message with level WARNING on this logger.
Logger.error(msg) : It is used to log a message with level ERROR on this logger.
Logger.critical(msg) : It is used to log a message with level CRITICAL on this logger.
Logger.log(lvl,msg) : It is used to logs a message with integer level lvl on this logger.
Logger.exception(msg) : It is used to log a message with level ERROR on this logger.
Logger.setLevel(lvl) : It is used to sets the beginning of this logger to lvl. It will ignore all the messages which are written below.
Logger.addFilter(filt) : It is used to add a specific filter filt to the to this logger.
Logger.removeFilter(filt) : It is used to eliminates a specific filter filt to the to this logger.
Logger.filter(record) : It put on the filter of logger to the record. If the record available and to be handled then returns True. Otherwise, it will return False.
Logger.addHandler(hdlr) : It is used to add a particular handler hdlr to the to this logger.
Logger.removeHandler(hdlr) : It is used to eliminate a particular handler hdlr to this logger.
Logger.hasHandlers() : It is used to verify if the logger contains any handler configured or not.
Let’s understand the following example.
Example –
import logging
logging.debug('The debug message is displaying')
logging.info('The info message is displaying')
logging.warning('The warning message is displaying')
logging.error('The error message is displaying')
logging.critical('The critical message is displaying')
Output:
WARNING:root:The warning message is displaying
ERROR:root:The error message is displaying
CRITICAL:root:The critical message is displaying
Explanation:
As we can see in the above output, every message is displayed along with the root, which is the logging module name given to its default logger. The message and the level title are separated via a colon (:) and print the messages in default output format.
We can word that the debug() and info() message didn’t show messages because, via default, the log module logs the messages with a severity level of WARNING, ERROR and CRITICAL.
Basic Configurations
The fundamental assignment of logging is to shop the files events in a file. The logging module gives the basicConfig(**kwarg), used to configure the logging.
It accepts some of the often used argument as follows.
level – The specified severity level is set by the root level.
filename – It specifies a file.
filemode – It opens a file in a specific mode. The default mode of the opening file is a, which means we can append the content.
format – The format defines the format of the log message.
We can set the degree of log messages with the aid of the usage of the stage parameter as we want to record. We want to pass by the one steady in the class, which would permit all logging calls.
Let’s understand the following example.
Example –
import logging
logging.basicConfig(level=logging.DEBUG)
logging.debug('The dubug message is logged')
Output:
DEBUG:root: The debug will be get logged
Similarly, we can log the message to a file as an alternative of show on console, filename and filemode can be used in the basicConfig() function, and we can determine the layout of the message using layout attributes. Let’s apprehend the following example.
Example –
import logging
logging.basicConfig(filename='msg.log', filemode='w', format='%(name)s - %(levelname)s - %(message)s')
logging.warning('This will get logged to a file')
Output:
root - WARNING - This will get logged to a file
Explanation:
The above output will be displayed in the msg.log file alternatively of console. We opened the file in w, which skill the file is opened in the “write mode”. If the basicConfig() is known as multiple times, then every run of the software will rewrite the log file’s output. The basicConfig() characteristic can be modified by using passing the extra arguments (https://docs.python.org/3/library/logging.html#logging.basicConfig).
Let’s understand the following example.
Example –
import logging
#Create and configure logger using the basicConfig() function
logging.basicConfig(filename="newfile.log",
format='%(asctime)s %(message)s',
filemode='w')
#Creating an object of the logging
logger=logging.getLogger()
#Setting the threshold of logger to DEBUG
logger.setLevel(logging.DEBUG)
#Test messages
logger.debug("This is a harmless debug Message")
logger.info("This is just an information")
logger.warning("It is a Warning. Please make changes")
logger.error("You are trying to divide by zero")
logger.critical("Internet is down")
Output:
2020-09-05 13:17:39,204 This is a harmless debug Message
2020-09-05 13:17:39,205 This is just an information
2020-09-05 13:17:39,205 It is a Warning. Please make changes
2020-09-05 13:17:39,205 You are trying to divide by zero
2020-09-05 13:17:39,205 Internet is down
Explanation:
The above code will generate a file, and we can see the output while opening a file.
Formatting the Output
A string exceeded in the software as a message to log can be modified in accordance to our requirements. There are some basic factors in the given string and part of the Logrecord. Let’s apprehend the following example.
Example –
import logging
logging.basicConfig(format='%(process)d-%(levelname)s-%(message)s')
logging.warning('This is a Warning Message')
Output:
18472-WARNING-This is a Warning Message
The format argument can accept a string with Logrecord attributes in any form as we require.
Let’s understand the following example –
Example –
import logging
logging.basicConfig(format='%(asctime)s - %(message)s', level=logging.INFO)
logging.info('Admin logged in')
Output:
2020-09-02 20:12:06,288 - Admin logged in
The %(asctime) attributes provides the time advent of the Logrecord. We can additionally personalize the format the usage of datefmt attributes, which affords the same feature as the datetime module.
Example –
import logging
logging.basicConfig(format='%(asctime)s - %(message)s', datefmt='%d-%b-%y %H:%M:%S')
logging.warning('Admin logged out')
Output:
02-Sep-20 13:29:05 - Admin logged out
Logging Variable Data
Sometimes, we want to encompass the dynamic records from the utility in the log. The logging strategies are familiar a string as an argument, and it is right practice to structure a string with the variable records and passed to a log method.
But as a substitute of that, we can also use a structure string for the message and appending the variable statistics as an argument.
Let’s understand the following example –
import logging
name = 'Peter Decosta'
logging.error('%s raised an error', name)
Output:
ERROR:root: Peter Decosta raised an error
Explanation:
The arguments passed to the approach would be convoluted as variable information in the message.
We can use the f{string} to structure the given string. It provides a quick and easy way to manage the string.
Example –
import logging
name = 'Antonio Mino'
logging.error(f'{name} raised an error')
Output:
ERROR:root: Antonio Mino raised an error
Capturing Stack Traces
We can capture the full stacks of traces in an application the use of the logging module. There is an exc_info parameter in the logging function; if we set it as True, it can seize the Exception information.
Let’s understand the following example –
Example –
import logging
a = 10
b = 0
try:
c = a / b
except Exception as e:
logging.error("Exception occurred", exc_info=True)
Output:
ERROR:root:Exception occurred
Traceback (most recent call last):
File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/loggingFile.py", line 224, in <module>
c = a / b
ZeroDivisionError: division by zero
Explanation:
If we don’t set authentic to exc_info, the output will no longer inform us about the exception. It would be challenging to debug an error in thousand strains of code, if it displays solely the following output.
ERROR:root:Exception occurred
There is additionally other alternative to get complete records about the exception. The logging module offers the exception() method, which logs a message with ERROR and attaches the exception information. To use it, call the logging.exception() technique identical as calling logging.error(exc_info = True).
Let’s understand the following example.
Example –
import logging
a = 10
b = 0
try:
c = a / b
except Exception as e:
logging.exception("Exception occurred", exc_info=True)
Output:
ERROR:root:Exception occurred
Traceback (most recent call last):
File "C:/Users/DEVANSH SHARMA/PycharmProjects/Hello/loggingFile.py", line 224, in <module>
c = a / b
ZeroDivisionError: division by zero
We can use any of one choice in error(), debug(), or critical() strategies to get records about the exception.
Classes and Functions
We have considered so far the default logger known as root. The logging module is used it whenever its features are referred to as such as logging.debug(), logging.error(), etc. We can also outline very own logger by means of creating an object of the Logger class. Here, we are defining the regularly used instructions and functions.
Below are the instructions and functions defined in the logging module.
Logger – The logger object is used to call the functions directly.
LogRecord – It creates automatically log record file which consists the information related to all event of being logged such as the logger’s name, the function, the line number, the message, and more.
Handler – The handlers are used to dispatch the LogRecord to the output endpoint. The FileHandler, StreamHandler, HTTPHandler, SMTTPHandler are the subclasses of a Handler.
Formatters – The formatters are used to define the structure of the output. It is used the string formatting methods to specify the format of the log messages.
If we do not have the message to format, the default is to use the raw message. The default format date structure is.
%Y-%m-%d %H:%M:%S
The following format is used to make the log message in the human -readable format.
'%(asctime)s - %(levelname)s - %(message)s'
We generally work with the objects of the Logger class, which are created using the logging.getLogger(name) function. If the getLogger() technique is referred to as multiple instances with the identical name, it will return the reference of the equal logger object.
Let’s understand the following example:
Example –
import logging
logger = logging.getLogger('first_logger')
logger.warning('This is a warning message')
Output:
This is a warning message
Explanation:
We have created the own logger name first_logger, but unlike the root logger, the first_logger is not phase of the output format. To display it, bypass it into the configuration function. Then the output will seem like as follows.
WARNING:first_logger:This is a warning message
Work With Handlers
Handlers are commonly used to configure logger and transmit the logs to the many locations at a time. It sends the log messages to the wellknown output move or a file over HTTP or on email.
Let’s understand the following example of growing handlers.
Example:
import logging
# Create a custom logger_obj
logger_obj = logging.getLogger(__name__)
# Create handlers
w_handler = logging.StreamHandler()
e_handler = logging.FileHandler('file.log')
w_handler.setLevel(logging.WARNING)
e_handler.setLevel(logging.ERROR)
# Create formatters and add it to handlers
c_format = logging.Formatter('%(name)s - %(levelname)s - %(message)s')
f_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
w_handler.setFormatter(c_format)
e_handler.setFormatter(f_format)
# Add handlers to the logger_obj
logger_obj.addHandler(w_handler)
logger_obj.addHandler(e_handler)
logger_obj.warning('This is a warning message')
logger_obj.error('This is an error message')
Output:
__main__ - WARNING - This is a warning message
__main__ - ERROR - This is an error message
Explanation:
In the following program, we have created a custom logger named the logger_obj and created a LogRecord that stores the all file of the logging events and exceeded it to all the Handlers that it has: w_handlers and e_handlers.
The w_handlers is a flow handler with the degree WARNING. It accepts the log from the LogRecord to generate the output in the structure string and print it to the screen.
The e_handler is a file handler with the stage ERROR. It disregards the LogRecord as its stage WARNING.
Conclusion
The logging module is bendy and convenient to use. It is very useful for keeping song of the logging files and displaying the gorgeous message to the user. It offers the flexibility to create customized log levels, handler classes, and many other useful methods.
It additionally gives basic logging for small projects.
In this tutorial, we have discussed all the necessary principles of the logging module. We have protected generate messages with special levels.
Leave a Review