创建日志消息前缀的记录器

Zul*_*lan 4 python logging

假设我有一个客户端和服务器类:

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)


kol*_*pto 7

使用 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)


Sim*_*ser 4

这可以使用该库来完成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)