假设我有一个客户端和服务器类:
import logging
class Client:
def __init__(self, name):
self.logger = logging.getLogger(self.__class__.__name__)
self.name = name
def foo(self):
self.logger.warn('[%s] foo', self.name)
class Server:
def __init__(self):
self.logger = logging.getLogger(self.__class__.__name__)
def bar(self):
self.logger.warn('bar')
Run Code Online (Sandbox Code Playgroud)
我怎样才能为客户端制作一个能够[self.name]神奇地处理前缀的记录器?我唯一的想法是设置一个全局格式,包括%(client)-prefix和使用自定义过滤器Client.这似乎是不必要的复杂和全球性的.我觉得必须有一种我没看到的简单方法.
Vin*_*jip 10
这可以在不使用自定义的任何附加的依赖性来完成LoggerAdapter:
import logging
class LoggerAdapter(logging.LoggerAdapter):
def __init__(self, prefix, logger):
super(LoggerAdapter, self).__init__(logger, {})
self.prefix = prefix
def process(self, msg, kwargs):
return '[%s] %s' % (self.prefix, msg), kwargs
class Client:
def __init__(self, name):
logger = logging.getLogger(self.__class__.__name__)
self.logger = LoggerAdapter(name, logger)
self.name = name
def foo(self):
self.logger.warning('foo: %s', 'bar')
client = Client('client1')
logging.basicConfig(format='%(message)s')
client.foo()
Run Code Online (Sandbox Code Playgroud)
哪个应该打印
[client1] foo: bar
Run Code Online (Sandbox Code Playgroud)
使用 LoggerAdapter:
logger = PrefixLoggerAdapter(logger, dict(prefix='username'))
logger.info('hey')
# INFO [username] hey
Run Code Online (Sandbox Code Playgroud)
这是课程:
class PrefixLoggerAdapter(logging.LoggerAdapter):
""" A logger adapter that adds a prefix to every message """
def process(self, msg: str, kwargs: dict) -> (str, dict):
return (f'[{self.extra["nickname"]}] ' + msg, kwargs)
Run Code Online (Sandbox Code Playgroud)
这可以使用该库来完成logaugment(免责声明:我创建该库是为了使其更容易,但这也可以使用标准库来完成)。
填写客户端名称可以作为记录器的一部分来完成,记录器Formatter将日志记录格式化为字符串,并且在该步骤中您可以为消息添加前缀。
创建一个记录器:
import logging
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter("%(client)s: %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
Run Code Online (Sandbox Code Playgroud)
%(client)s指定此记录器的客户端名称(即在上述格式化日志字符串中填写的值:
logaugment.set(logger, client='Client')
Run Code Online (Sandbox Code Playgroud)
从现在开始,您可以正常调用记录器方法,并且客户端的名称将自动填写:
logger.warn("My message")
Run Code Online (Sandbox Code Playgroud)