import logging logger = logging.getLogger() logger.setLevel(level = logging.INFO) #可以不設,默認是WARNING級別 handler = logging.FileHandler("log.txt") handler.setLevel(logging.INFO)#可以不設,默認是WARNING級別
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter) #設置文件的log格式
logger.addHandler(handler)
logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail.") logger.info("Finish")
利用FileHandler將log寫入文件,比basicConfig的好處是想寫到哪個文件就寫到哪個,basicConfig是一旦設置就不能更改
注:個人理解:handler是控制log文件的,logger是控制程序文件的,logger.addHandler(handler)確定程序的log要寫到哪個文件
注:
logger.setLevel(level = logging.INFO)和
handler.setLevel(logging.INFO)
都會生效,最后寫入的是滿足兩個要求的數據
注意一點,FileHandler里面默認寫log文件中中文的編碼方式是GBK,而Python讀取文件方式是utf-8,所以如果用默認的編碼方式的話,pycharm讀取log文件后會亂碼
解決方式是,進到FileHandler中,把初始化函數改成如下
class FileHandler(StreamHandler): """ A handler class which writes formatted logging records to disk files. """ def __init__(self, filename, mode='a', encoding='utf-8', delay=False):
多個log文件的例子
下面程序是將一個程序內的不同log寫到兩個文件
import logging logger=logging.getLogger() logger.setLevel(level=logging.INFO) filehandle01=logging.FileHandler("log01.txt") filehandle02=logging.FileHandler("log02.txt") filehandle02.setLevel(logging.ERROR) formatter01=logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') formatter02=logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(lineno)s-%(message)s') filehandle01.setFormatter(formatter01) filehandle02.setFormatter(formatter02) logger.addHandler(filehandle01) logger.addHandler(filehandle02) logger.info("Start print log") logger.debug("Do something") logger.warning("Something maybe fail") logger.info("Finish") logger.error("error print log")
log01文件內容
2020-03-25 15:52:41,006 - root - INFO - Start print log 2020-03-25 15:52:41,006 - root - WARNING - Something maybe fail 2020-03-25 15:52:41,006 - root - INFO - Finish 2020-03-25 15:52:41,006 - root - ERROR - error print log
log02文件內容
2020-03-25 15:52:41,006 - trylog.py - ERROR - 22-error print log
下面是將兩個程序文件的log寫到一個log文件
程序文件1
import logging file1logger=logging.getLogger() file1logger.setLevel(level=logging.INFO) handler=logging.FileHandler("log.txt") handler.setLevel(logging.INFO) formatter=logging.Formatter('time:%(asctime)s - %(levelname)s-line:%(lineno)s - %(message)s') handler.setFormatter(formatter) file1logger.addHandler(handler) print("this is file1's log") file1logger.warning("this is file1's log")
程序文件2
import logging file1logger=logging.getLogger() file1logger.setLevel(level=logging.INFO) handler=logging.FileHandler("log.txt") handler.setLevel(logging.INFO) formatter=logging.Formatter('time:%(asctime)s - %(levelname)s-line:%(lineno)s - %(message)s') handler.setFormatter(formatter) file1logger.addHandler(handler) print("this is file2's log") file1logger.warning("this is file2's log")
以上兩個文件分別執行一次
log文件:
time:2020-07-21 17:10:00,718 - WARNING-line:12 - this is file1's log time:2020-07-21 17:10:04,150 - WARNING-line:12 - this is file2's log
注:
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')這里引號里的格式是隨便的,最后程序會用Formatter參數格式化替換
里面的格式化標准
栗子:
formatter = logging.Formatter('time:%(asctime)s - %(name)s - lineno:%(lineno)s - %(message)s')
Formatter參數的官方文檔
https://docs.python.org/3.7/library/logging.html#logrecord-attributes
Attribute name |
Format |
Description |
---|---|---|
args |
You shouldn’t need to format this yourself. |
The tuple of arguments merged into |
asctime |
|
Human-readable time when the |
created |
|
Time when the |
exc_info |
You shouldn’t need to format this yourself. |
Exception tuple (à la |
filename |
|
Filename portion of |
funcName |
|
Name of function containing the logging call. |
levelname |
|
Text logging level for the message ( |
levelno |
|
Numeric logging level for the message ( |
lineno |
|
Source line number where the logging call was issued (if available). |
message |
|
The logged message, computed as |
module |
|
Module (name portion of |
msecs |
|
Millisecond portion of the time when the |
msg |
You shouldn’t need to format this yourself. |
The format string passed in the original logging call. Merged with |
name |
|
Name of the logger used to log the call. |
pathname |
|
Full pathname of the source file where the logging call was issued (if available). |
process |
|
Process ID (if available). |
processName |
|
Process name (if available). |
relativeCreated |
|
Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded. |
stack_info |
You shouldn’t need to format this yourself. |
Stack frame information (where available) from the bottom of the stack in the current thread, up to and including the stack frame of the logging call which resulted in the creation of this record. |
thread |
|
Thread ID (if available). |
threadName |
|
Thread name (if available).
|