简体   繁体   English

Python 记录器格式化不格式化字符串

[英]Python logger formatting is not formatting the string

Following are the contents of mylogger.py :以下是mylogger.py的内容:

def get_logger(name='my_super_logger'):
    log = logging.getLogger(name)
    log.setLevel(logging.DEBUG)
    formatter = logging.Formatter(fmt='%(asctime)s %(name)s %(message)s',
                                  datefmt='%m/%d/%Y %I:%M:%S %p')
    if not len(log.handlers):
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(formatter)
        log.addHandler(ch)
    # print(id(log))
    return log

and following is contents of myscript.py :以下是myscript.py的内容:

from mylogger import get_logger

_logger = get_logger()

_logger.info('trying info')
_logger.debug('trying debug')

However I am facing two issues.但是我面临两个问题。 It prints the logs twice and formatter is not working everytime:它会打印两次日志,并且格式化程序每次都无法正常工作:

09/18/2015 09:59:54 PM my_super_logger trying info 
INFO:my_super_logger:trying info 
09/18/2015 09:59:54 PM my_super_logger trying debug 
DEBUG:my_super_logger:trying debug 

What exactly is the issue with my get_logger code?我的get_logger代码到底有什么问题?

I need a custom formatting.我需要自定义格式。 However I found out that without adding a handler I cannot add a formatter .但是我发现如果不添加处理程序,我就无法添加formatter So that's why I have added StreamHandler .这就是我添加StreamHandler的原因。 And the reason for if block is mentioned in this answer .这个答案中提到了if块的原因。 Without that, I would get duplicate log messages printed.没有它,我会打印出重复的日志消息。

The root logger is also emitting the message.根记录器也在发出消息。 Stop propagation up to the root with:停止传播到根:

log.propagate = False

If you wanted to format all log output (so messages propagated up to the logger), set the formatter for the root logger.如果您想格式化所有日志输出(因此消息传播到记录器),请为根记录器设置格式化程序。

You can do so with a logging.basicConfig() call provided nothing has yet been sent to the loggers, or by looping over the logger.handlers list of the root logger;您可以使用logging.basicConfig()调用来执行此操作,前提是尚未将任何内容发送到记录器,或者通过循环遍历根记录器的logger.handlers列表; you could pick out any StreamHandlers if you so wish:如果您愿意,可以选择任何StreamHandlers

root_logger = logging.getLogger()  # no name
for handler in root_logger.handlers:
    if isinstance(handler, logging.Streamhandler):
        handler.setFormatter(formatter)

In my case of a custom handler, I had to call format manually.在我的自定义处理程序的情况下,我必须手动调用format

I create a handler here我在这里创建一个处理程序

    logger_config = {
        "version": 1,
        "disable_existing_loggers": False,
        "formatters": {
            "standard": {"format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"},
        },
        "handlers": {
            "sns": {
                "formatter": "standard",
                "class": "app_logging.SnsHandler.SnsHandler",
                "log_level": os.environ.get("SNS_LOG_LEVEL") or "WARNING",
                "topic_arn": os.environ.get("SNS_LOG_TOPIC") or "hghghjg",
            }
        },
        "level": os.environ.get("LOG_LEVEL") or "DEBUG",
        # Root logger
        "loggers": {
            "": {
                "formatter": "standard",
                "handlers": ["sns"],
                "level": os.environ.get("LOG_LEVEL") or "DEBUG",
            },
        },
    }
    dictConfig(logger_config)

My handler class is here我的处理程序类在这里

from logging import Handler
import boto3


class SnsHandler(Handler):
    def __init__(self, log_level, topic_arn: str, region: str = "us-east-1") -> None:
        super().__init__(log_level)
        self.topic_arn = topic_arn
        self._sns_client = boto3.client("sns", region_name=region)

    def emit(self, record):
        msg = self.format(record)
        return self._sns_client.publish(
            TopicArn=self.topic_arn, Message=msg, Subject="Logging from the application"
        )

Note the call msg = self.format(record) in emit .注意emit中的调用msg = self.format(record) The built-in handlers do this too.内置的处理程序也这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM