2015-11-20 61 views
0

logging.LogRecord.getMessage()通過提供工廠簡化了日誌記錄的操作。我用我的一個模塊,在每一段代碼進口,以均質化日誌記錄:通過日誌記錄中變量的作用域是什麼?

log = mylogging.mylogging("name_of_the_project") 

這工作得很好

# this is mylogging.py 
import logging 
import logging.handlers 

def mylogging(name): 
    old_factory = logging.getLogRecordFactory() 
    def record_factory(*args, **kwargs): 
     record = old_factory(*args, **kwargs) 
     # send an SMS for critical events (level = 50) 
     if args[1] == 50: 
      pass # here is the code which sends an SMS 
     return record 
    logging.setLogRecordFactory(record_factory) 

    # common logging info 
    log = logging.getLogger(name) 
    log.setLevel(logging.DEBUG) 
    (...) 

我所有的腳本引導記錄。

我現在想跟蹤發送的短信數量。爲此,我想在mylogging.py之內設置一個計數器,這對所有import mylogging的腳本通用。問題是這樣的變量對於每個腳本都是本地的。

在另一方面,logging是在這個意義上,當不同的腳本調用logging.getLogger(name)具有相同name,處理程序被重複使用特殊的 - 這意味着有腳本之間的一些持久性(儘管他們每個人做一個獨立的import logging )。

記住這一點,是否有一種方法可以使用一個變量,該變量對於所有日誌都是通用的,放在here is the code which sends an SMS行之後,無論日誌請求來自哪個腳本,哪個腳本都會增加?

+0

你使用術語 「腳本」 目前尚不清楚。你是否多次執行Python解釋器並試圖讓值在整個運行過程中保持不變?或者你在談論單個Python程序中使用的多個模塊?在單個Python解釋器運行中,無論有多少個模塊導入「mylogging」,只有一個「mylogging.counter」。 – user2357112

回答

1

的進口,如

from mylogging import mycounter 
mycounter += 1 

增加在當地的模塊命名空間的新引用mycounter。對於不可變類型(如整型計數器),只能在本地命名空間中重新綁定值 - 其他模塊會在導入點處看到該值。

一個解決方案是保留原來的名稱空間,以便重新綁定發生在mylogger本身。

import mylogger 
mylogger.mycounter += 1 

這是脆弱的。它不是很明顯,它只是因爲導入完成的方式才起作用。

更好的解決方案是使用可變類型。 itertools.count很有趣,但不會讓您查看計數器的當前值。這是一個簡單的課程,可以做到這一點。我已經添加了鎖定,以便它也可以在多線程環境中工作。

添加到mylogger.py

import threading 

class MyCounter(object): 

    def __init__(self): 
     self.val = 0 
     self.lock = threading.Lock() 

    def inc(self): 
     with self.lock: 
      self.val += 1 
     return self.val 

sms_counter = MyCounter() 

一些其他模塊

from mylogger import sms_counter 
print('sms count is {}'.format(sms_counter.inc())) 
+0

謝謝。你的回答不僅直接解決了我的問題,而且幫助我理解我正在啓動流程而不是線程 - 這會影響變量的作用域。 – WoJ

相關問題