Python Series 50 built-in module: logging

Introduction to logging

Python's built-in module logging provides logging related functions. It is a very powerful and commonly used module.

Official documents

Its use may be complicated if you ask the bottom of the matter. Therefore, only one of the most convenient use methods is introduced in this chapter, and other use methods will not be used in daily development, so they will not be introduced.

Simple understanding

The logging module specifies that the log has six levels, and each level has two forms: word and number, as shown in the following table:

levelnumberdescribe
logging.critical50Fatal error
logging.error40General error
logging.warning30Warning message
logging.info20General information
logging.debug10debug information
logging.NOSET0...

logging.NOSET is generally not used, so you can also think that the logging level of logging is only 5.

The lower the level, the more log information can be seen. It will advance upward according to the level, as shown in the following figure:

The default level is 30, that is, the warning level. You can only see the logs of critical, error and warning, but not info and debug.

As follows:

import logging

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

# ❶ ❷
# WARNING:root:warning..
# ERROR:root:error..
# CRITICAL:root:critical..

❶: root refers to the user who records the log. It is root by default

❷: the default log output location is to the screen, or the log can be output to a file

configuration file

If you want to quickly use the logging module for logging.

You can use the form of configuration file. Generally speaking, the configuration file will be stored in settings Py:

import os

# Define 2 logging formats
# Standard: standard_format
# Simple: simple_format
standard_format = "[%(asctime)s][%(threadName)s:%(thread)d][username:%(name)s][%(filename)s:%(lineno)d]" \
                  "[%(levelname)s][%(message)s]"

simple_format = "[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s"

# Define log storage path
LOG_DIR = os.path.dirname(os.path.abspath(__file__))
if not os.path.isdir(os.path.join(LOG_DIR, "log")):
    os.mkdir(os.path.join(LOG_DIR, "log"))
LOG_PATH = os.path.join(LOG_DIR, "log", "run.log")

# The application configuration Dictionary of LOGGING can be used out of the box without much change
LOGGING_SETTING = {
    "version": 1,
    "disable_existing_loggers": False,
    # Add 2 logging formats
    "formatters": {
        "standard": {
            "format": standard_format
        },
        "simple": {
            "format": simple_format
        },
    },
    # Control flow related configuration
    "handlers": {
        # Output to the terminal (logging.StreamHandler), using a simple logging format
        "screen": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "simple"
        },
        # Output to a file (logging.handlers.RotatingFileHandler), using the standard logging format
        "file": {
            "level": "DEBUG",
            "class": "logging.handlers.RotatingFileHandler",
            "formatter": "standard",
            # Log file location and name. If not specified, it will be in the current directory by default
            "filename": LOG_PATH,
            # The maximum size of each log file is 5M. When there are 5 log files, start log rotation
            "maxBytes": 1024*1024*5,
            "backupCount": 5,
            "encoding": "utf-8",
        },
    },
    # Define the control flow adopted by different users
    "loggers": {
        # If no user is specified, or the specified user is not in the loggers dictionary, this configuration is adopted
        "": {
            "handlers": ["screen", "file"],
            # The filter level in the relevant configuration of control flow shall prevail. Here is one filter and there are two filters in control flow
            "level": "DEBUG",
            # Turn off log bubbling and do not change it manually
            "propagate": False,
        },
        # If the specified user is testUser, this configuration is adopted
        "testUser": {
            "handlers": ["screen"],
            "level": "DEBUG",
            "propagate": False,
        }
    }
}

Project application

How do I use this profile? We assume that the project directory is as follows:

Project/
|-- bin/
|   |-- run.py    # Startup script
|
|-- view/
|   |-- main.py   # main program
|
|-- common.py     # Common module
|-- settings.py   # logging profile

The first is the startup script:

# bin/run.py

import os
import sys

sys.path.append(
    os.path.dirname(os.path.dirname(__file__))
)

from view.main import main

if __name__ == "__main__":
    main()

The second is the main program:

# view/main.py

from common import logger

def main():
    logger.debug("debug")
    logger.info("info..")
    logger.warning("warning..")
    logger.error("error..")
    logger.critical("critical..")

Finally, the common module:

# common.py

from logging import config
from logging import getLogger
from settings import LOGGING_SETTING

config.dictConfig(LOGGING_SETTING)
logger = getLogger("adminstartion")

You can see that the configuration dictionary is imported into the common module and applied to the logging module.

Then get a log object logger, which can be used for logging in the future. Here, the user name of getLogger() is adminstart, which is not defined in login_ In the loggers of setting, the first configuration will be adopted, that is, the following:

"loggers": {
        # If no user is specified, or the specified user is not in the loggers dictionary, this configuration is adopted
        "": {
            "handlers": ["screen", "file"],
            "level": "DEBUG",
            "propagate": False,
        },
        ...
        }

Keywords: Python

Added by nadeauz on Sat, 22 Jan 2022 04:39:10 +0200