python寫項目時的logging日誌

 

簡單的輸出,用於快捷操作



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級別

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章