[toc]
Generally, logging is an extremely valuable tool in a software developer’s toolbox. Logging helps to assist you with the flow of a program and find situations that you probably would not have considered while coding. By logging useful data and information, you can troubleshoot the errors effectively as well as utilize the information to examine the performance of the application to anticipate scaling the program.
Python provides us with a logging framework (standard library) to rapidly add logging to our application. One can import the logging module and use it in their program. The logging module has various functions to get detailed information like the line number, stack traces to the line where the error occurred. In this tutorial, let us learn about different levels of logging and different ways to log a Python Error with debug information.
β¨A Quick Introduction to The Logging Module
The logging module is used in Python to track the event that happens while our programming software runs. You can add logging calls to your code to demonstrate what occasions have occurred. The logging module considers both- demonstrative logging that records occasions identified with an application’s activity as well as, review logging which records the occasions of a userβs transactions for examination. It is particularly used to record occasions to a document or file.
To add the logging module in your Python program using the following command:
Import logging |
?οΈDifferent Levels of Logging
Based on the severity, there are FIVE different logging levels :
- DEBUG – used to log the Details.
- INFO – used to log informational messages when something runs as expected.
- WARNING – used to log warnings when there is a problem, but the code can run to completion.
- ERROR – used to log an error indicating a problem to perform an action.
- CRITICAL– used to log a serious error when the code cannot run to completion.
By default, the module logs only the Warning, Error, and Critical levels. Meaning, when the program runs as expected, nothing is logged unless you change the default settings. But, the module logs a warning or an error, or a critical event it encounters.
β¨Overview of Stack Trace in Python
The Python stack trace stores a significant piece of data that you can use to debug your code. It contains all information about the call stack and shows where the code went wrong. Towards the end of a stack trace, you can generally track down the specific exception type and a detailed message of where exactly the error occurred.
Generally, a stack trace report contains all the function calls made in your code just before the error occurred. At the point when your program raises an exception, it will print the stack trace. The following is an example of a basic Python script that will raise an exception:
Example:
def foo(n): print('The number is ', y) foo(10)
Output:
Traceback (most recent call last): File "main.py", line 3, in <module> foo foo(n) File "main.py", line 2, in foo print('The number is ', y) NameError: name 'x' is not defined
The stack trace report has a lot of information regarding what went wrong in the program. It first mentions the type of error that happened: NameError. This explains that we’ve referred to a variable that doesn’t exist. It also displays the variable we attempted to reference. Here, y is not defined. The debug information is usually the stack trace report.
Now that you know what attack trace and logging are, letβs dive into the various methods to log a Python error with debug information:
?Method 1: Using logging.{level}()
Use this method to log the information at different log levels.
β¦Ώ If you want to display only the custom error message, the syntax is :
logging.{level}(msg)
where,
level | can be debug, info, warning, or critical. |
msg | is any custom message. |
Example: In this example, let us use logging.error() to log an error with a custom message.
import logging import math def find_sqrt(x): #function to find square root of a number try: return(math.sqrt(x)) #returns squareroot of a number except ValueError: logging.error("Check the value.s Negative numbers cannot be passed") find_sqrt(-2)
Output:
ERROR:root:Check the value. Negative numbers cannot be passed
β¦Ώ If you want to log the Custom error message along with stack trace, the syntax is :
logging.{level}(msg,stack_info=True)
level | can be debug, info, warning, error, critical. |
msg | is any custom message. |
Example: In the following example, let us use logging.error() with the parameter stack_info to log an error with a custom message and stack trace pointing to the error.
import logging import math def find_sqrt(x): #function to find square root of a number try: return(math.sqrt(x)) #returns squareroot of a number except ValueError: #Error- when negative number is passed logging.error("Check the value. Negative numbers cannot be passed",stack_info=True) find_sqrt(-2)
Output:
ERROR:root:Check the value. Negative numbers cannot be passed Stack (most recent call last): File "C:\Users\admin\Desktop\Finxter\main.py", line 15, in <module> find_sqrt(-2) File "C:\Users\admin\Desktop\Finxter\main.py", line 13, in find_sqrt logging.error("Check the value. Negative numbers cannot be passed",stack_info=True)
?Method 2 : Using logging.exception()
What is an exception in Python?
In Python, an exception is an object that addresses an error. At the point when the script raises an exception, it should either deal with the exception, else the program stops running and terminates.
You can use the logging.exception() when you want to log the exception messages and get details of the line number. Make sure to use it only within an except block.
Syntax: logging.exception(msg) |
exception()
logs at the ERROR level and with exc_info
. Meaning, it is the same as executing, logging.error(msg,exc_info=3)
To show detailed debug information and data, you first have to import the logging
library in Python and then use the logging.exception()
method. This method usually logs the message with a level “Error” on the logger. The exception information also gets added to the logging message. The logging.exception()
method must be called from an exception handler.
Example:
# Importing the logging module import logging def foo(n): # The try block try: res = n / 0 print("Result = ", res) # The except block except : # logging.exception() method inside the except block logging.exception("The debugged error message is -") foo(10)
Output:
ERROR:root: The debugged error message is - Traceback (most recent call last): File "main.py", line 4, in foo res = n / 0 ZeroDivisionError: division by zero
In the above example, we have got detailed debug information regarding the error:
- It displays the exact
function (foo)
where the error occurred. - It also displays the line number (
line 4
) where the error occurred. - It also displays the cause of the error. (
ZeroDivisionError: division by zero
.)
β¦Ώ Using logging.exception() with exc_info:
By default, the logging.exception()
method utilizes the log level of ERROR
. Although, you can utilize the customary logging techniques like logging.debug(), logging.info(), logging.warn()
, and so forth. For this, you have to pass the exc_info
parameter.
Example:
# Importing the logging module import logging def foo(n): # The try block try: res = n / 0 print("Result = ", res) # The except block except Exception as e: # logging.exception() method inside the except block logging.exception("The debugged error message is -", exc_info = e) foo(10)
Output:
ERROR:root: The debugged error message is - Traceback (most recent call last): File "main.py", line 4, in foo res = n / 0 ZeroDivisionError: division by zero
Note:
- The
exc_info
holds the current exception information only if an exception occurs in the program else, it will holdNone
. - The
exc_info
parameter also accepts instances. You can even set the parameter to beTrue
.
Look at the following example:
# Importing the logging module import logging def foo(n): # The try block try: res = n / 0 print("Result = ", res) # The except block except Exception: # The logging.exception() method inside the except block logging.exception("The debugged error message is -", exc_info = True) foo(10)
Output:
ERROR:root: The debugged error message is - Traceback (most recent call last): File "main.py", line 4, in foo res = n / 0 ZeroDivisionError: division by zero
Setting the exc_info
to True causes the logging module to include the full stack trace exactly like logging.exception()
does.
?Method 3: Using traceback Module
We recommend using the logging module to log. But, at times, when you cannot use the logging module, use the traceback module with some tweaks as shown below.
import traceback,sys try : #do something except: exc_type, exc_value, exc_traceback = sys.exc_info() print(" ".join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
Example – Let us import the traceback module, extract values of the exception that is being handled. Format the values into a list and join the list to display the error message as shown below.
import traceback,sys import math def find_sqrt(x): #function to find square root of a number try: return(math.sqrt(x)) #returns squareroot of a number except ValueError: # extract the information from tuple about the exception exc_type, exc_value, exc_traceback = sys.exc_info() print(" ".join(traceback.format_exception(exc_type, exc_value, exc_traceback))) find_sqrt(-2)
Output:
Traceback (most recent call last): File "C:\Users\admin\Desktop\Finxter\main.py", line 11, in find_sqrt return(math.sqrt(x)) #returns squareroot of a number ValueError: math domain error
Conclusion
We hope you have found this article helpful. Please stay tuned and subscribe for more solutions and interesting discussions in the future. Till then Happy Pythoning!
RECOMMENDED READS: Errors in Python
Authors:–
?β? ANUSHA PAI
?β? RASHI AGARWAL
Co-author: SHUBHAM SAYON
To become a PyCharm master, check out our full course on the Finxter Computer Science Academy available for free for all Finxter Premium Members: