python--6、logging模塊
logging
可用的日誌級別:
- debug 10
- info 20
- warning 30
- error 40
- critical 50
logging默認參數:
- 默認日誌級別是warning。
- 默認情況日誌輸出到終端。
- 默認日誌名是root,即默認root產生日誌。
簡單使用:
import logging
logging.info(‘info level‘)
logging的全局配置方式:basicconfig
修改logging模塊的默認日誌格式。
filename - 指定日誌的存儲位置。
filemode - 指定文件打開模式。默認‘a‘
format - 定義日誌的格式。
datafmt - 指定日期格式。
level - 定義日誌級別,寫級別對應的數字。
format可設定的日誌格式:
%(name)s:Logger的名字,並非用戶名,詳細查看
%(levelno)s:數字形式的日誌級別
%(levelname)s:文本形式的日誌級別
%(pathname)s:調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s:調用日誌輸出函數的模塊的文件名
%(module)s:調用日誌輸出函數的模塊名
%(funcName)s:調用日誌輸出函數的函數名
%(lineno)d:調用日誌輸出函數的語句所在的代碼行
%(created)f:當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d:輸出日誌信息時的,自Logger創建以 來的毫秒數
%(asctime)s:字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒
%(thread)d:線程ID。可能沒有
%(threadName)s:線程名。可能沒有
%(process)d:進程ID。可能沒有
%(message)s:用戶輸出的消息
示例:
import logging
logging.basicConfig(
filename=‘test.log‘
format=‘%(asctime)s - %(name)s - - %(levelname)s -%(module)s: %(message)s‘,
level=30,
datefmt=‘%Y-%m-%D %X‘
)
logging.error(‘error level‘)
缺點:
- 不能同時輸出到文件和終端。
- 不能多種輸出環境的級別、格式的自定義。
logging模塊的四種對象
Formatter
定義不同的日誌格式對象,然後綁定給不同的Handler。以此來控制不同Handler的日誌格式。
Handler
負責接收日誌並控制打印到不同地方。一個Handler對象可以綁定一種日誌格式。
FileHandler - 打印到文件。
StreamHandler - 打印到終端。
Logger
負責產生日誌的對象,getLogger()方法實例化後的對象。對應日誌的masage字段。
Filter
負責過濾日誌的對象。目測沒啥用
logging應用
import logging
#logger對象,負責產生日誌信息
logger = logger.getLogger(‘root‘)
#filter對象,沒用
#Handler對象:接受log傳來的日誌內容,控制打印到終端or文件。
Handler1 = logging.FileHandler(‘tset1.log‘)
Handler2 = logging.StreamHandler()
#formatter對象
formatter1 = logging.Formatter(‘%(asctime)s - %(name)s - - %(levelname)s -%(module)s: %(message)s‘,
datafmt=‘%Y-%m-%d %H:%M:%S‘,)
formatter2 = logging.Formatter(‘%(asctime)s %(name)s %(message)s‘,)
#把日誌格式綁定到不同輸出對象。
Handler1.setFormatter(formatter1)
Handler2.setFormatter(formatter2)
#設置日誌輸出級別
Handler1.setLevel(10)
#設置日誌產生的級別
logger.setLevel(10)
#把日誌信息綁定到Handler來輸出。
logger.addHandler(Handler1)
#測試。
logger.info(‘info level‘)
logger與Handler定義級別時的關鍵
logger是第一級別過濾,然後日誌才會到Handler,需給logger和Handler同時設置level,但要註意:
在所有logger傳的日誌都要輸出時,必須有如下的要求:
內容級別 >= logger對象的日誌級別必須 >= Handler對象的日誌級別。
logger的繼承——只需知道有這麽個玩意
import logging
formatter=logging.Formatter(‘%(asctime)s - %(name)s -%(module)s: %(message)s‘,)
inherit=logging.StreamHandler()
inherit.setFormatter(formatter)
logger1=logging.getLogger(‘root‘)
logger2=logging.getLogger(‘root.child1‘)
logger1.addHandler(inherit)
logger2.addHandler(inherit)
logger1.setLevel(10)
logger2.setLevel(10)
logger1.debug(‘log1 debug‘)
logger2.debug(‘log2 debug‘)
★生產環境中的應用方法
配置
"logging配置"
import os,logging.config
#先定義兩種日誌輸出格式
standard_format = ‘[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]‘ ‘[%(levelname)s][%(message)s]‘ #其中name為getlogger指定的名字
simple_format = ‘[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s‘
#定義日誌輸出格式
logfile_dir = os.path.dirname(os.path.abspath(__file__))
logfile_name = ‘production.log‘
if not os.path.isdir(logfile_dir)
os.mkdir(logfile_dir)
#log文件全路徑
logfile_path = os.path.join(logfile_dir,logfile_name)
#log配置字典
LOGGING_DIC = {
‘version‘:1,
‘disable_existing_loggers‘:False,
‘formatters‘: {
‘standard‘: {
‘format‘: standard_format
},
‘simple‘: {
‘format‘: simple_format
},
},
‘filters‘: {},
‘handlers‘: {
#打印到終端
‘console‘: {
‘level‘: ‘DEBUG‘,
‘class‘: ‘logging.StreamHandler‘,
‘formatter‘: ‘simple‘
},
#打印到文件
‘default‘: {
‘level‘: ‘DEBUG‘,
‘class‘: ‘logging.handlers.RotatingFileHandler‘,
‘formatter‘: ‘standard‘,
‘filename‘: logfile_path,
‘maxBytes‘: 1024*1024*6,
‘encoding‘: ‘utf-8‘,
},
},
‘loggers‘: {
#logging.getLogger(__name__)時拿到的配置
‘‘: {
#把上面定義的兩個Handler加到這裏,log即寫入文件又打到終端。
‘handlers‘: [‘default‘,‘console‘],
‘level‘: ‘DEBUG‘,
#向上(更高level的logging)傳遞
‘propagate‘: True,
},
},
}
def load_my_logging_cfg():
logging.config.dictConfig(LOGGING_DIC)
#生成個log實例,__name__即把當前模塊名傳進去,找不到日誌相關配置,使用‘‘這個默認的。
logger = logging.getLogger(__name__)
使用:
"MyLogging Test"
import time
import logging
import my_logging # 導入自定義的logging配置
logger = logging.getLogger(__name__) # 生成logger實例
def demo():
logger.debug("start range... time:{}".format(time.time()))
logger.info("中文測試開始。。。")
for i in range(10):
logger.debug("i:{}".format(i))
time.sleep(0.2)
else:
logger.debug("over range... time:{}".format(time.time()))
logger.info("中文測試結束。。。")
if __name__ == "__main__":
my_logging.load_my_logging_cfg() # 在你程序文件的入口加載自定義logging配置
demo()
python--6、logging模塊