• 日志规范实践


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

    一、日志规范

    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"
                }
            }
        ]
    

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

  • 相关阅读:
    python脚本 – 删除指定天数前的文件
    java 获取屏幕的分辩率
    解决Multi input/output stream coders are not yet supported(org.apache.commons.compress)
    解决tomcat at org.apache.tomcat.util.buf.CharChunk.append(CharChunk.java:355)
    org.quartz.jobStore.misfireThreshold = 60000
    python list 自定义排序
    利用pycron在windows上实现cron定时任务
    [Selenium+Java] Scroll UP or Down a page in Selenium Webdriver
    Python获取硬件信息(硬盘序列号,CPU序列号)
    ChromeDriver自动更新、FirefoxDriver自动更新、InternetExplorerDriver自动更新(Java+Python)
  • 原文地址:https://www.cnblogs.com/dengchj/p/7843011.html
Copyright © 2020-2023  润新知