Python 日誌向控制檯和檔案輸出
1.建立logger例項
logging模組是依靠呼叫Logger類的方法來實現的,Logger並不直接建立例項,而是通過呼叫logging.getLogger([name])建立logger例項,
每個例項都有自己的名字.
logger = logging.getLogger("mylogger")
2.日誌的級別
logging模組通過事件的嚴重程度提供6種不同級別的日誌記錄,提示日誌的重要程度.
Level 數值
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0
模組預設設定的級別是WARNING 即當且僅當等於或高於WARNING的事件會被記錄下來,
更改logger的預設level
logger.setLevel("INFO") //此時小於INFO級別的日誌都不輸出, 大於等於INFO級別的日誌都輸出.
例如:
logger.debug("this is debug message") # 不輸出
logger.info("this is info message") # 輸出
logger.warning("this is warning message") # 輸出
3.建立一個handle物件,併為handler設定 level
通過handler物件可以將日誌記錄(log record)寫到不同的地方(destination),比如檔案,socket, 控制檯.
python提供了十幾種實用handler,比較常用有:
StreamHandler: 輸出到控制檯
FileHandler: 輸出到檔案
BaseRotatingHandler 可以按時間寫入到不同的日誌中。比如將日誌按天寫入不同的日期結尾的檔案檔案。
SocketHandler 用TCP網路連線寫LOG
DatagramHandler 用UDP網路連線寫LOG
SMTPHandler 把LOG寫成EMAIL郵寄出去
RotatingFileHandler 指定了單個log檔案的size的最大值和log檔案的數量的最大值,
如果檔案大於最大值,將分割為多個檔案,如果log檔案的數量多於最多個數,最老的log檔案將被刪除
fh = logging.FileHandler(logName) //logName是在某個路徑下的log檔名mylogger
fh.setLevel(logLevel) //logLevel是傳入的日誌級別引數.
ch = logging.StreamHandler()
rh = logging.RotatingFileHandler(logName,maxBytes= ,backupCount= )
4.formatter物件,定義handler 格式化輸出
formatter物件 可以指定日誌記錄的時間格式、程序號、檔名、函式名等資訊.
幾種常用格式:
%(asctime)s //預設的日期格式精確到微秒,例如‘2016-03-16 8:20:34,896'
%(name)s //logName mylogger
%(levelname)s // logLevel
%(message)s //日誌資訊logger.debug("this is debug message") this is debug message
%(filename)s //log.py
%(lineno)d //原始檔中log日誌被呼叫的行號,logger.info("this is info message")
log_format=logging.Formatter("%(asctime)s-%(name)s-%(levelname)s-%(message)s-[%(filename)s:%(lineno)d]")
為建立的handler物件新增輸出格式
fh.setFormatter(log_format)
5.為logger例項新增handler物件
每個logger可以擁有多個handler,通過addHandler()新增
logger.addHandler(fh)
6.呼叫logger例項對應級別的目志訊息輸出函式:
logger.debug("debug message")
logger.info(" info message")
logger.warning("warning message")
logger.critical("critical message")
logger.error("error message")
程式碼如下:
#coding=utf-8
import loggingimport logging.handlers
logDir=r"D:\logs"
def getLog():
#建立一個logger例項
logger = logging.getLogger("mylogger")
llogger.setLevel("DEBUG") #設定級別為DEBUG,覆蓋掉預設級別WARNING
#建立一個handler,用於寫入日誌檔案,handler可以把日誌內容寫到不同的地方
logName = logDir + r"\\" + "test.log"
fh = logging.FileHandler(logName)
fh.setLevel("WARNING")
#再建立一個handler,用於輸出控制檯
ch = logging.StreamHandler()
ch.setLevel("ERROR")
#定義handler的格式輸出
log_format=logging.Formatter("%(asctime)s-%(name)s-%(levelname)s-%(message)s-[%(filename)s:%(lineno)d]")
fh.setFormatter(log_format) #setFormatter() selects a Formatter object for this handler to use
ch.setFormatter(log_format)
#為logger新增handler
logger.addHandler(fh)
logger.addHandler(ch)
logger.debug("debug message")
logger.info("info message")
logger.warning("warning message")
logger.error("error message")
logger.critical("critical message")
if __name__ = "__main__":
getLog()
控制檯輸出:
2016-03-17 15:02:44,065-mylogger-ERROR-error message-[log.py:26]
2016-03-17 15:02:44,065-mylogger-CRITICAL-critical message-[log.py:27]
test.log檔案輸出:
2016-03-17 15:02:44,065-mylogger-WARNING-warning message-[log.py:25]
2016-03-17 15:02:44,065-mylogger-ERROR-error message-[log.py:26]
2016-03-17 15:02:44,065-mylogger-CRITICAL-critical message-[log.py:27]
也可以封裝成一個類呼叫
#coding=utf-8
class Logger():
def __init__(self, lognName, logLevel, logger):
# 建立一個logger
self.logger = logging.getLogger(logger)
self.logger.setLevel(logging.DEBUG)
# 建立一個handler,用於寫入日誌檔案
fh = logging.FileHandler(logName)
fh.setLevel(logLevel)
# 再建立一個handler,用於輸出到控制檯
ch = logging.StreamHandler()
ch.setLevel(logLevel)
# 定義handler的輸出格式
log_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s
-[%(filename)s:%(lineno)d]')
fh.setFormatter(log_format)
ch.setFormatter(log_format)
# 給logger新增handler
self.logger.addHandler(fh)
self.logger.addHandler(ch)
def getlog(self):
return self.logger
在另一個test.py檔案中呼叫
from log import Logger
logger = Logger(logname='log.txt', loglevel="INFO", logger="test.py").getlog()
另:logging.basicConfig函式
basicConfig()是為root logger 建立一個控制代碼(StreamHandler),當未給root logger 建立一個控制代碼時,logging的debug() info() warning() error()和critical()函式會自動呼叫系統預設的basicConfig()函式
#coding=utf-8
import logging
LOG_FILENAME="D:\test\log.txt"
logging.basicConfig(logName=LOG_FILENAME,level=logging.INFO,format = '%(asctime)s - %(levelname)s: %(message)s')
logging.info("info message")
LOG_FILENAME="D:\test\log2.txt"
<pre name="code" class="python">logging.basicConfig(logName=LOG_FILENAME,level=logging.WARNING,format = '%(asctime)s - %(levelname)s: %(message)s')
logging.error("error message")
注:error message不會記錄到D:\test\log2.txt,會全部記錄到log.txt檔案下
因為logger已經有一個控制代碼了,basicConfig不會創造一個新的控制代碼了,所以日誌資訊會輸出到第一個日誌檔案下