logging.LogRecord.getMessage()
通过提供工厂简化了记录记录的操作。我使用我的模块,在每段代码中导入,以使日志记录均匀化:
# 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)
(...)
我的所有脚本都通过
引导记录log = mylogging.mylogging("name_of_the_project")
这很好用。
我现在想跟踪发送的短信数量。为此,我想在mylogging.py
内设置一个计数器,对import mylogging
的所有脚本都是通用的。问题是这样的变量将是每个脚本的本地变量。
另一方面,logging
在某种意义上是特殊的,当不同的脚本使用相同的logging.getLogger(name)
调用name
时,处理程序会被重用 - 这意味着它们之间存在一些持久性脚本(即使每个脚本都是独立的import logging
)。
考虑到这一点,有没有办法使用一个对所有日志记录都通用的变量,放在here is the code which sends an SMS
行之后,无论日志记录请求来自哪个脚本,它都会增加?
答案 0 :(得分: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()))