asynchronous logging with Python
项目中通常会用Python logging
模块做发报警邮件、发日志到logstash
等功能,甚至可以发送到slack、telegram这类应用。可能是logging
模块太好了,用来做这些notification都足够了。但如果有频繁的log请求或者比较高的响应要求,可能就会有很多时间花在这些网络日志的连接与断开上,因此想想大Python应该有异步日志之类的第三方模块吧。找了半天没有合适的可以满足我这类通用网络日志的模块,遂自己写了个。
主要用的是threading
模块,当然如果觉得不合适可以用Celery
。思路很简单,重载logging.Handler
来写自己的日志处理。考虑到网络日志可能有如上各种应用,再加上如果需要使用Celery
的话handler function需要可序列化,因此传个回调给handler实例,并在emit
方法中调用。这个回调里做网络日志的各种操作,这样就可以做到足够的可定制化,话不多说,上代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import logging import time
from celery import shared_task
from asynclog import AsyncLogDispatcher
@shared_task def write_task(msg): print(msg)
celery_handler = AsyncLogDispatcher(write_task, use_thread=False, use_celery=True) celery_handler.setLevel(logging.INFO) logger.addHandler(celery_handler)
logger.info('Test Log')
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| def write_log(msg): time.sleep(0.5)
logger = logging.getLogger() logger.setLevel(logging.INFO) handler = AsyncLogDispatcher(write_log) handler.setLevel(logging.INFO) logger.addHandler(handler)
logger.info('Test Log')
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| log_cfg = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'simple': { 'format': '%(asctime)s \n %(levelname)s \n %(message)s' }, }, 'handlers': { 'async_handler': { 'level': 'INFO', 'formatter': 'simple', 'class': 'asynclog.AsyncLogDispatcher', 'func': 'write_log', } }, 'loggers': { 'asynclogger': { 'handlers': ['async_handler', ], 'level': 'DEBUG', 'propagate': False, }, } }
logging.config.dictConfig(log_cfg) logger = logging.getLogger('asynclogger') logger.info('Test asynclog')
|
考虑到重载的类实际只是用logging
的方法来filter、format日志,真正处理的其实在回调中,所以类名也就不敢叫AsyncLogHandler
, 就取名AsyncLogDispatcher
。
该模块已上传至pypi.org, pip install asynclog
即可,代码托管在我的GitHub, 欢迎交流。