Introduction to logging
Python's built-in module logging provides logging related functions. It is a very powerful and commonly used module.
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:
level | number | describe |
---|---|---|
logging.critical | 50 | Fatal error |
logging.error | 40 | General error |
logging.warning | 30 | Warning message |
logging.info | 20 | General information |
logging.debug | 10 | debug information |
logging.NOSET | 0 | ... |
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, }, ... }