单个Python应用如何在Google Cloud Logging中拆分不同子包的日志
解决方案
你的问题核心来自两个错误用法:
- 所有模块都调用
pylogging.getLogger()获取根日志器,没有按模块做日志器区分 - 仅给根日志器绑定了一个日志名为
package的CloudLoggingHandler,所有日志自然都会落到同一个日志名下
按以下两步修改即可实现子包日志拆分:
1. 修改所有子包的日志配置
所有子包内不要调用pylogging.basicConfig(该配置仅第一次调用生效,子包内的调用属于冗余配置还会干扰入口统一配置),同时获取带当前模块名的专属日志器,示例如下:
import logging as pylogging # 传入__name__自动生成带层级的日志器名,比如package.subpackage1.script1 LOGGER = pylogging.getLogger(__name__) class Class1: def __init__(self): LOGGER.info("Work Class1")
2. 修改入口文件的日志配置
入口文件统一配置日志,给不同子包的日志器分别绑定对应日志名的CloudLoggingHandler即可:
import logging as pylogging from google.cloud import logging from google.cloud.logging.handlers import CloudLoggingHandler from package.subpackage1.script1 import Class1 from package.subpackage2.script2 import Class2 from package.subpackage3.script3 import Class3 pylogging.basicConfig(level=20) # 根日志器保留全局日志名package,用于输出全局启动/结束日志 LOGGER = pylogging.getLogger() def main(): log_client = logging.Client() # 给根日志器加全局handler global_handler = CloudLoggingHandler(log_client, name="package") LOGGER.addHandler(global_handler) # 给每个子包单独加对应日志名的handler # 子包1的日志器 sub1_logger = pylogging.getLogger("package.subpackage1") sub1_handler = CloudLoggingHandler(log_client, name="package-subpackage1") sub1_logger.addHandler(sub1_handler) # 子包2的日志器 sub2_logger = pylogging.getLogger("package.subpackage2") sub2_handler = CloudLoggingHandler(log_client, name="package-subpackage2") sub2_logger.addHandler(sub2_handler) # 子包3的日志器 sub3_logger = pylogging.getLogger("package.subpackage3") sub3_handler = CloudLoggingHandler(log_client, name="package-subpackage3") sub3_logger.addHandler(sub3_handler) LOGGER.info("Starting work") Class1() Class2() Class3() LOGGER.info("Finished work") if __name__ == '__main__': main()
可选优化
- 如果不需要子包的日志同时出现在全局
package日志中,可以给子包日志器添加配置sub1_logger.propagate = False,关闭日志向上传递到父日志器,避免重复存储 - 如果子包数量较多,可以用循环批量创建handler,减少重复代码:
sub_packages = ["subpackage1", "subpackage2", "subpackage3"] for sub_name in sub_packages: logger = pylogging.getLogger(f"package.{sub_name}") handler = CloudLoggingHandler(log_client, name=f"package-{sub_name}") logger.addHandler(handler) # 可选关闭向上传递 # logger.propagate = False
修改完成后,全局运行日志会保留在package日志名下,各子包的日志会分别落到package-subpackage1、package-subpackage2等独立日志名下,既可以从全局日志查看单次运行的整体状态,也可以单独查看对应子包的日志。
内容的提问来源于stack exchange,提问作者Steven
相关产品推荐
相关产品推荐

