6. logging模块¶
对于一个模块中,主脚本初始化logging之后,其他脚本可以通过log = logging.getLogger(__name__)来进行调用,此处有一个坑,就是需要在主脚本中设置log = logging.getLogger()而不能带有参数(默认是None)
- logging对象其实是一个树形结构,每个创建的logging对象都是root logging对象的孩子结点。当使用logging模块的getLogger(name=None)函数构造logging对象的时候,如果name为None,这样会产生一个root logging对象。如果name中含有.,比如name = ‘a.b.c’,通过这种方式会产生3个logging对象,分别为c、b、a,c->b->a->root,root树的根结点,a为root的孩子结点,b为a的孩子结点,c为a的孩子结点,依次类推。
- root结点是全局的,虽然这过程中涉及到多个模块,但是它们会共享一个root结点。
- 每个logging对象打LOG的时候,也会把LOG信息传递到传递到上层logging对象中,对于c->b->a->root这种情况,这个LOG其实会打4次,以c、b、a、root循序依次打一个LOG。
import logging.handlers
from pathlib import Path
def init_logging(log_file=str(Path(__file__).stem) + '.log', log_dir='log', debug=False):
log = logging.getLogger()
formatter = logging.Formatter('%(asctime)s [%(name)s] %(levelname)s: %(message)s')
fh = logging.handlers.WatchedFileHandler(os.path.join(log_dir, log_file))
fh.setFormatter(formatter)
log.addHandler(fh)
ch = logging.StreamHandler()
ch.setFormatter(formatter)
log.addHandler(ch)
level = logging.DEBUG if debug else logging.INFO
log.setLevel(level)
return log