I'm using the logging library and I want to call a function whenever any event is logged. 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
Edit2: I tried implementing one of your suggestions but I'm not 100% sure about how to add it to my current logging configuration.
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'
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. 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
. But is better to rewrite method emit
which is executed by handle
after filtering.
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')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.