Python 日志记录实战:结构化日志与敏感信息脱敏
【摘要】 用 Python 标准库 logging 输出结构化 JSON 日志,并对密码、Token 等敏感字段做脱敏,避免日志本身变成新的安全风险。
Python 日志记录实战:结构化日志与敏感信息脱敏
很多项目一开始只用 print 排查问题,等到线上出问题时才发现:日志没有级别、没有统一格式、还可能把密码和 Token 直接写进文件。本文用 Python 标准库 logging 做一个最小可用的方案:输出结构化 JSON 日志,同时对敏感字段脱敏。
1. 为什么不要直接打印字典
直接把请求参数、用户信息打印出来,很容易顺带打印出密码、Token、AK/SK。日志一旦落盘、上传或被其他人看到,就很难收回。所以第一条规则是:日志字段先过一层脱敏,再输出。
2. 一个可复用的脱敏函数
对字典和列表做递归处理,键名包含 password、token、ak、secret 等敏感词时替换为 ***,其他字段原样保留:
SENSITIVE = ("password", "token", "ak", "secret")
def redact(obj):
if isinstance(obj, dict):
return {
k: ("***" if any(s in k.lower() for s in SENSITIVE) else redact(v))
for k, v in obj.items()
}
if isinstance(obj, list):
return [redact(v) for v in obj]
return obj
注意,这里的匹配是按“包含”来做的,比精确匹配更稳妥,但也可能误伤,例如把 tokenizer 当成敏感字段。实际项目里可以改成白名单加黑名单结合:先明确哪些字段允许记录,再对剩余字段做脱敏。
3. 输出 JSON,而不是拼接字符串
拼接字符串的日志很难被搜索和分析。把级别、消息、业务字段统一成 JSON,之后用 jq、日志平台按字段过滤都会方便很多:
import json, logging
class JsonFormatter(logging.Formatter):
def format(self, record):
payload = {
"level": record.levelname,
"msg": record.getMessage(),
"name": record.name,
}
if record.args and isinstance(record.args, dict):
payload.update(redact(record.args))
return json.dumps(payload, ensure_ascii=False)
使用时把业务字段作为字典传进去,而不是拼进消息字符串里,这样字段结构始终稳定。
4. 本地验证
下面这段代码在本地直接运行过,输出证明密码和 Token 已被替换,级别和字段也都正常:
import io
stream = io.StringIO()
handler = logging.StreamHandler(stream)
handler.setFormatter(JsonFormatter())
log = logging.getLogger("demo")
log.handlers = [handler]
log.setLevel(logging.INFO)
log.propagate = False
log.info("user login", {"user": "demo", "password": "hunter2", "token": "abc123"})
print(stream.getvalue())
输出示例:
{"level": "INFO", "msg": "user login", "name": "demo", "user": "demo", "password": "***", "token": "***"}
5. 几个容易踩的坑
- 不要在日志里记录完整请求体:先明确字段清单,只记排查需要的部分。
- 异常日志要带上下文,不要只记一句话:至少保留操作、关键标识和错误类型,敏感字段同样要脱敏。
- 级别要分开用:INFO 记正常关键节点,WARNING 记可恢复的异常,ERROR 记需要人工介入的失败,不要全部用 INFO。
- 脱敏要在输出前做,不要事后去文件里替换:事后替换容易漏掉滚动文件、备份文件和已经上传的副本。
小结
结构化日志解决的是“能不能快速查到问题”,脱敏解决的是“日志本身会不会变成新的风险”。两者都不需要引入第三方库,Python 标准库就能先把基本盘做好,再根据项目规模决定是否接入统一日志平台。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)