logging模塊
日志
1 簡介
? 追蹤某些軟件運行時所發(fā)生事件的方法, 可以在代碼中調(diào)用日志中某些方法來記錄發(fā)生的事情
- 一個事件可以用一個可包含可選變量數(shù)據(jù)的消息來描述
- 事件有自己的重要性等級
2 作用
? 通過對log的分析, 可以了解你想通過程序了解的事情
- 系統(tǒng)或軟件、應(yīng)用的運行情況
- 豐富的log還可以分析用戶的操作行為、類型喜好、地域分布等其他信息
- 在一個應(yīng)用中對log進行多級區(qū)分镜会,可以分析應(yīng)用的健康狀況剂碴,并可以快速定位問題猾编,加以解決
3 日志等級
? 等級區(qū)分可以讓我們更好的‘避輕就重’逝薪,讓我們在排查故障的時候免于淹沒在日志的海洋里, 簡單列舉出所有的等級
- DEBUG
- INFO
- NOTICE
- WARNING
- ERROR
- CRITICAL
- ALERT
- EMERGENCY
4 日志字段信息和格式
? 日志即記錄, 需要知道
- 時間
- 位置
- 嚴重級別
- 內(nèi)容
- 其他
其中日志內(nèi)容和級別需要明確指定, 其他字段信息只需要指出是否需要顯示
logging
1 logging日志級別
? 雖然可以自定義日志等級, 但是建議使用默認等級
DEBUG
? 最詳細日志信息, 多用于問題診斷INFO
? 僅次于DEBUG, 多用于記錄關(guān)鍵點信息, 確保程序按預(yù)期執(zhí)行
WARNING
? 低等級故障, 但程序仍能運行, 如磁盤空間不足警告ERROR
? 由于比WARNING嚴重的問題, 導(dǎo)致某些功能不能正常運行時的記錄CRITICAL
? 嚴重錯誤, 導(dǎo)致應(yīng)用程序不能繼續(xù)運行時的記錄
? 開發(fā)部署階段, 使用DEBUG或INFO獲取盡可能詳盡的日志來進行開發(fā);
? 上線時應(yīng)該使用WARNING或ERROR或CRITICAL級別日志來降低機器I/O壓力, 提高獲取日志信息的效率
DEBUG < INFO < WARNING < ERROR < CRITICAL
指定某級別后, 記錄此級別以及更高級別的日志信息, 而不僅僅只記錄指定級別
使用方式
1. 使用logging提供的模塊級別函數(shù)
函數(shù)說明
a logging.五個級別(msg, *args, **kwargs)
創(chuàng)建這幾個級別的日志記錄
b logging.log(level, *args, **kwargs)
創(chuàng)建級別為level的日志記錄
c logging.basicConfig(**kwargs)
進行一次性配置
其中
basicConfig
用于指定 日志級別 日志格式 日志輸出位置 日志文件的打開模式;
2. 使用logging日志系統(tǒng)四大組件
a loggers
? 提供應(yīng)用程序代碼直接使用的接口
b handlers
? 用于將日志記錄發(fā)送到指定的目的位置
c filters
? 過濾, 決定哪些輸出哪些日志記錄, 其余忽略
d formatters
? 控制日志輸出格式
logging模塊級別實際上是使用這四大組件加上一些基礎(chǔ)配置實現(xiàn)的
模塊級別函數(shù)使用
嘗試使用:
In [1]: import logging
In [2]: logging.debug('debug')
In [3]: logging.info('info')
In [4]: logging.warning('warning')
WARNING:root:warning
In [5]: logging.error('error')
ERROR:root:error
In [6]: logging.critical('critical')
CRITICAL:root:critical
? 發(fā)現(xiàn)當(dāng)級別達到WARNING后才會輸出, 正如我們前面所說, 模塊級別是四大組件的小擴展, 這個擴展就配置了日志級別是WARNING, 所以小于這個級別的debug和info就會被忽略
WARNING:root:warning
日志級別:日志器名稱:日志內(nèi)容
這也是小擴展里的BASIC_FORMAT的值設(shè)置為了
%(levelname)s:%(name)s:%(message)s
以上這些可以通過修改logging.basicConfig(**kwargs)
函數(shù)的參數(shù)
- filename 輸出目標(biāo)文件文件名, 指定后不會輸出到控制臺
- filemode 指定日志文件打開模式, 默認為'a', 添加模式, 且在filename指定后才生效
- format 格式
- datefmt 日期格式, format中包含時間字段(%(asctime)s)時生效
- level 日志級別
format:
-
%(asctime)s
人類可讀時間 -
%(created)f
時間戳, 等同于time.time()
-
%(relativeCreated)d
日志發(fā)生的時間相對于logging模塊加載時間的相對毫秒數(shù) -
%(msecs)d
日志時間發(fā)生的毫秒部分 -
%(levelname)s
日志級別str格式 -
%(levelno)s
日志級別數(shù)字形式(10, 20, 30, 40, 50) -
%(name)s
日志器名稱, 默認root -
%(message)s
日志內(nèi)容 -
%(pathname)s
日志全路徑 -
%(filename)s
文件名含后綴 -
%(module)s
文件名不含后綴 -
%(lineno)d
調(diào)用日志記錄函數(shù)源代碼的行號 -
%(funcName)s
調(diào)用日志記錄函數(shù)的函數(shù)名 -
%(process)d
進程id -
%(processName)s
進程名稱 -
%(thread)d
線程ID -
%(threadName)s
線程名稱
import logging
# 日志格式
LOG_FORMAT="%(lineno)d - %(asctime)s - %(levelno)s - %(levelname)s - %(name)s - %(message)s - %(process)d - %(thread)d - %(module)s - %(funcName)s"
# 日期格式
DATE
logging.basicConfig(filename='my.log', level=logging.DEBUG, format=LOG_FORMAT)
logging.debug('debug log')
logging.warning('warning log')
# my.log
12 - 08/24/2018 19:42:24 PM - 10 - DEBUG - root - debug log - 13144 - 4464 - test - <module>
13 - 08/24/2018 19:42:24 PM - 30 - WARNING - root - warning log - 13144 - 4464 - test - <module>
可以修改每個占位格式的占位寬度:
%(lineno)-10d
, 占10個寬度; 其他修改類似
logging.basicConfig()
只在第一次調(diào)用時起作用, 后續(xù)再調(diào)用無效- 如果需要日志中包含變量, 可將格式字符串作為第一個參數(shù)
msg
的傳入, 變量數(shù)據(jù)作為第二個參數(shù)*args
的傳入, 如logging.warning('%s - %d', 'book', 10)
- 對于**kwargs, 支持三個關(guān)鍵字
exc_info
: 布爾類型, 默認False, 為True則將異常信息添加到日志, 沒有異常添加None
stack_info
: 布爾類型, 默認False, 如為True, 棧信息將會被添加到日志
extra
: 字典參數(shù), 可自定義消息格式所包含字段, 但鍵不能與logging模塊定義字段沖突
import logging
FORMAT = '%(asctime)-15s %(clientip)s %(user)-8s %(message)s'
logging.basicConfig(format=FORMAT)
d = {'clientip': '192.168.0.1', 'user': 'fbloggs'}
logging.warning('Protocol problem: %s', 'connection reset', extra=d)
logging.error('error log', exc_info=True, stack_info=True, extra=d)
# my.log
2018-08-24 20:03:00,927 192.168.0.1 fbloggs Protocol problem: connection reset
2018-08-24 20:03:00,928 192.168.0.1 fbloggs error log
NoneType: None
Stack (most recent call last):
File "E:\1coding\temp\test\test.py", line 10, in <module>
logging.error('error log', exc_info=True, stack_info=True, extra=d)
給FORMAT添加了自定義字段, 就要在每個logging里都加上該字段對應(yīng)的關(guān)鍵字參數(shù), 否則報錯
日志模塊四大組件
- 日志器 Logger : 提供應(yīng)用程序使用接口
- 處理器 Handler: 創(chuàng)建日志記錄, 發(fā)送到合適目的地
- 過濾器 Filter: 對日志進行過濾存儲
- 格式器 Formatter: 決定日志輸出格式
logging模塊就是通過這些組件處理日志
日志器(logger)可以通過一個或多個處理器(handler)將一條日志信息輸出到不同的目標(biāo)位置
并且每個處理器(handler)都可以設(shè)置自己的過濾器(fileter)和格式器(formatter)來決定日志輸出內(nèi)容
- Logger類
作用:
a. 設(shè)置日志等級
b. 提供寫日志接口
c. 添加或移除處理器
d. 添加或移除過濾器
a> 設(shè)置等級:
Logger.setLevel(logging.級別)
- `Logger.setLevel(logging.ERROR)
b> 接口
Logger.級別()
- Logger.debug()
未完待續(xù)...