如何将Django shell操作日志上报至Google Cloud Logging
Django Shell 操作日志上报 Google Cloud Logging 实现方案
你当前用logstart写本地文件的方案已经满足本地留存,要对接GCP日志有两种可落地的方案,按需选择即可。
方案1:通过IPython事件钩子直接上报(推荐)
logstart本身只支持写本地文件,不需要硬凑它的能力,直接用IPython官方提供的事件钩子,可以在内核层面捕获所有输入、输出内容,同时完成本地写入和GCP上报,不会漏记,还支持上报结构化日志方便审计检索。
直接替换你原来的ipython-config.py配置即可:
# ipython-config.py import os from datetime import datetime from google.cloud import logging as gcp_logging # 初始化GCP日志客户端,提前确保运行环境的服务账号有logging写入权限 gcp_client = gcp_logging.Client() gcp_logger = gcp_client.logger("django-shell-audit") # 保留本地日志文件配置 session_ts = datetime.now().strftime("%Y-%m-%d-%H-%M") local_log = open(f"/var/log/django/shell-{session_ts}.log", "a", encoding="utf-8") c = get_config() def capture_input(info): """捕获用户输入的执行命令""" cmd = info.raw_cell.strip() if not cmd: return # 写本地日志 local_log.write(f"[{datetime.now().isoformat()}] [INPUT] {cmd}\n") local_log.flush() # 上报GCP gcp_logger.log_struct( { "session_id": session_ts, "operator": os.getenv("USER", "unknown"), "content": cmd, "type": "command" }, severity="INFO" ) def capture_output(info): """捕获命令执行返回结果""" res = info.result if res is None: return res_str = str(res) # 写本地日志 local_log.write(f"[{datetime.now().isoformat()}] [OUTPUT] {res_str}\n") local_log.flush() # 上报GCP gcp_logger.log_struct( { "session_id": session_ts, "operator": os.getenv("USER", "unknown"), "content": res_str, "type": "result" }, severity="INFO" ) def close_log_file(ip): """Shell退出时关闭本地文件句柄""" local_log.close() # 注册钩子到IPython事件流 c.InteractiveShellApp.exec_lines = [ "ip = get_ipython()", "ip.events.register('pre_run_cell', capture_input)", "ip.events.register('post_run_cell', capture_output)", "ip.events.register('shutdown', close_log_file)", ]
这个方案的优势:
- 兼容性好,不会和IPython、shell_plus的原有输出逻辑冲突
- 上报的是结构化日志,后续在GCP里按操作人、会话ID、命令关键词检索都很方便
- 可以很方便的在捕获逻辑里加敏感信息脱敏规则,避免密钥、密码这类内容被记录
方案2:通过日志采集agent同步本地日志(改动最小)
如果你不想改现有IPython配置,直接在运行Django服务的机器上安装Google Cloud Ops Agent,配置采集规则指向你现在存本地日志的/var/log/django/shell-*.log路径,agent会自动把新增的日志内容同步到Cloud Logging。
这个方案你之前写的logstart配置完全不用动,只需要改运维侧的采集配置,缺点是上报的是纯文本非结构化日志,后续检索需要自己在GCP侧配置解析规则,灵活度不如方案1。
注意事项
- 不管用哪种方案,都要确保运行Django shell的账号/服务账号有Cloud Logging的写入权限,否则上报会失败
- 如果有合规要求,建议在日志捕获逻辑里加操作人、来源IP这类额外字段,方便审计溯源
- 不要用stdout重定向的方式捕获日志,会和IPython的富输出、自动补全逻辑产生冲突,用官方事件钩子是最稳定的选择
内容的提问来源于stack exchange,提问作者Константин Манойло
相关产品推荐
相关产品推荐

