框架之日志管理

1 Butterfly 日志

1.1 Butterfly 日志概览

  • 程序标准输出

    • __stdout

  • 框架日志

    • logs/acc.log: access 日志

    • logs/err.log: error 日志

    • logs/init.log: 启动信息日志

  • 自定义日志

    • logs/common.log

    • logs/common.log.wf

    • logs/common_bf.log

    • logs/common_bf.log.wf

1.2 访问日志

logs/acc.log

1.2.1 不同请求时的访问日志

curl "http://127.0.0.1:8585/demo_api/ping" -------------------------- 正常无参数请求

curl "http://127.0.0.1:8585/demo_api/hello?str_info=meetbill" ------- 正常有参数请求

curl "http://127.0.0.1:8585/demo_api/hello?str_infox=meetbill" ------ 接口存在,但参数错误

curl -v "http://127.0.0.1:8585/demo_api/hellox?str_info=meetbill" -- 接口不存在

1.2.2 字段解析

curl "http://127.0.0.1:8585/demo_api/hello?str_info=meetbill" ------- 正常有参数请求

以正常有参数请求日志为例

  • DATE: 2021-02-08

  • TIME: 21:35:30

  • PID : 91640

  • CODE_INFO: /meetbill/butterfly/xlib/httpgateway.py:259

  • IP: 127.0.0.1

  • REQID: 1FA15BDE4B6CD7A0 (请求 ID)

  • METHOD: GET

  • PATH: /demo_api/hello

  • COST: cost:0.000162 (整体耗时,单位是秒)

  • STAT: stat:OK (执行结果状态, 若自定义 HTTP 方式时,则此处会是 HTTP 状态码)

  • USER: user:- (用户名)

  • TALK: talk:ceshi1=0.098;ceshi2=0.002 (代码片段耗时,比如一个 SQL 语句,请求 Redis 的耗时等)

  • PARAMS: params:str_info=hello (请求参数)

  • ERROR_MSG: error_msg:(错误信息)

  • RES: res:ceshi2=5.4;ceshi1=5.3 (需要记录的结果数据信息)

1.2.3 时间说明

厂内 GDP 的时间

  • talk[7.561] 本次交互耗时, 单位ms

  • connect[3.673] 链接耗时, 单位ms

  • write[0.241] 写耗时, 单位ms

  • read[0.100] 读耗时, 单位ms

  • pack[0] 打包的耗时, 单位ms

  • unpack[0.179] 解包的耗时,单位ms

1.3 自定义日志 logging

logging 中的几个概念:

上述三者的关系是:一个 Logger 使用多个 Handler,一个 Handler 使用一个 Formatter。

配置

1.3.1 logging 模块常用 format 格式说明

common 日志 format

1.3.2 logging 记录日志时默认添加 reqid 信息

除了传递给日志记录函数的参数外,有时候我们还想在日志输出中包含一些额外的上下文信息。

比如,在一个网络应用中,可能希望在日志中记录客户端的特定信息,如:请求 id

这里我们来介绍以下几种实现方式,详细查看传送门:

  • 通过向日志记录函数传递一个 extra 参数引入上下文信息

  • 使用 LoggerAdapters 引入上下文信息

  • 使用 Filters 引入上下文信息

实现

本框架使用 Filters 实现对要打印的日志默认添加 reqid 信息

主线程中设置:logging 的 filters 模块添加 reqid 信息,reqid 从 butterfly_local 中获取

线程中更新 butterfly_local 的属性

todo

以上方式在使用 logging 记录日志时不需要额外传参,但每次写日志都会查询全局作用域,所以会消耗一些时间, 后续可以再优化下

变量作用域

作用域例子

2 Butterfly 日志相关实现

2.1 获取当前运行函数文件名和代码行号

对象的属性

栈帧 (frame)

代码块 (code)

代码

2.2 使用 inspect.stack() 获取调用栈

2.2.1 demo

输出

inspect.stack() 信息

2.2.2 封装为库

即在需要打印日志的时候,可以通过调用 get_stack() 获取调用栈信息

3 报表

报表统计需要分析日志的字段并进行统计

3.1 使用 re 进行日志中的字段预处理

3.1.1 re 匹配日志

re 分组

re 基础知识

3.1.2 twemproxy 解析日志 demo

3.1.2 GDP 解析日志 demo

GDP 日志是以 key1[value1] key2[value2] 方式输出,可以通过如下方式获取到每个 field 的值

3.2 将日志转换为 dict

eg.

3.3 输出例子

reportlog

访问方式

4 tips

4.1 如何匹配 acc.log 对应的列数据

acc.log 的各列间使用 TAB 间隔

假设要获取 400 状态码的日志,需要加 —P 来匹配 TAB

4.2 如果查看大日志文件

比如一行日志就有 200MB

5 在线调整日志级别

  • 在线调整日志级别

  • 获取缓存命中率等信息

5.1 logging 日志级别调整

参考传送门

Last updated