Python series logging topics

Keywords: Python Back-end

Python topic series (1) pathlib topic

Python topic series (2) csv topic

Python topic series (3) logging topic

1 logging log level

levelNumber of levelsUse occasion
DEBUG10Details, common language debugging
INFO20Some information generated during the normal operation of the program
WARNING20Warn the user that although the program is still working properly, errors may occur
ERROR40Due to more serious problems, the program can no longer perform some functions
CRITICAL50Serious error. The program can no longer run

2 logging defaults to the warning level

import logging

logging.debug("this is debug log")
logging.info("this is info log")
logging.warning("this is warning log")
logging.error("this is error log")
logging.critical("this is critical log")

The results are as follows:

WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log

3. You can set the log level through logging.basicConfig(level=logging.DEBUG)

import logging

logging.basicConfig(level=logging.DEBUG)
logging.debug("this is debug log")
logging.info("this is info log")
logging.warning("this is warning log")
logging.error("this is error log")
logging.critical("this is critical log")

The operation results are as follows:

DEBUG:root:this is debug log
INFO:root:this is info log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log

4. The logging log is written by one unit. The contents printed by logging are inconsistent with the inner cylinder sequence printed by print

import logging

print("this is print log")
logging.basicConfig(level=logging.DEBUG)
logging.debug("this is debug log")
logging.info("this is info log")
logging.warning("this is warning log")
logging.error("this is error log")
logging.critical("this is critical log")

The run result may be the following output sequence

DEBUG:root:this is debug log
INFO:root:this is info log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log
this is print log

5 logging.basicConfig(filename = "demo.log") can specify the log file name. By default, the file is generated in the current directory. At this time, the log will not be printed to the screen, but the log information will be output to the specified log file

import logging

print("this is print log")
logging.basicConfig(filename="demo.log",level=logging.DEBUG)
logging.debug("this is debug log")
logging.info("this is info log")
logging.warning("this is warning log")
logging.error("this is error log")
logging.critical("this is critical log")

After running, the output result on the screen is:

this is print log

A demo.log log log file is generated under the current file. The contents of this log file are:

DEBUG:root:this is debug log
INFO:root:this is info log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log

6 logging.basicConfig(filemode ='w ') can specify the mode of log file. W means to empty the log file and write again each time, and a means to append after the log file. The default mode is a

Execute the example code in 5 above again. The content in demo.log is:

DEBUG:root:this is debug log
INFO:root:this is info log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log
DEBUG:root:this is debug log
INFO:root:this is info log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log

If the code is modified as follows, execute again:

import logging

print("this is print log")
logging.basicConfig(filename="demo.log",filemode='w',level=logging.DEBUG)
logging.debug("this is debug log")
logging.info("this is info log")
logging.warning("this is warning log")
logging.error("this is error log")
logging.critical("this is critical log")

After running, the contents in demo.log are restored to the following contents:

DEBUG:root:this is debug log
INFO:root:this is info log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log

7 logging: how to write variables to the log

import logging

logging.basicConfig(level=logging.DEBUG)
name="zhangsan"
age=20
logging.debug("name: %s age: %d",name,age)
logging.info("name: %s age: %d" %(name,age))
logging.warning("name: {} age: {}".format(name,age))
logging.error("name: {name} age: {age}".format(name=name,age=age))

The operation results are as follows:

DEBUG:root:name: zhangsan age: 20
INFO:root:name: zhangsan age: 20
WARNING:root:name: zhangsan age: 20
ERROR:root:name: zhangsan age: 20

8. Add some public content to the log content format

import logging

logging.basicConfig(format=("%(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(message)s"),
                    datefmt="%Y-%m-%d_%H:%M:%S",
                    level=logging.DEBUG)
name="zhangsan"
age=20
logging.debug("name: %s age: %d",name,age)
logging.info("name: %s age: %d" %(name,age))
logging.warning("name: {} age: {}".format(name,age))
logging.error("name: {name} age: {age}".format(name=name,age=age))

The operation result is:

2020-08-03_07:20:42 | DEBUG | test1.py:9 | name: zhangsan age: 20
2020-08-03_07:20:42 | INFO | test1.py:10 | name: zhangsan age: 20
2020-08-03_07:20:42 | WARNING | test1.py:11 | name: zhangsan age: 20
2020-08-03_07:20:42 | ERROR | test1.py:12 | name: zhangsan age: 20

9 advanced application of logging

The logging module adopts modular design and mainly includes four components

  • Loggers: a logger that provides an interface that application code can use directly
  • Handlers: the processor that sends the logs generated by the recorder to the destination
  • Filters: filters that provide better granularity control and determine which logs will be output
  • Formatter: sets the composition structure and message fields of built-in content

10 advanced application process of logging

                             |---Create screen StreamHandler--Set log level---|
Create a logger And set the default level---|                                       |----establish formatter----use formatter Render all hansdler----Put all handler join logger within----Program call logger
                             |---create a file FileHandler--Set log level-----|

11 loggers recorder

  • Provides the calling interface of the application

    logger=logging. getLogger(name)
    The logger is a singleton

  • Determines the level of logging

    logger.setLevel()

  • Pass the log contents to the associated handlers

    logger.addHandler()

    logger. removeHandler()

12 handler processor

  • StreamHandler

    Standard output stdout (e.g. display) distributor

    Creation method: sh=logging.StreamHandler(stream=None)

  • FileHandler

    The processor that saves the log to a disk file

    Creation method: fh=logging.FileHandler(filename,mode = "a", encoding = none, delay = false)

  • setFormatter(): sets the message format used by the current handler object

13 common Handlers processors

  • StreamHandler
  • FileHandler
  • BaseRotatingHandler
  • RotatingHandler
  • TimedRotatingFileHandler
  • SocketHandler
  • DatagramHandler
  • SMTPHandler
  • SysLogHandler
  • NTEventLogHandler
  • HTTPHandler
  • WatchedFileHandler
  • QueueHandler
  • NullHandler

14 common formatter formats

attributeformatdescribe
asctime%(asctime)sThe default format of log generation time is 2020-08-03 12.12.12265
created%(created)fLog creation timestamp generated by time.time()
filename%(filename)sName of the program that generated the log
funcName%(funcName)sFunction name of call log
levelname%(levelname)sLog level (DEBUG,INFO,WARNING,ERROR,CRITICAL)
levelno%(levelno)sValue corresponding to log level
lineno%(lineno)s)Code line number for the log (if available)
module%(module)sName of the module that generated the log
mesecs%(mesecs)dThe millisecond portion of the time the log was generated
message%(message)sSpecific log information
name%(name)sLog caller
pathname%(pathname)sThe full path of the file that generated the log
process%(process)did of the process that generated the log (if available)
processName%(processName)sProcess name (if available)
thread%(thread)dThe id of the thread that generated the log, if available
threadName%(threadName)sThread name (if available)

15 the functions of the following two codes are exactly the same. Using logging to directly tune info, debug and other logs is the same as instantiating a default root logger. In other words, using logging to directly tune logs is realized by obtaining the root log

import logging

logging.debug("this is debug log")
logging.info("this is info log")
logging.warning("this is warning log")
logging.error("this is error log")
logging.critical("this is critical log")

logger=logging.getLogger()
logger.debug("this is debug log")
logger.info("this is info log")
logger.warning("this is warning log")
logger.error("this is error log")
logger.critical("this is critical log"

The operation results are as follows:

WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log
WARNING:root:this is warning log
ERROR:root:this is error log
CRITICAL:root:this is critical log

The following code specifies a name when using getLogger, that is, instantiate a logger, and then set two processors to write logs to the console and files respectively. You can also set the format of log content, as shown below

import logging


logger=logging.getLogger("test")

console_handler=logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

file_handler=logging.FileHandler(filename="demo.log")
file_handler.setLevel(logging.DEBUG)

formatter=logging.Formatter(fmt="%(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(message)s")

console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

logger.addHandler(console_handler)
logger.addHandler(file_handler)

log=logger

log.debug("this is debug log")
log.info("this is info log")
log.warning("this is warning log")
log.error("this is error log")
log.critical("this is critical log")

The operation results are as follows:

2020-08-04 23:08:56,625 | WARNING | test1.py:25 | this is warning log
2020-08-04 23:08:56,625 | ERROR | test1.py:26 | this is error log
2020-08-04 23:08:56,625 | CRITICAL | test1.py:27 | this is critical log

The following contents are written in the demo.log log file:

2020-08-04 23:08:56,625 | WARNING | test1.py:25 | this is warning log
2020-08-04 23:08:56,625 | ERROR | test1.py:26 | this is error log
2020-08-04 23:08:56,625 | CRITICAL | test1.py:27 | this is critical log

17 the log printing of the above 16 is obviously inconsistent with the original expectation. It was expected that the console and file were set with the DEBUG level, but in fact, the Warning level logs were printed in the console and file

It should be noted here that the default log level of logger is warning, and the final log level will depend on the highest level of logger and handler. Therefore, in the above 16, although the log levels of console and file handler are set to debug, because the default level of logger is warning, the final printing is warning level. The following code sets logger to d Ebug level, set the console to info, set the file handler to warning, and then look at the effect:

import logging


logger=logging.getLogger("test")
logger.setLevel(logging.DEBUG)

console_handler=logging.StreamHandler()
console_handler.setLevel(logging.INFO)

file_handler=logging.FileHandler(filename="demo.log")
file_handler.setLevel(logging.WARNING)

formatter=logging.Formatter(fmt="%(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(message)s")

console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

logger.addHandler(console_handler)
logger.addHandler(file_handler)

log=logger

log.debug("this is debug log")
log.info("this is info log")
log.warning("this is warning log")
log.error("this is error log")
log.critical("this is critical log")

The operation results are as follows:

2020-08-04 23:21:37,888 | INFO | test1.py:25 | this is info log
2020-08-04 23:21:37,888 | WARNING | test1.py:26 | this is warning log
2020-08-04 23:21:37,888 | ERROR | test1.py:27 | this is error log
2020-08-04 23:21:37,888 | CRITICAL | test1.py:28 | this is critical log

The following contents are written in the demo.log log file, which is consistent with the above analysis

2020-08-04 23:21:37,888 | WARNING | test1.py:26 | this is warning log
2020-08-04 23:21:37,888 | ERROR | test1.py:27 | this is error log
2020-08-04 23:21:37,888 | CRITICAL | test1.py:28 | this is critical log

18 define a filter and add a filter to the handler of the console. The filtered name is inconsistent with the log name. The following code will not write the log to the console at this time, but the log of the log file is written normally

import logging


logger=logging.getLogger("test")
logger.setLevel(logging.DEBUG)

console_handler=logging.StreamHandler()
console_handler.setLevel(logging.INFO)

file_handler=logging.FileHandler(filename="demo.log")
file_handler.setLevel(logging.WARNING)

formatter=logging.Formatter(fmt="%(asctime)s | %(levelname)s | %(filename)s:%(lineno)s | %(message)s")

console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)

logger.addHandler(console_handler)
logger.addHandler(file_handler)

filter=logging.Filter("test1")
console_handler.addFilter(filter)

log=logger

log.debug("this is debug log")
log.info("this is info log")
log.warning("this is warning log")
log.error("this is error log")
log.critical("this is critical log")

At this time, after running, the console result is empty, the log file is as follows, and the log printing is normal

2020-08-04 23:31:00,459 | WARNING | test1.py:29 | this is warning log
2020-08-04 23:31:00,459 | ERROR | test1.py:30 | this is error log
2020-08-04 23:31:00,459 | CRITICAL | test1.py:31 | this is critical log

19 how to configure files

  • (1) First, write a log configuration file similar to the following: logging.conf, which defines root and test logger s
[loggers]
keys=root,test

[handlers]
keys=fileHandler,consoleHandler

[formatters];
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_test]
level=DEBUG
handlers=fileHandler,consoleHandler
qualname=test
propagate=0

[handler_consoleHandler]
class=StreamHandler
args=(sys.stdout,)
level=DEBUG
formatter=simpleFormatter

[handler_fileHandler]
class=handlers.TimedRotatingFileHandler
args=("test.log","midnight",1,0)
level=DEBUG
formatter=simpleFormatter

[formatter_simpleFormatter]
format=%(asctime)s|%(levelname)s|%(filename)s[line:%(lineno)d]|%(message)s
datafmt=%Y-%m-%d_%H:%M:%S
  • (2) Then write the following code in the py file, which demonstrates the use of root's logger and test's logger
import logging.config

logging.config.fileConfig("logging.conf")
logger=logging.getLogger("test")

log=logger
log.debug("this is debug log")
log.info("this is info log")
log.warning("this is warning log")
log.error("this is error log")
log.critical("this is critical log")

rlog=logging.getLogger("root")
rlog.debug("this is debug log")
rlog.info("this is info log")
rlog.warning("this is warning log")
rlog.error("this is error log")
rlog.critical("this is critical log")

The operation results are as follows:

2020-08-05 00:25:02,673|DEBUG|test1.py[line:8]|this is debug log
2020-08-05 00:25:02,674|INFO|test1.py[line:9]|this is info log
2020-08-05 00:25:02,674|WARNING|test1.py[line:10]|this is warning log
2020-08-05 00:25:02,674|ERROR|test1.py[line:11]|this is error log
2020-08-05 00:25:02,674|CRITICAL|test1.py[line:12]|this is critical log
2020-08-05 00:25:02,674|DEBUG|test1.py[line:15]|this is debug log
2020-08-05 00:25:02,674|INFO|test1.py[line:16]|this is info log
2020-08-05 00:25:02,674|WARNING|test1.py[line:17]|this is warning log
2020-08-05 00:25:02,674|ERROR|test1.py[line:18]|this is error log
2020-08-05 00:25:02,674|CRITICAL|test1.py[line:19]|this is critical log

At the same time, the following logs are generated in the test.log log file:

2020-08-05 00:25:02,673|DEBUG|test1.py[line:8]|this is debug log
2020-08-05 00:25:02,674|INFO|test1.py[line:9]|this is info log
2020-08-05 00:25:02,674|WARNING|test1.py[line:10]|this is warning log
2020-08-05 00:25:02,674|ERROR|test1.py[line:11]|this is error log
2020-08-05 00:25:02,674|CRITICAL|test1.py[line:12]|this is critical log

20 on the basis of the above 19, add the log system to other files. There are two ways to print the log:

import test1
import logging


log=logging.getLogger("test")

log.debug("this is debug log")
log.info("this is info log")
log.warning("this is warning log")
log.error("this is error log")
log.critical("this is critical log")

log=test1.logger

log.debug("this is debug log")
log.info("this is info log")
log.warning("this is warning log")
log.error("this is error log")
log.critical("this is critical log")

The operation results are as follows:

2020-08-05_00:31:35|DEBUG|test2.py[line:8]|this is debug log
2020-08-05_00:31:35|INFO|test2.py[line:9]|this is info log
2020-08-05_00:31:35|WARNING|test2.py[line:10]|this is warning log
2020-08-05_00:31:35|ERROR|test2.py[line:11]|this is error log
2020-08-05_00:31:35|CRITICAL|test2.py[line:12]|this is critical log
2020-08-05_00:31:35|DEBUG|test2.py[line:16]|this is debug log
2020-08-05_00:31:35|INFO|test2.py[line:17]|this is info log
2020-08-05_00:31:35|WARNING|test2.py[line:18]|this is warning log
2020-08-05_00:31:35|ERROR|test2.py[line:19]|this is error log
2020-08-05_00:31:35|CRITICAL|test2.py[line:20]|this is critical log

Corresponding logs are also generated in the log file:

2020-08-05_00:31:35|DEBUG|test2.py[line:8]|this is debug log
2020-08-05_00:31:35|INFO|test2.py[line:9]|this is info log
2020-08-05_00:31:35|WARNING|test2.py[line:10]|this is warning log
2020-08-05_00:31:35|ERROR|test2.py[line:11]|this is error log
2020-08-05_00:31:35|CRITICAL|test2.py[line:12]|this is critical log
2020-08-05_00:31:35|DEBUG|test2.py[line:16]|this is debug log
2020-08-05_00:31:35|INFO|test2.py[line:17]|this is info log
2020-08-05_00:31:35|WARNING|test2.py[line:18]|this is warning log
2020-08-05_00:31:35|ERROR|test2.py[line:19]|this is error log
2020-08-05_00:31:35|CRITICAL|test2.py[line:20]|this is critical log

21 in the try - except ion statement block, log.exception(e) can be used to print the exception log, which can print the program error call stack

import logging.config

logging.config.fileConfig("logging.conf")
logger=logging.getLogger("test")

log=logger

try:
    a=1/0
except Exception as e:
    log.exception(e)

The operation results are as follows:

2020-08-05_00:35:14|ERROR|test1.py[line:12]|division by zero
Traceback (most recent call last):
  File "G:/lamb_source/test/log/test1.py", line 10, in <module>
    a=1/0
ZeroDivisionError: division by zero

Posted by bschultz on Fri, 12 Nov 2021 12:09:21 -0800