簡單的輸出,用於快捷操作
import logging
import time
# filemode="a" ,才能在文件末尾追加
# 在循環中,logging 相對於 open(file,'w').write的優點:不需要等到循環執行完成log日誌纔有內容
logging.basicConfig(filename="test.log", filemode="w",format="%(asctime)s %(name)s:%(levelname)s: %(message)s", \
datefmt="%Y-%M-%d %H:%M:%S", level=logging.INFO)
a = 5
b = 0
for i in range(1):
try:
c = a / b # 如果有異常需要捕獲異常,下面有3中方式將具體異常寫入log文件
except Exception as e:
logging.exception("Exception occurred")
#logging.error("Exception occurred", exc_info=True) # 要寫exc_info=True,才能把ZeroDivisionError: division by zero的具體錯誤信息寫入log文件
#logging.log(level=logging.INFO, msg="Exception occurred", exc_info=True) # 這裏的level寫成debug,無法寫入文件,因爲basicConfig設置了INFO ; logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)
logging.debug('This is a debug message')
logging.info('This is an info message')
logging.warning('This is a warning message')
logging.error('This is an error message')
logging.critical('This is a critical message')
操作更多樣
# 下面的方式會把”信息“累加到test.log日誌中
import logging
import logging.handlers
logger = logging.getLogger("logger") # %(name)s 日誌對象名稱 logger(括號中的名稱"logger")
handler1 = logging.StreamHandler()
handler2 = logging.FileHandler(filename="test.log")
logger.setLevel(logging.DEBUG) # 這個設置總的級別,handler的級別>=這個級別
handler1.setLevel(logging.WARNING)
handler2.setLevel(logging.DEBUG)
formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s", datefmt="%Y-%M-%d %H:%M:%S") # %message :下面debug,warning等括號中的內容
handler1.setFormatter(formatter)
handler2.setFormatter(formatter)
logger.addHandler(handler1)
logger.addHandler(handler2)
#分別爲 30、10、10
# print(handler1.level)
# print(handler2.level)
# print(logger.level)
logger.debug('This is a customer debug message')
logger.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')
輸出
# #控制檯輸出結果爲:
2018-10-13 23:24:57,832 logger WARNING This is a customer warning message
2018-10-13 23:24:57,832 logger ERROR This is an customer error message
2018-10-13 23:24:57,832 logger CRITICAL This is a customer critical message
# 文件中輸出內容爲:
2018-10-13 23:44:59,817 logger DEBUG This is a customer debug message
2018-10-13 23:44:59,817 logger INFO This is an customer info message
2018-10-13 23:44:59,817 logger WARNING This is a customer warning message
2018-10-13 23:44:59,817 logger ERROR This is an customer error message
2018-10-13 23:44:59,817 logger CRITICAL This is a customer critical message
注意點
# 創建了自定義的 Logger 對象,就不要在用 logging 中的日誌輸出方法了,這些方法使用的是默認配置的 Logger 對象,否則會輸出的日誌信息會重複。
# 比如下面寫了 logging.info,那麼會在>info等級輸出(warning,error,critical)重複信息
import logging
import logging.handlers
logger = logging.getLogger("logger")
handler = logging.StreamHandler()
handler.setLevel(logging.DEBUG)
# formatter = logging.Formatter("%(asctime)s %(name)s %(levelname)s %(message)s")
# handler.setFormatter(formatter)
logger.addHandler(handler)
logger.debug('This is a customer debug message')
logging.info('This is an customer info message')
logger.warning('This is a customer warning message')
logger.error('This is an customer error message')
logger.critical('This is a customer critical message')
輸出
This is a customer warning message
WARNING:logger:This is a customer warning message
This is an customer error message
ERROR:logger:This is an customer error message
This is a customer critical message
CRITICAL:logger:This is a customer critical message
使用文件導入配置
config.py文件
from datetime import datetime
config = {
'version': 1,
'formatters': {
'simple': {
'format': '%(filename)s - %(asctime)s - %(name)s - %(levelname)s - %(message)s',
'datefmt': '%Y-%m-%d %H:%M:%S'
},
# 其他的 formatter
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'level': 'DEBUG',
'formatter': 'simple'
},
'file': {
'class': 'logging.handlers.RotatingFileHandler', # 還有時間分割handler:logging.handlers.TimedRotatingFileHandler("test.log", when="H", interval=1, backupCount=10)
'filename': '{}.log'.format(datetime.now().strftime("%Y-%m-%d")), # 生成以日期爲名稱的日誌文件
'level': 'INFO',
'formatter': 'simple',
'maxBytes' : 200,
'backupCount' : 2, # 假設200kb爲3行內容,filename=logging.log,logging.log文件寫滿3行,將早期的3行移入logging.log.1文件,logging.log文件再寫滿3行,將早期3行已入logging.log.1文件,將logging.log.1的3行內容移入logging.log.2文件
'encoding': 'utf-8',
'mode':'w' # 'w', 'a' 都是追加寫入
},
# 其他的 handler
},
'loggers':{
'StreamLogger': {
'handlers': ['console'],
'level': 'DEBUG',
},
'FileLogger': {
# 既有 console Handler,還有 file Handler
'handlers': ['console', 'file'],
'level': 'DEBUG',
},
# 其他的 Logger
}
}
# 先經過loggers的級別處理,再經過handlers的級別處理,根據實際情況使用StreamLogger或FileLogger。可以也只使用FileLogger,在handlers的console或file中設置相應的級別,比如console設置DEBUG,file設置INFO,這樣fileLogger能打印>=DEBUG的信息,文件會寫入>=INFO的信息
導入config配置
import logging
import logging.config
from config import config
logging.disable(logging.DEBUG) # > debug級別才能被輸出
logging.disable = True
logging.config.dictConfig(config)
StreamLogger = logging.getLogger("StreamLogger")
FileLogger = logging.getLogger("FileLogger")
#StreamLogger.info('aaa')
FileLogger.info('pppp') # 在文件和控制檯都輸出
# 省略日誌輸出
PS:
handler和logger設置的級別都是 >=就能輸出;但是“注意點”下的logging.info 和 “使用文件導入配置” 的 logging.disable 的相關設置需要 > 對應級別才能輸出。Logger's level 的默認等級爲warning,所以如果沒有設置logger.setLevel(logging.DEBUG),那麼所有輸出將>=warning才能輸出,不管你的handler已經設置了debug級別