日志规范实践

最近在考虑后端日志规范拟定,参考了一些别的同志的经验,加上自己的一些思考,初步整理如下。

一、日志规范

1. 日志严格分级

  • DEBUG:该级别日志的主要作用是对系统每一步的运行状态进行精确的记录。可以将各类详细信息记录到DEBUG里,起到调试的作用,包括参数信息、调试细节信息、返回值信息等。

  • INFO:该种日志记录系统的正常运行状态,通过查看INFO级别的日志,可以很快地对系统中出现的 WARN,ERROR,FATAL错误进行定位。可以将初始化系统配置、业务状态变化信息,或者用户业务流程中的核心处理记录到INFO日志中,方便日常运维工作以及错误回溯时上下文场景复现。

  • WARN:该日志表示系统可能出现问题,也可能没有。

  • ERROR:该级别的错误也需要马上被处理,但是紧急程度要低于FATAL级别。ERROR应该尽量详细记录。

  • FATAL:需要立即被处理的系统级错误。系统需要将错误相关痕迹以及错误细节记录FATAL日志中,方便后续人工回溯解决。

必须严格按照日志的级别给出日志。

2. 日志记录时机

a) 程序设计语言异常位置:C++提示异常的位置。结合实际业务使用WARN及以上级别日志。

b) 业务流程与预期不符:如外部参数不正确等问题,取决于开发人员的经验。结合实际业务,使用WARN和ERROR级别日志。

c) 系统核心角色,组件关键动作:如用户从登陆到交易完成的整个流程,各个服务节点间交互的位置,核心组件运行过程等。建议记录INFO级别日志。

d) 系统及各模块初始化:各个服务组件的启动参数,状态信息。建议INFO级别日志记录。

3. 日志记录规范

在出现问题之后,需要立即根据日志定位问题。对于INFO及以上级别的日志,要求按照一定顺序,输出以下必要的信息。(最好各个级别日志都遵循以下规范,否则有些日志可能仍无法快速定位。)

- 当前服务器IP
- 当前服务或应用名
- (实例ID):若是不同实例不同名,可忽略,参考应用名。
- 当前类名(如有)
- 当前函数名
- 当前行号
- 内容信息:包含参数信息,调试信息等等。可以有多项。

例子:

PJ_LOG_INFO("Host:{},App:{},Class:{},Function:{},Line:{},Content:{}",localhost,app_example,class_example,func_example,1234,content);

TODO:

  • 如果定位问题花费了很长时间,说明系统日志还存在问题,需要进一步完善和优化。
  • 日志集中,如何集中?哪些日志集中在一起?同一个在线系统的日志?所有在线系统的所有日志?若存在多个在线的系统?如果日志集中后,需要考虑日志融合和区分。

二、日志追踪定位

TODO:可以尝试使用zipkin或者基于Google dapper搭建。

参考

  • Trace:跟踪,表示一条链路,以一个唯一的TraceID标识。一次完整调用需要传递并记录唯一的traceID,需要参考一下zipkin代码。
  • Span:跨度,dapper中的基本工作单元,以一个至少Trace内的SpanID标识。每个span中包含traceid,spanid,parentid,spanname,下面提到的annotationsh和binaryAnnotations等。
  • Annotation:基本标注列表,一个标注可以理解成span生命周期中重要时刻的数据快照。
    "annotations": [
        {
            "timestamp":1476197067420000,
            "value": "cs",
            "endpoint": {
                "serviceName":"gateway",
                "ipv4": "xxx.xxx.xxx.110"
            }
        },
        {
            "timestamp":1476197072114000,
            "value": "cr",
            "endpoint": {
                "serviceName":"gateway",
                "ipv4": "xxx.xxx.xxx.110"
            }
        }
    ],
  • BinaryAnnotation:业务标注列表,如果某些跟踪埋点需要带上部分业务数据(比如url地址、返回码和异常信息等),可以将需要的数据以键值对的形式放入到这个字段中。
    "binaryAnnotations": [
        {
            "key":"http.url",
            "value": "http://localhost:8080/service1",
            "endpoint": {
                "serviceName":"gateway",
                "ipv4": "xxx.xxx.xxx.110"
            }
        }
    ]

还有很多没有完成的工作和不太成熟的地方,欢迎交流指正。

原文地址:https://www.cnblogs.com/dengchj/p/7843011.html