我正在使用python logger.以下是我的代码:
import os
import time
import datetime
import logging
class Logger :
def myLogger(self):
logger = logging.getLogger('ProvisioningPython')
logger.setLevel(logging.DEBUG)
now = datetime.datetime.now()
handler=logging.FileHandler('/root/credentials/Logs/ProvisioningPython'+ now.strftime("%Y-%m-%d") +'.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是我在每个logger.info调用的日志文件中都有多个条目.我怎么解决这个问题?
Wer*_*mit 83
这logging.getLogger()已经是单身人士了.(文件)
问题是,每次调用时myLogger(),它都会向实例添加另一个处理程序,从而导致重复日志.
也许是这样的?
import os
import time
import datetime
import logging
loggers = {}
def myLogger(name):
global loggers
if loggers.get(name):
return loggers.get(name)
else:
logger = logging.getLogger(name)
logger.setLevel(logging.DEBUG)
now = datetime.datetime.now()
handler = logging.FileHandler(
'/root/credentials/Logs/ProvisioningPython'
+ now.strftime("%Y-%m-%d")
+ '.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
loggers[name] = logger
return logger
Run Code Online (Sandbox Code Playgroud)
Gui*_*sco 43
import datetime
import logging
class Logger :
def myLogger(self):
logger=logging.getLogger('ProvisioningPython')
if not len(logger.handlers):
logger.setLevel(logging.DEBUG)
now = datetime.datetime.now()
handler=logging.FileHandler('/root/credentials/Logs/ProvisioningPython'+ now.strftime("%Y-%m-%d") +'.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
Run Code Online (Sandbox Code Playgroud)
为我做了伎俩
使用python 2.7
小智 40
从Python 3.2开始,您只需检查处理程序是否已存在,如果存在,请在添加新处理程序之前清除它们.调试时,这非常方便,代码包括记录器初始化
if (logger.hasHandlers()):
logger.handlers.clear()
logger.addHandler(handler)
Run Code Online (Sandbox Code Playgroud)
你Logger.myLogger()不止一次打电话.存储它返回某处的logger实例并重用它.
另请注意,如果在添加任何处理程序之前进行日志记录,StreamHandler(sys.stderr)则会创建默认值.
小智 8
问题是处理程序的数量,如果您有多个处理程序,则您有多个日志,因此您只需在添加之前进行检查:
if not logger.handlers:
logger.addHandler(handler)
Run Code Online (Sandbox Code Playgroud)
logger 的实现已经是单例了。
多次调用 logging.getLogger('someLogger') 返回对同一个记录器对象的引用。这不仅在同一个模块内如此,而且在跨模块时也是如此,只要它在同一个 Python 解释器进程中。对同一对象的引用也是如此;此外,应用程序代码可以在一个模块中定义和配置父记录器,并在单独的模块中创建(但不配置)子记录器,所有对子记录器的调用都将传递给父记录器。这是一个主要模块
源 -在多个模块中使用日志记录
所以你应该使用它的方式是 -
假设我们已经在主模块中创建并配置了一个名为“main_logger”的记录器(它只是配置记录器,不返回任何内容)。
# get the logger instance
logger = logging.getLogger("main_logger")
# configuration follows
...
Run Code Online (Sandbox Code Playgroud)
现在在子模块中,如果我们按照命名层次结构'main_logger.sub_module_logger'创建一个子记录器,我们不需要在子模块中配置它。只需按照命名层次结构创建记录器就足够了。
# get the logger instance
logger = logging.getLogger("main_logger.sub_module_logger")
# no configuration needed
# it inherits the configuration from the parent logger
...
Run Code Online (Sandbox Code Playgroud)
它也不会添加重复的处理程序。
请参阅此问题以获得更详细的答案。
这是对@rm957377 的回答的补充,但解释了为什么会发生这种情况。当您在 AWS 中运行 lambda 函数时,它们会从一个为多次调用而保持活动状态的包装实例中调用您的函数。意思是,如果您addHandler()在函数的代码中调用,则每次函数运行时,它都会继续向日志记录单例添加重复的处理程序。 日志记录单例通过多次调用 lambda 函数而持续存在。
要解决此问题,您可以在通过以下方式设置处理程序之前清除它们:
logging.getLogger().handlers.clear()
logging.getLogger().addHandler(...)
Run Code Online (Sandbox Code Playgroud)
你的记录器应该作为单例工作。您不应多次创建它。下面是它的外观示例:
import os
import time
import datetime
import logging
class Logger :
logger = None
def myLogger(self):
if None == self.logger:
self.logger=logging.getLogger('ProvisioningPython')
self.logger.setLevel(logging.DEBUG)
now = datetime.datetime.now()
handler=logging.FileHandler('ProvisioningPython'+ now.strftime("%Y-%m-%d") +'.log')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
handler.setFormatter(formatter)
self.logger.addHandler(handler)
return self.logger
s = Logger()
m = s.myLogger()
m2 = s.myLogger()
m.info("Info1")
m2.info("info2")
Run Code Online (Sandbox Code Playgroud)
当我们使用不带任何参数的 getLogger() 时,它返回 RootLogger。
因此,如果您在多个位置调用 getLogger() 并添加日志处理程序,它会将这些日志处理程序添加到 RootLogger(如果您不显式添加日志处理程序,它将自动添加 StreamHandler)。因此,当您尝试记录消息时,它将使用添加到 RootLogger 的所有处理程序来记录消息。这就是重复日志的原因。
您可以通过在调用 getLogger() 时提供不同的记录器名称来避免这种情况。就像是
logger1 = logging.getLogger("loggera")
logger2 = logging.getLogger("loggerb")
Run Code Online (Sandbox Code Playgroud)
这对我有用。
| 归档时间: |
|
| 查看次数: |
49921 次 |
| 最近记录: |