GAE弹性环境Python2.7无法将logging.info写入Stackdriver日志
解决GAE弹性环境Python2.7 Stackdriver Info日志不输出的问题
我之前在Google App Engine弹性环境的Python2.7项目里也碰到过一模一样的坑——明明设置了日志级别为INFO,但只有ERROR和print的内容能进Stackdriver,INFO日志死活不出来。折腾了好一阵才找到靠谱的解决办法,给你整理了一个可直接运行的示例:
核心问题分析
GAE Python2.7的logging模块默认带了一些隐藏配置,而且Stackdriver的setup_logging方法有时候不会完全覆盖root logger的所有处理器级别。另外,如果在setup_logging之后才去获取logger,很可能导致配置不生效。
完整示例代码
1. 主应用文件(比如main.py)
import logging from google.cloud import logging as stackdriver_logging from flask import Flask, request app = Flask(__name__) # 关键:Stackdriver日志客户端初始化必须放在所有logging.getLogger()调用之前 client = stackdriver_logging.Client() # 强制设置日志级别为INFO,让客户端接管日志系统 client.setup_logging(log_level=logging.INFO) # 显式配置root logger,确保所有子logger继承正确级别 root_logger = logging.getLogger() root_logger.setLevel(logging.INFO) # 遍历root logger的所有处理器,确保它们的级别也设为INFO(避免处理器过滤掉INFO日志) for handler in root_logger.handlers: handler.setLevel(logging.INFO) # 获取当前模块的logger(也可以直接用root logger) logger = logging.getLogger(__name__) @app.route('/') def main_page(): # 现在这几条日志都应该能出现在Stackdriver里了 logger.info('in MainPage - info') logger.error('in MainPage - error') print('in MainPage - print') return "Hello World" if __name__ == '__main__': # 主函数里再验证一次INFO级日志 logger.info('in main - info') app.run(host='0.0.0.0', port=8080)
2. app.yaml配置(关键部分)
确保配置里没有限制日志级别,同时指定正确的运行环境:
runtime: python27 api_version: 1 threadsafe: true handlers: - url: /.* script: main.app env_variables: # 让Stackdriver客户端正确识别项目环境 GOOGLE_CLOUD_PROJECT: "你的项目ID"
额外注意事项
- 初始化顺序不能乱:Stackdriver客户端的
setup_logging必须在任何logging.getLogger()调用之前执行,否则已经创建的logger不会被客户端接管。 - 别忽略处理器级别:有时候root logger本身设为INFO,但它的处理器(比如默认的StreamHandler)会被默认设为ERROR级别,导致INFO日志被过滤,所以必须手动遍历处理器调整级别。
- 尽量统一用logging:虽然print能输出日志,但建议统一使用logging模块,这样能更好地利用Stackdriver的结构化日志、级别过滤等功能。
按照这个示例部署后,你应该能在Stackdriver日志里看到所有INFO、ERROR级别的日志了。
内容的提问来源于stack exchange,提问作者Jim Charters
相关产品推荐
相关产品推荐

