简体   繁体   English

记录某些内容时如何调用 Python function

[英]How do I call a Python function when something is logged

I'm using the logging library and I want to call a function whenever any event is logged.我正在使用日志库,我想在记录任何事件时调用 function。 Something like this:像这样的东西:

import logging

#logging config here

async def on_log(message, level): #call this whenever something is logged
    print(level, ":", message)

logging.debug("Hello world")

Edit: on_log is a coroutine编辑: on_log是一个协程

Edit2: I tried implementing one of your suggestions but I'm not 100% sure about how to add it to my current logging configuration. Edit2:我尝试实施您的建议之一,但我不能 100% 确定如何将其添加到我当前的日志记录配置中。

from logging import *
import datetime
import sys

class MyLogger(Handler):
    def emit(*args):
        for item in args:
            print(item)

time = datetime.datetime.today()
logtime = f"{time.year}-{time.month}-{time.day}__{time.hour}h-{time.minute}m-{time.second}s"

file_handler = FileHandler(filename=f'./logs/{logtime}.log')  # File output
stdout_handler = StreamHandler(sys.stdout)  # Console output

basicConfig(
    format=f'[%(asctime)s][%(levelname)s] %(message)s',
    datefmt='%H:%M:%S',
    level=DEBUG,
    handlers=[file_handler, stdout_handler, MyLogger]
)

I get this error: AttributeError: type object 'MyLogger' has no attribute 'formatter'我收到此错误: AttributeError: type object 'MyLogger' has no attribute 'formatter'

It is minimal working code这是最小的工作代码

import logging

# --- classes ---

class MyLogger():

    #level = logging.NOTSET
    level = logging.DEBUG

    def handle(*args):
        print('--- args ---')
        for item in args:
            print(item)
        print('---')

# --- main ---

logger = logging.getLogger('test')
logger.setLevel(logging.DEBUG) 
#logger.setLevel(logging.INFO) 

my_logger = MyLogger()
#my_logger.level = logging.DEBUG

logger.addHandler(my_logger)

# --- test ---

logger.debug("DEBUG: Hello world")
logger.info("INFO: Hello world")

It can't be function but class with method handle and in variable level because every handler has own level.它不能是 function 但 class 具有方法handle和可变level ,因为每个处理程序都有自己的级别。 This way some handlers can be executed always, other only for debug message.这样一些处理程序可以始终执行,其他仅用于调试消息。


EDIT:编辑:

The same using class Handler which already has variable level and you have to only rewrite method handle .同样使用 class 处理程序,它已经具有可变level ,您只需重写方法handle But is better to rewrite method emit which is executed by handle after filtering.但是最好重写过滤后由handle执行的方法emit

You can set level when you create instance.您可以在创建实例时设置级别。

import logging

# --- classes ---

class MyLogger(logging.Handler):
    
    #def handle(*args):
    def emit(*args):
        print('--- args ---')
        for item in args:
            print(item)
        print('---')
        
# --- main ---

logger = logging.getLogger('test')
logger.setLevel(logging.DEBUG) 
#logger.setLevel(logging.INFO) 

my_logger = MyLogger(logging.DEBUG)

logger.addHandler(my_logger)

# --- test ---

logger.debug("DEBUG: Hello world")
logger.info("INFO: Hello world")

The comments recommend using a custom handler but I would advise against it since there is a way to do this that is also proposed in the official documentation by using filters.评论建议使用自定义处理程序,但我建议不要这样做, 因为官方文档中也提出了一种使用过滤器的方法。 In the specific case here it would work like this:在这里的具体情况下,它会像这样工作:

import logging

def on_log(record):
    print(record.levelname, ":", record.getMessage())
    return True

logging.root.addFilter(on_log)

logging.warning('some log')

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

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