成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

python logging 日志重復(fù)打印問題定位

crossea / 3495人閱讀

摘要:在同一系統(tǒng)中我們有時要用到這種機制來方便日志打印,因此有時會不同進程使用同一前綴名來初始化。避免日志重復(fù)的原則是在名有相同前綴的情況下對于一個模塊兩個進程調(diào)的情況,涉及到會被其他進程的模塊,不應(yīng)觸發(fā)任何同名前綴的的操作。

圖:

圖編號按順序1-4,嫌長可以跳過定位過程看總結(jié)

定位過程:

我司項目幾個服務(wù)進程的初始化log都是這樣的:

這些進程都會初始化一個叫 sdsomlogger,并且把handler加到了這個logger對象中,后面getlogger的時候我們是 sdsom.xx, 這個按點分隔會導(dǎo)致認(rèn)為是子logger,比如是sdsom.A,就會新建一個loggersdsom.A,然后把 sdsom 這個logger設(shè)為它的parent(圖1),打日志的時候,會一直往上遍歷,把所有parent的所有handler都打一遍(圖2)。這些實例進程間是獨立的,但如果在一個進程里,比如在A進程中 import 了 B 的模塊,而這個模塊 import 了B自己的log.py模塊,觸發(fā)一次 addHandler (圖3),就把 B 的 handler 加進了 A進程的 sdsom logger里(把它設(shè)為了parent),所以 A 的 sdsom logger里有兩個handler (圖4),于是A 的log同時打到了B的日志文件里。(注意對比圖3 圖4的對象地址 是一致的)

這個logger父子關(guān)系前人要這么用的原因,我估計是我們項目的common這個模塊,用父子關(guān)系可以實現(xiàn)這樣一個方式:不需另外初始化,log = logging.getLogger("sdsom.common") 只需要執(zhí)行這一句,這個loggerparent就被設(shè)為 <import這個common模塊的> 進程的 sdsom logger,實際上sdsom.xxx 點號后面的內(nèi)容都沒有影響了,這個common logger打印時,會調(diào)parent,于是也就被相應(yīng)進程的handler打印了。
本身也算方便的機制,但由于這種方式內(nèi)部實現(xiàn)不可見, 容易誤用。

如果要共享日志, 還有一種方式就是對相應(yīng)的logger顯式加handler
比如要在其他日志里打印zerorpc的日志, 我們大部分日志初始化處都有這句: logging.getLogger("zerorpc").addHandler(handler), 給rpcLogger加上自己的handler就可以了,由于有了handler,那么只要zerorpc的源碼里是getLogger("zerorpc")的(實際源碼中一般是getLogger(__name__),在包內(nèi)__name__即為"zerorpc.xxx"),日志就能打印到對應(yīng)進程的日志里。
所以我們完全可以不用父子關(guān)系,而是像zerorpc一樣在進程logger初始化的地方加上:
logging.getLogger("common").addHandler(handler)
然后common里的模塊直接log = logging.getLogger("common")用即可,為避免和三方庫重復(fù)要注意一下命名
當(dāng)然還有一種方式就是自己的handler也通過函數(shù)觸發(fā),不要在模塊全局上執(zhí)行,加入一個函數(shù)手動調(diào),只在進程初始化時調(diào)。

總結(jié):

logging的父子關(guān)系是一個基礎(chǔ)機制,稍微看下源碼即可理解(其實主要就是圖1圖2):以點號.分隔,取最后一個點號的左邊為前綴,以此前綴名作父,一個logger觸發(fā)記錄時,會調(diào)用所有父親的handler。在同一系統(tǒng)中我們有時要用到這種機制來方便日志打印,因此有時會不同進程使用同一前綴名來初始化logger。這時,不同進程的模塊若有相互import,容易造成一個日志打到多個日志文件里。如:

進程A:
A.py:
logger = logging.getLogger("xxsystem.A")
logger.addHandler(logging.FileHandler("service1.log"))
進程B 兩個模塊:

B.py:
from C import func
logger = logging.getLogger("xxsystem.B")
logger.addHandler(logging.FileHandler("service2.log"))

C.py:
from A import func

這樣,就會造成B進程的log總是同時打到兩個service1.log, service2.log日志文件里。這里是簡化環(huán)境,只要B的import樹里有A模塊,就會造成同樣結(jié)果。

避免日志重復(fù)的原則是:
logger名有相同前綴的情況下,對于一個模塊兩個進程調(diào)的情況,涉及到會被其他進程import的模塊,不應(yīng)觸發(fā)任何同名前綴的loggeraddHandler操作。 (不能import <調(diào)用了addHandler方法的> 模塊,自身也不能執(zhí)行getLogger(prefix).addHandler

實際上我司使用這種機制本來也沒有什么問題,只要注意不要隨便import,都用getLogger即可。但由于代碼不規(guī)范還是出現(xiàn)了不應(yīng)有的import 日志初始化模塊的情況。

要達(dá)到:

哪個進程調(diào)用模塊,日志就打在那個進程對應(yīng)的日志里:
a)getLogger,只要前綴相同,就會把當(dāng)前進程的"prefix" logger設(shè)為父, 由于上面說的原因,這個logger會且只會被打到調(diào)用它的進程中(自己的handler沒有初始化過)
b)logger對象

無論哪個進程調(diào)用模塊,日志都打在自己規(guī)劃所屬的進程對應(yīng)日志里:
不要有任何父子關(guān)系, 日志名不要帶點。這時反過來,必須調(diào)用日志初始化模塊觸發(fā)初始化,而不能只用getLogger, 否則是一個空logger,哪里都不會打印。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/44962.html

相關(guān)文章

  • 基于Selenium + Python的web自動化框架

    摘要:一什么是是一個基于瀏覽器的自動化工具,她提供了一種跨平臺跨瀏覽器的端到端的自動化解決方案。模塊主要用來記錄用例執(zhí)行情況,以便于高效的調(diào)查用例失敗信息以及追蹤用例執(zhí)行情況。測試用例倉庫用例倉庫主要用來組織自動化測試用例。 一、什么是Selenium? Selenium是一個基于瀏覽器的自動化工具,她提供了一種跨平臺、跨瀏覽器的端到端的web自動化解決方案。Selenium主要包括三部分:...

    sunny5541 評論0 收藏0
  • Python中的logging模塊

    摘要:最近修改了項目里的相關(guān)功能,用到了標(biāo)準(zhǔn)庫里的模塊,在此做一些記錄??赡軟]有線程名??赡軟]有用戶輸出的消息日志級別有如下級別,,,,默認(rèn)級別是,模塊只會輸出指定以上的。在或者中這是很常見的方式。正常的做法應(yīng)該是全局只配置一次。 最近修改了項目里的logging相關(guān)功能,用到了python標(biāo)準(zhǔn)庫里的logging模塊,在此做一些記錄。主要是從官方文檔和stackoverflow上查詢到的一...

    zsirfs 評論0 收藏0
  • pythonlogging 模塊淺析

    摘要:的繼承關(guān)系使用做日志輸出時,首先我們需要一個創(chuàng)建一個對象。再設(shè)計多級別的日志系統(tǒng)時,尤其要注意這點。當(dāng)然,這樣做其實是有悖于的本意的。是什么是一個程序內(nèi)全局唯一的,所有對象的祖先。因此,直接修改是危險的。 0x00 python logging的繼承關(guān)系 使用python做日志輸出時,首先我們需要一個創(chuàng)建一個Logger對象:import logging; logger = log...

    cooxer 評論0 收藏0
  • Unity命令行模式,也能「日志實時輸出」

    摘要:類似這樣執(zhí)行打印最終輸出的日志要想在命令行模式工作的時候,查看它的編譯進度,霖哥一般會遠(yuǎn)程跑進執(zhí)行編譯工作的機器,然后用命令,把它的日志實時輸出來嗯,這相當(dāng)?shù)牟豢茖W(xué)啊。我是霖哥,一個商學(xué)院畢業(yè)的程序員,一個游戲開發(fā)工程師。 showImg(https://segmentfault.com/img/remote/1460000008856262); 如果你使用過Unity命令行模式(ba...

    whjin 評論0 收藏0
  • python學(xué)習(xí)筆記-裝飾器

    摘要:裝飾器介紹中的裝飾器的目的是為一個目標(biāo)函數(shù)添加額外的功能卻不修改函數(shù)本身。裝飾器的本身其實是一個特殊的函數(shù)。那么有啥更好的解決方式呢裝飾器代碼像上面這么寫,可以較好地解決了上面提到的第一個問題。裝飾器語法糖放在函數(shù)前面,相當(dāng)于執(zhí)行了等。 怎么理解python中的裝飾器 一個比喻 知乎上有一個比較形象的比喻 https://www.zhihu.com/questio...:人類穿著內(nèi)褲很...

    張金寶 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<