日志中变量的范围是什么?

时间:2015-11-20 16:16:23

标签: python python-3.x logging

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行之后,无论日志记录请求来自哪个脚本,它都会增加?

1 个答案:

答案 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()))