Bootstrap FreeKB - Python (Scripting) - Logging to a log file
Python (Scripting) - Logging to a log file

Updated:   |  Python (Scripting) articles

There are several built in modules that are part of the Python Standard Library included with your Python installation, such as os (Operating System) and re (Regular Expression) and sys (System).

Here is a basic example of how to get started with logging.

#!/usr/bin/python
import logging
logging.debug('debug message')       # <- will NOT appear in console output
logging.info('info message')         # <- will NOT appear in console output
logging.warning('warning message')   # <- will appear in console output
logging.error('error message')       # <- will appear in console output
logging.critical('critical message') # <- will appear in console output

 

Which should output the following.

WARNING:root:warning message
ERROR:root:error message
CRITICAL:root:critical message

 

Since logging is such a common task across nearly all of your Python scripts, it almost always makes sense to create a logging module that can be imported into your various Python scripts.

For example, if using Python version 2, here is what you could put into your logging module such as logger.py. This will always append events to a log file and optionally display the events on the console.

#!/usr/bin/python
import logging
from logging.handlers import RotatingFileHandler
import sys

def return_logger(log_file, console):

  logger = logging.getLogger()

  # Set Default Log Level
  #   DEBUG    - print/log critical, error, warning, info, debug events
  #   INFO     - print/log critical, error, warning, info events
  #   WARNING  - print/log critical, error, warning events
  #   ERROR    - print/log critical, error events
  #   CRITICAL - print/log critical events
  logger.setLevel(logging.INFO)

  format = logging.Formatter(fmt="[%(asctime)s %(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")

  fileHandler = logging.FileHandler(log_file)
  fileHandler = RotatingFileHandler(log_file, maxBytes=10000000, backupCount=10)
  fileHandler.setFormatter(format)
  logger.addHandler(fileHandler)

  if console == True:
    consoleHandler = logging.StreamHandler(sys.stdout)
    consoleHandler.setFormatter(format)
    logger.addHandler(consoleHandler)

  return logger

 

And here is what you could have in your child Python scripts, where the logging module is imported and used.

#!/usr/bin/python
import os
import re
import sys

sys.path.append("/path/to/the/directory/that/has/your/logger/module")
from logger import return_logger

log_file = os.path.basename(__file__)
log_file = re.sub(".py", ".log", log_file)

# True is used so that the events are displayed on the console
return_logger(log_file, True)

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

 

Here is how you can set different log formats for different log levels.

#!/usr/bin/python
import logging
from logging.handlers import RotatingFileHandler
import sys

def return_logger(log_file, console):

  logger = logging.getLogger()

  # Set Default Log Level
  #   DEBUG    - print/log critical, error, warning, info, debug events
  #   INFO     - print/log critical, error, warning, info events
  #   WARNING  - print/log critical, error, warning events
  #   ERROR    - print/log critical, error events
  #   CRITICAL - print/log critical events
  logger.setLevel(logging.INFO)

  class CustomFormatter(logging.Formatter):

    default_format = logging.Formatter(fmt="[%(asctime)s %(levelname)s] %(message)s", datefmt="%Y-%m-%d")
    warning_format = logging.Formatter(fmt="[%(asctime)s %(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S")

    def format(self, record):
      if record.levelno == logging.WARNING:
        return self.warning_format.format(record)
      else:
        return self.default_format.format(record)

  fileHandler = logging.FileHandler(log_file)
  fileHandler = RotatingFileHandler(log_file, maxBytes=100000, backupCount=10)
  fileHandler.setFormatter(CustomFormatter)
  logger.addHandler(fileHandler)

  if console == True:
    consoleHandler = logging.StreamHandler(sys.stdout)
    consoleHandler.setFormatter(CustomFormatter)
    logger.addHandler(consoleHandler)

  return logger

 

If using Python version 3, here is how to append to a log file. No output will appear on the console. The log level is set to DEBUG so that all log level events are appended to the log file.

#!/usr/bin/python
import logging
logging.basicConfig(filename='/path/to/example.log', encoding='utf-8', level=logging.DEBUG)
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

 

Here is how you can control the format of the log file.

#!/usr/bin/python
import logging
logging.basicConfig(
        filename='/path/to/example.log',
        encoding='utf-8',
        format='[%(asctime)s %(levelname)s] %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S',
        level=logging.DEBUG)
logging.debug('debug message')
logging.info('info message')
logging.warning('warning message')
logging.error('error message')
logging.critical('critical message')

 

Which should produce the following.

[2023-01-06 00:04:04 DEBUG] debug message
[2023-01-06 00:04:04 INFO] info message
[2023-01-06 00:04:04 WARNING] warning message
[2023-01-06 00:04:04 ERROR] error message
[2023-01-06 00:04:04 CRITICAL] critical message

 

The following can be used to print stdout to the console and to write to the log file.

logging.getLogger().addHandler(logging.StreamHandler(sys.stdout))

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 04ed1f in the box below so that we can be sure you are a human.