当前位置: 首页 > 后端技术 > Python

收集python程序最优雅的日志解决方案——日志存储

时间:2023-03-26 12:18:27 Python

不管运行程序的平台是docker还是k8s,收集日志的方式有两种:方式一:收集程序的标准输出方式二:程序将日志写入文件,然后收集日志文件。首先分析一下方案1和方案2,不好的方案1的缺点是:“多行日志采集”无论是使用“行首正则表达式”还是“jsonification”“正则表达式at”都不是一个优雅的方案行首”,不是所有的模块都有固定的日志格式,当然有办法强制一致性;"jsonization":unformattedjson人类无法读取,"jsonization"方便了程序,但是让程序员的眼光反感所以,通过方案二:没有缺点如何使用:程序,即打印日志到标准输出,然后写入日志文件将日志打印到标准输出:这个是给人看的,可以直接用dockerlogs,docker-composelogs,kubectllogs直接看,方便写输入日志文件:使用loguru的serialize='json'将单个日志写入日志文件。因此,这些日志输出方案可以满足程序员直接查看日志,方便程序收集。如何实现?直接上代码fromloguruimportloggerfrommarkimportBASE_DIRimportsettingsimportosimportjsonfromloguru._handlerimportHandlerfromloguru._recattrsimportRecordExceptionlog_path=BASE_DIR/'logs'ifnotos.path.exists(log_cordpath):os.makedirs(log_repath)(log:str,record:dict):exception:RecordException=record["exception"]如果异常不是None:exception={"type":Noneifexception.typeisNoneelseexception.type.__name__,"value":exception.value,"traceback":bool(exception.traceback),}serializable={"text":text,"record":{"extra":record["extra"],},}返回json。转储(可序列化,默认=str,ensure_ascii=False)+“\n”Handler._serialize_record=staticmethod(_serialize_record)logger.add(log_path/'run.log',serialize='json',rotation='100MB',retention=1)最重要的是下面这一段。我们添加一个日志处理器,将日志写到第一个参数指定的文件中,第二个参数写到哪里,写成什么格式。这里使用的是json。因为这样可以避免“打印堆栈错误会有多行”的问题。指定第三个和第四个参数,表示日志轮转规则。如果写入慢了100MB,就做个备份,然后从0MB重新开始。总共有1个logger.add(log_path/'run.log',serialize='json',rotation='100MB',retention=1)loguru默认使用serialize='json'输出太多字段,所以我们使用monkeypatch来替换_serialize_record函数,去掉不需要的字段,节省日志存储成本。参考文章:loguru如何轮转日志loguruserializereducefields如何使用loguru接管程序的所有日志输出