程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python + logging implements log output and saving to file

編輯:Python

List of articles
  • 1 Start using logging
    • 1.1 The first program
    • 1.2 The level of logging
    • 1.3 Output format
  • 2 Output log to file
    • 2.1 Use basicConfig Profile path
    • 2.2 logging Modular design
    • 2.3 Automatically split log files

Recently, because of a small demand , You need to save the log to a file . Because debugging is usually done with print, When you don't need it, you have to print Delete , It's not convenient , And this can only output the error message to the console . So I went online to check ,python There's a built-in module logging, Used to output log information , Various configurations can be made , After reading it, I felt sorry to meet you so late . Here are some personal summaries , It is mainly the induction of their own learning , I hope it can help you .

1 Start using logging

1.1 The first program

The first is the simplest use :

# -*- coding: utf-8 -*-
import logging
logging.debug('debug Level , It is generally used to print some debugging information , The lowest level ')
logging.info('info Level , It is generally used to print some normal operation information ')
logging.warning('waring Level , Generally used to print warning information ')
logging.error('error Level , Usually used to print some error messages ')
logging.critical('critical Level , It is usually used to print some fatal error messages , The highest level ')

In this way, you can directly output log information on the console :

WARNING:root:waring Level , Generally used to print warning information
ERROR:root:error Level , Usually used to print some error messages
CRITICAL:root:critical Level , It is usually used to print some fatal error messages , The highest level 

1.2 The level of logging

You will find that only the following three messages are output , This is because logging It's hierarchical , above 5 Levels of information are incremented from top to bottom , Can be set by logging Of level, Make it only print information above a certain level . Because the default level is WARNING, So only WARNING Logs of above levels are printed out . If we want to debug and info And print it out , have access to basicConfig Configure it :

logging.basicConfig(level=logging.DEBUG)

So the output of the console will include the above 5 All information .

The log level is not only python Only then , Basically, logs are classified by level , This allows us to focus on different priorities at different times , For example, we put some debugging information as debug Level output of , And the logging Of level Set to DEBUG, So when we don't need to display these logs in the future , Only need to level Set to info Or higher , Don't look like print You should also comment or delete that statement .

1.3 Output format

We found that the log output information above is very brief , It can't meet our needs for the time being , For example, we may need to output the time of this message , Location, etc , This can also be done by basicConfig To configure .

logging.basicConfig(format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
level=logging.DEBUG)

Then the output will be in this format :

2019-07-19 15:54:26,625 - log_test.py[line:11] - DEBUG: debug Level , It is generally used to print some debugging information , The lowest level 

format You can specify the content and format of the output , Its built-in parameters are as follows :

%(name)s:Logger Name
%(levelno)s: Print log level values
%(levelname)s: Print the log level name
%(pathname)s: Print the path of the currently executing program , In fact, that is sys.argv[0]
%(filename)s: Print the name of the currently executing program
%(funcName)s: Print the current function of the log
%(lineno)d: Print the current line number of the log
%(asctime)s: Time to print the log
%(thread)d: Print thread ID
%(threadName)s: Print thread name
%(process)d: Printing process ID
%(message)s: Print log information 

Besides ,basicConfig There are many other configurations available , We will continue to introduce .

2 Output log to file

2.1 Use basicConfig Profile path

We just output the log to the console , But many times we may need to save the log to a file , When something goes wrong with this program , It is convenient for us to locate according to the log information . The easiest way is to use basicConfig:

logging.basicConfig(format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s',
level=logging.DEBUG,
filename='test.log',
filemode='a')

Just add... To the above configuration filename and filemode Parameters , So you can output the log to test.log It's in the document , If there is no such file, it will be created automatically . The parameter filemode Indicates file open mode , If it is not set, it defaults to ’a’, That is, append mode , You don't have to ; It can also be set to ’w’, Each log write overwrites the previous log . But after doing this , We will find that the console does not output , How to output to the console and write to the file ? This requires further study .

2.2 logging Modular design

We just use logging Perform very simple operations , But the effect is limited , Actually logging The library adopts a modular design , There are many components available : Recorder 、 processor 、 Filters and formatters .

  • Logger Exposed the interface that application code can use directly .
  • Handler take ( The recorder produced ) Log records are sent to the appropriate destination .
  • Filter Provides better granularity control , It can decide which logging to output .
  • Formatter Indicates the content and format of the log record in the final output .

In short , among Logger Is responsible for logging messages , And then where do we put these log messages , hand Handler Handle ,Filter Help us filter information ( Not limited to filtering by level ),Formatter Just follow the above format One meaning , Used to set the log content and format .

such , Let's try using modules , Log again :

logger = logging.getLogger('test')
logger.debug('debug Level , It is generally used to print some debugging information , The lowest level ')
logger.info('info Level , It is generally used to print some normal operation information ')
logger.warning('waring Level , Generally used to print warning information ')
logger.error('error Level , Usually used to print some error messages ')
logger.critical('critical Level , It is usually used to print some fatal error messages , The highest level ')

First line getLogger Got a logger , The name identifies this Logger. Then the following output method starts with us logging The usage of is very similar , Doesn't it look very simple . But that won't work , An error will be reported after operation :

No handlers could be found for logger "test"

We didn't do it for this logger Appoint handler, It doesn't know what to do with logs , Where to export . Then we'll add one to him Handler Well ,Handler There are many kinds of , Commonly used 4 Kind of :

  • logging.StreamHandler -> Console output
  • logging.FileHandler -> File output
  • logging.handlers.RotatingFileHandler -> Automatically split log files by size , Once the specified size is reached, regenerate the file
  • logging.handlers.TimedRotatingFileHandler -> Automatically split log files by time

Now let's start with the simplest StreamHandler Output the log to the console :

logger = logging.getLogger('test')
stream_handler = logging.StreamHandler()
logger.addHandler(stream_handler)
...

So you can see on the console :

waring Level , Generally used to print warning information
error Level , Usually used to print some error messages
critical Level , It is usually used to print some fatal error messages , The highest level 

A few logs are missing , Because we have not set the log level , We also set the level , And also use Formatter The module sets the output format .

logger = logging.getLogger('test')
logger.setLevel(level=logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG)
stream_handler.setFormatter(formatter)
logger.addHandler(stream_handler)
...

We found that Formatter It's for handler Set up , That makes sense , because handler Is responsible for outputting logs to , So it is to format it , Rather than to logger; What then? level It needs to be set twice ? to logger Setting is to tell it which levels of logs to log , to handler Setting is to tell it which level of logs to output , It is equivalent to two times of filtration . The advantage of this is , When we have multiple log destinations , Such as saving to a file , And output to the console , You can set different levels for them ;logger The level of is filtered first , So be logger Filtered logs handler It can't be recorded , So you can just change logger And affect all outputs . The combination of the two makes it easier to manage the level of logging .

With handler, We can easily output the log to the console and file at the same time :

logger = logging.getLogger('test')
logger.setLevel(level=logging.DEBUG)
formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
file_handler = logging.FileHandler('test2.log')
file_handler.setLevel(level=logging.INFO)
file_handler.setFormatter(formatter)
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.DEBUG)
stream_handler.setFormatter(formatter)
logger.addHandler(file_handler)
logger.addHandler(stream_handler)

Just one more FileHandler that will do .

2.3 Automatically split log files

Sometimes we need to split the log file , To facilitate our management .python Two processors are provided , It is convenient for us to split the file :

  • logging.handlers.RotatingFileHandler -> Automatically split log files by size , Once the specified size is reached, regenerate the file
  • logging.handlers.TimedRotatingFileHandler -> Automatically split log files by time

How to use it is the same as above Handler similar , Just add some parameter configurations , such as when='D' Indicates that the file is segmented in days , The meaning of other parameters can be referred to :Python + logging Output to the screen , take log Log write file

from logging import handlers
time_rotating_file_handler = handlers.TimedRotatingFileHandler(filename='rotating_test.log', when='D')
time_rotating_file_handler.setLevel(logging.DEBUG)
time_rotating_file_handler.setFormatter(formatter)
logger.addHandler(time_rotating_file_handler)

If it's changed to when='S', Then cut in seconds , After running several times, the file will be generated :

Those without suffix are the latest log files .

Reference article : Python + logging Output to the screen , take log Log write file Python Standard module –logging


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved