摘要:原因是,直接傳遞格式化后的字符串會導(dǎo)致參數(shù)被完全求值,這個有可能是非必要的,會導(dǎo)致日志性能下降。添加一個過濾器用來進行消息格式化上面的中的中文注釋部分直接說明了解決方案。
問題
Python的logging庫是標(biāo)準(zhǔn)庫中用來實現(xiàn)日志的庫,功能強大,而且使用起來也算是方便。該庫提供了很多個不同的Handler,用來對日志進行不同的處理。例如FileHandler用來將日志記錄到文件,RotateFileHandler用來將日志記錄到文件而且支持日志文件滾動備份,還有本文中所說的HttpHandler,可以將日志通過HTTP請求發(fā)送到服務(wù)器上。
使用Python的logging模塊的過程大約有如下幾個步驟:
根據(jù)配置文件、配置字典或者調(diào)用方法的方式初始化日志配置,并獲取一個logger。
調(diào)用logger實例的如下方法來發(fā)出一條日志:critical, error, warning, info, debug。這些方法的定義如下,以info為例:
logger.info(fmt, *args, exc_info, extra)
P.S. 本文的目的不是說明logging如何使用,所以具體的用法請參考官方文檔。
當(dāng)logger對象調(diào)用info等方法發(fā)出一條日志時,他可以接受像C語言中的printf函數(shù)或者Python3中的pritnf函數(shù)一樣的前兩個參數(shù):格式化字符串和對應(yīng)的參數(shù)列表,用來表示要發(fā)出的日志的內(nèi)容。當(dāng)logging模塊真的要發(fā)出這條日志時,才會對字符串進行格式化,并且加入最終的日志字符串中。因此,在Python參考手冊(第4版)中(19.7節(jié),289頁)有強調(diào)了如下這一點:發(fā)出日志消息時,應(yīng)該避免在發(fā)出消息時帶有字符串格式化的代碼(即格式化一條消息,然后把結(jié)果傳遞到日志記錄模塊中)。原因是,直接傳遞格式化后的字符串會導(dǎo)致參數(shù)被完全求值,這個有可能是非必要的,會導(dǎo)致日志性能下降。舉個例子:
正確方式: logger.info("hello, %s", "myname") 錯誤方式: logger.info("hello, %s" % "myname")
那么問題來了,如果一個logger的handler使用了HttpHandler,這個坑爹貨居然不會在發(fā)出日志前對日志內(nèi)容部分進行格式化,而是只發(fā)送了前面的fmt字符串到http服務(wù)器,結(jié)果就像下面這樣:
WARNING Tue Jan 27 15:27:34 2015 admin.config 192.168.100.126 POST /user/login User [%s] logged in failed.
而我們期待的應(yīng)該是:
WARNING Fri Jan 23 11:36:45 2015 admin.config 192.168.100.126 POST /user/login User [admin] logged in failed.
解決方法使用logging模塊提供的Filter功能。
直接給出實例代碼:
# -*- coding: utf-8 -*- import logging import logging.config import logging.handlers log_config_dict = { "version": 1, "formatters": { "format_def": { "format": "%(levelname)-8s %(asctime)s %(name)s %(ip)s " "%(method)s %(path)s %(message)s", }, }, "handlers": { "handler_http": { "class": "logging.handlers.HTTPHandler", "formatter": "format_def", "level": "INFO", "host": "192.168.100.1:8888", "url": "/log/admin", "method": "POST", }, }, "loggers": { "admin.config": { "level": "INFO", "propagate": 0, "handlers": ["handler_http"], }, "admin.api": { "level": "INFO", "propagate": 0, "handlers": ["handler_http"], } }, } class RequestFilter(logging.Filter): """A filter used to add extra information to a record. Add ip, method and path information to a record for a HTTP request. Attributes: name: logger"s name """ def __init__(self, name): self.name = name def filter(self, record): # 這里調(diào)用getMessage()方法得到格式化后的日志內(nèi)容, # HTTP服務(wù)器上只要讀取POST中的message參數(shù)即可。 record.message = record.getMessage() return True def init_log(): logging.config.dictConfig(log_config_dict) def get_logger(name): if type(name) is not str: return None log = logging.getLogger(name) log.addFilter(RequestFilter(name)) # 添加一個過濾器用來進行消息格式化 log.addHandler(logging.NullHandler()) return log def get_config_logger(): return get_logger("admin.config") def get_api_logger(): return get_logger("admin.api")
上面的中的中文注釋部分直接說明了解決方案。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/45341.html
摘要:上一篇文章模塊分析第節(jié)模塊一日志記錄的級別優(yōu)先級,記錄調(diào)試的詳細(xì)信息,只在調(diào)試時開啟優(yōu)先級,記錄普通的消息,報告錯誤和警告等待。監(jiān)聽端口號上一篇文章模塊分析第節(jié)模塊 上一篇文章:Python模塊分析:第3節(jié)-typing模塊 一、日志記錄的級別 debug:優(yōu)先級10,記錄調(diào)試的詳細(xì)信息,只在調(diào)試時開啟 info:優(yōu)先級20,記錄普通的消息,報告錯誤和警告等待。 warning:優(yōu)...
Python整個底層的邏輯還是比較的復(fù)雜的,內(nèi)容也是比較的多,那么,Python如何進行異步處理操作呢?通俗來說,就是怎么同步發(fā)送日志到遠(yuǎn)程服務(wù)器?下面就一步一步的給大家解答,請仔細(xì)閱讀哦?! ”尘啊 ≡赑ython中使用日志最常用的方式就是在控制臺和文件中輸出日志了,logging模塊也很好的提供的相應(yīng)的類,使用起來也非常方便,但是有時我們可能會有一些需求,如還需要將日志發(fā)送到遠(yuǎn)端,或者直接...
摘要:它的構(gòu)造函數(shù)是其中參數(shù)是一個文件對象。它的構(gòu)造函數(shù)是是文件名,必須指定一個文件名。用于指定日志文件的最大文件大小。它的構(gòu)造函數(shù)是其中參數(shù)和參數(shù)和具有相同的意義。表示時間間隔的單位,不區(qū)分大小寫??赡軟]有線程名。 0.前置說明 1.運行環(huán)境:Win7虛擬機、python2.7(anacoda版) 2.本文大部分內(nèi)容引用此參考文獻(xiàn):http://my.oschina.net/leeju...
摘要:百度云搜索搜網(wǎng)盤淘寶券使用代理格式化,第一個參數(shù),請求目標(biāo)可能是或者對應(yīng)設(shè)置初始化將代理設(shè)置成全局當(dāng)使用請求時自動使用代理引入隨機模塊文件格式化注意第一個參數(shù)可能是或者,對應(yīng)設(shè)置初始化將代理設(shè)置成全局當(dāng)使用請求時自動使用代理請求 【百度云搜索:http://bdy.lqkweb.com】 【搜網(wǎng)盤:http://www.swpan.cn】 【淘寶券:http://www.tbquan....
摘要:確認(rèn)一切按預(yù)期運行。表明發(fā)生了一些意外,或者不久的將來會發(fā)生問題如磁盤滿了。由于更嚴(yán)重的問題,軟件已不能執(zhí)行一些功能了。嚴(yán)重錯誤,表明軟件已不能繼續(xù)運行了。對于不能獲取的名稱,則記錄到模塊。 最近在寫一些python腳本,總是使用print來打印信息感覺很low,所以抽空研究了一下python的logging庫,來優(yōu)雅的來打印和記錄日志: 一、簡單的將日志打印到屏幕: import l...
閱讀 1978·2021-11-22 15:33
閱讀 3009·2021-11-18 10:02
閱讀 2622·2021-11-08 13:16
閱讀 1632·2021-10-09 09:57
閱讀 1378·2021-09-30 09:47
閱讀 2013·2019-08-29 13:05
閱讀 3075·2019-08-29 12:46
閱讀 1013·2019-08-29 12:19