Logging to Console and File In Python

Python has a great integrated logging mechanism for developers. You don’t have to make complicated stuffs to activate logger and you can easily log to file or console with separating different kinds of log levels. In this writing, I will create a basic initialization method and use it to log my main program. More complicated implications are up to you.

First, I want to give some basic concepts of logger for python. Logger has a 5 different level in python. These are:

  • debug
  • info
  • warning
  • error
  • critical

Every output place is controlled by handlers. For example, if you want to console output, you need to define console related handler. After that, you can handle logging level or logging format via that handler.

Now, I will give you a basic example code for logging. My file structure will be like below:

Logging file structure

There is loggerinitializer.py file:

import logging
import os.path

def initialize_logger(output_dir):
    logger = logging.getLogger()
    logger.setLevel(logging.DEBUG)
    
    # create console handler and set level to info
    handler = logging.StreamHandler()
    handler.setLevel(logging.INFO)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    # create error file handler and set level to error
    handler = logging.FileHandler(os.path.join(output_dir, "error.log"),"w", encoding=None, delay="true")
    handler.setLevel(logging.ERROR)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

    # create debug file handler and set level to debug
    handler = logging.FileHandler(os.path.join(output_dir, "all.log"),"w")
    handler.setLevel(logging.DEBUG)
    formatter = logging.Formatter("%(levelname)s - %(message)s")
    handler.setFormatter(formatter)
    logger.addHandler(handler)

Line 5-6: Get main logger to add new specifications. Then set global log level to debug.

Line 9-13: In this area I add console logging mechanism to logger. In first line I get StreamHandler() and this means console for me. Then I said I only want output for INFO messages or higher level like errors or critical messages. For example Debug messages will not be printed out with this options. Then I give my own output format. There are a lot of options for this format and mine is very very simple. At the end, I add my console handler to my main logger.

Line 16-20: This area is nearly same as above except little differences. This time we get a FileHandler to write a file. In first parameter, we give the path for output file. Then we say we want to ‘write’ to file without any encoding specification. Last parameter puts some magic here. If no message is sent to this handler, no file will be created. The below lines are the same as above except that logger level is set to Error.

Line 23-27: In this area we create a new handler to log every message. We set level to debug, which is minimum, and let file be created every run.

After that, we can test this code with below code:

#!/usr/bin/env python3

from utils.loggerinitializer import *

initialize_logger('/home/aykut/Documents/blog')

logging.debug("debug message")
logging.info("info message")
logging.warning("warning message")
logging.error("error message")
logging.critical("critical message")

If we look at the outputs, we will see below:

Python Logging Outputs

Developers Rock!!!

This entry was posted in Python and tagged , , , , , , . Bookmark the permalink.

5 Responses to Logging to Console and File In Python

  1. asd says:

    Do you know whether this is Python 2 compatible? Because Ive read that ONE single logging statement (i.e. logging.critical(“critical message”)) would never log to two different loggers, so Im wondering if that was a statement regarding python 2 only and hence your code above is working only in Py3? Thanks

  2. sudonym says:

    In my setup (python 2.7, windows), this solution doesn’t work. I see logging.info() on console, but for logging.warning(), no logfile is ever created.

  3. russ says:

    @asd this works in python 2 as well. I just tested with the exact same code as above on python 2.7.5 and it works exactly the same. 🙂

  4. anand naik says:

    @aykutakin, This snippet worked like a charm on both python v2.7 and v3.2 . This is the simplest way explaining logging example. Effort appreciated.

  5. NIcole says:

    Thank you! Explaining what each line does is super helpful to Python newbs like myself! So helpful. Thank you so much!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s