乐趣区

关于python:最优雅的采集-python-程序的日志方案日志存储篇

不论运行程序的平台是 docker 还是 k8s,采集日志有两种计划:

  • 计划一:采集程序的规范输入
  • 计划二:程序把日志写文件中,而后采集日志文件

在先来剖析一下计划一和二的好坏

计划一的害处就是:『多行日志采集』

不论是用『行首正则表达式』还是『json 化』都不是优雅的解决方案

『行首正则表达式』,不是所有模块的日志都有固定格局,当然,想要强制统一也有方法;『json 化』:没有格式化的 json 是人类不可读的,『json 化』不便了程序,然而恶心了程序员的眼睛

所以,pass

计划二:没有毛病

我怎么用的:程序,即打印日志到规范输入,又写入日志文件

  • 打印日志到规范输入:这是给人看到,能够间接应用 docker logs、docker-compose logs、kubectl logs 间接看,不便
  • 写入日志文件:应用 loguru 的 serialize=’json’ 将单条日志写入日志文件

所以这些日志输入计划,及满足了程序员间接查看日志,也不便程序的采集。

那具体如何实现呢?间接上代码

from loguru import logger
from mark import BASE_DIR
import settings
import os
import json
from loguru._handler import Handler
from loguru._recattrs import RecordException

log_path = BASE_DIR/'logs'

if not os.path.exists(log_path):
    os.makedirs(log_path)

def _serialize_record(text: str, record: dict):
    exception: RecordException = record["exception"]

    if exception is not None:
        exception = {
            "type": None if exception.type is None else exception.type.__name__,
            "value": exception.value,
            "traceback": bool(exception.traceback),
        }

    serializable = {
        "text": text,
        "record": {"extra": record["extra"],
        },
    }

    return json.dumps(serializable, default=str, ensure_ascii=False) + "\n"


Handler._serialize_record = staticmethod(_serialize_record)

logger.add(
    log_path/'run.log',
    serialize='json',
    rotation='100 MB',
    retention=1
)

最重要的就是上面这段,咱们增加一个日志处理器,用于将日志写到文件中
第一个参数指定,写哪里
第二个参数指定,用什么格局写,这里用 json,因为这样能够防止『打印堆栈谬误会多行』的问题
第三、四个参数指定,示意日志轮换规定,写慢 100 MB,就备份一下,而后从 0MB 从新开始,总共有 1 份

logger.add(
    log_path/'run.log',
    serialize='json',
    rotation='100 MB',
    retention=1
)

loguru 应用 serialize=’json’ 默认输入的字段太多了,所以咱们应用猴子补丁,替换 _serialize_record 函数,去掉不须要的字段,节约日志存储老本

参考文章:
loguru 如何轮换日志
loguru serialize 缩小字段
如何应用 loguru 接管程序的所有日志输入

退出移动版