国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Python向日志輸出中添加上下文信息

2020-02-16 01:35:09
字體:
來源:轉載
供稿:網友

除了傳遞給日志記錄函數的參數(如msg)外,有時候我們還想在日志輸出中包含一些額外的上下文信息。比如,在一個網絡應用中,可能希望在日志中記錄客戶端的特定信息,如:遠程客戶端的IP地址和用戶名。這里我們來介紹以下幾種實現方式:

通過向日志記錄函數傳遞一個extra參數引入上下文信息 使用LoggerAdapters引入上下文信息 使用Filters引入上下文信息

一、通過向日志記錄函數傳遞一個extra參數引入上下文信息

前面我們提到過,可以通過向日志記錄函數傳遞一個extra參數來實現向日志輸出中添加額外的上下文信息,如:

import loggingimport sysfmt = logging.Formatter("%(asctime)s - %(name)s - %(ip)s - %(username)s - %(message)s")h_console = logging.StreamHandler(sys.stdout)h_console.setFormatter(fmt)logger = logging.getLogger("myPro")logger.setLevel(logging.DEBUG)logger.addHandler(h_console)extra_dict = {"ip": "113.208.78.29", "username": "Petter"}logger.debug("User Login!", extra=extra_dict)extra_dict = {"ip": "223.190.65.139", "username": "Jerry"}logger.info("User Access!", extra=extra_dict)

輸出:

2017-05-14 15:47:25,562 - myPro - 113.208.78.29 - Petter - User Login!
2017-05-14 15:47:25,562 - myPro - 223.190.65.139 - Jerry - User Access!

但是用這種方式來傳遞信息并不是那么方便,因為每次調用日志記錄方法都要傳遞一個extra關鍵詞參數。即便沒有需要插入的上下文信息也是如此,因為該logger設置的formatter格式中指定的字段必須要存在。所以,我們推薦使用下面兩種方式來實現上下文信息的引入。

也許可以嘗試在每次創建連接時都創建一個Logger實例來解決上面存在的問題,但是這顯然不是一個好的解決方案,因為這些Logger實例并不會進行垃圾回收。盡管這在實踐中不是個問題,但是當Logger數量變得不可控將會非常難以管理。

二、使用LoggerAdapters引入上下文信息

使用LoggerAdapter類來傳遞上下文信息到日志事件的信息中是一個非常簡單的方式,可以把它看做第一種實現方式的優化版--因為它為extra提供了一個默認值。這個類設計的類似于Logger,因此我們可以像使用Logger類的實例那樣來調用debug(), info(), warning(),error(), exception(), critical()和log()方法。當創建一個LoggerAdapter的實例時,我們需要傳遞一個Logger實例和一個包含上下文信息的類字典對象給該類的實例構建方法。當調用LoggerAdapter實例的一個日志記錄方法時,該方法會在對日志日志消息和字典對象進行處理后,調用構建該實例時傳遞給該實例的logger對象的同名的日志記錄方法。下面是LoggerAdapter類中幾個方法的定義:

class LoggerAdapter(object): """ An adapter for loggers which makes it easier to specify contextual information in logging output. """ def __init__(self, logger, extra):  """  Initialize the adapter with a logger and a dict-like object which  provides contextual information. This constructor signature allows  easy stacking of LoggerAdapters, if so desired.  You can effectively pass keyword arguments as shown in the  following example:  adapter = LoggerAdapter(someLogger, dict(p1=v1, p2="v2"))  """  self.logger = logger  self.extra = extra def process(self, msg, kwargs):  """  Process the logging message and keyword arguments passed in to  a logging call to insert contextual information. You can either  manipulate the message itself, the keyword args or both. Return  the message and kwargs modified (or not) to suit your needs.  Normally, you'll only need to override this one method in a  LoggerAdapter subclass for your specific needs.  """  kwargs["extra"] = self.extra  return msg, kwargs def debug(self, msg, *args, **kwargs):  """  Delegate a debug call to the underlying logger, after adding  contextual information from this adapter instance.  """  msg, kwargs = self.process(msg, kwargs)  self.logger.debug(msg, *args, **kwargs)            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永昌县| 商南县| 海安县| 都匀市| 会东县| 安徽省| 行唐县| 抚松县| 辛集市| 浦东新区| 阳谷县| 黔东| 延安市| 婺源县| 闻喜县| 保亭| 盈江县| 巫溪县| 广西| 天津市| 阜南县| 绥宁县| 富顺县| 邵东县| 青神县| 朝阳县| 肥乡县| 商河县| 鄂托克前旗| 万盛区| 枣阳市| 电白县| 德钦县| 紫金县| 伊川县| 玉林市| 桑日县| 宜兰县| 陵水| 克什克腾旗| 汝阳县|