美文网首页架构与实践
服务器端日志规约和实践

服务器端日志规约和实践

作者: 蝗虫的小腿儿 | 来源:发表于2018-07-17 16:52 被阅读152次

    一、日志级别

    ALL、TRACE、DEBUG、INFO、WARN、ERROR、FATAL、OFF

    从左至右日志输出由多到少。

    生产环境使用INFO日志级别,调试时可以设置为DEBUG级别。

    针对Spring Boot的程序,使用配置中的logging.level.root控制默认日志级别。

    启动时可以使用logging.level.root参数做临时设置。例如:

    java -jar app.jar --logging.level.root=debug
    

    二、日志分类

    1. 监控日志

    监控系统内关键点的动作,DEBUG级别可做打点使用,ERROR级别记录程序异常。

    1. 业务日志

    系统内业务操作日志输出,例如:下单、支付、后台上下架商品等重要的操作。

    1. 统计日志

    根据统计需要,对用户操作进行记录,例如:登录、注册、浏览商品等。

    三、日志的触发点和级别

    1. 监控日志
    触发点 日志级别 例子
    关键方法入口 DEBUG 记录参数
    调用外部服务 DEBUG REST API调用返回数据
    耗时和资源占用高的方法 DEBUG 记录处理时间、记录资源消耗
    定时任务启动和结束 DEBUG 启动时间及状态、结束时间及状态
    容错及恢复 DEBUG 用户目录不存在,重新建立用户目录
    可处置的操作异常 WARN 用户登录失败
    无法处置的程序异常 ERROR logger.error(各类参数或者对象 toString + "_" + e.getMessage(), e);
    主程序启动和关闭 DEBUG 启动时间及状态、结束时间及状态
    重要配置或环境变量 DEBUG 配置,环境变量
    1. 业务日志
    触发点 日志级别 例子
    业务操作执行后 INFO 关键业务操作记录执行结果,执行人
    1. 统计日志
    触发点 日志级别 例子
    需要进行统计的操作 INFO 记录用户访问信息,IP、耗时、下载量;记录资源用量信息

    四、日志收集方式

    1. Fluentd

    将日志发送到远程日志中心,由Fluentd进行收集,Elasticsearch存储,Kibana展示。

    附logback配置文件片段。
    logger monitor/business/stats 分别对应 监控/业务/统计日志

    <appender name="FLUENT" class="ch.qos.logback.more.appenders.FluencyLogbackAppender">
        <tag>${fluentTag}</tag>
        <remoteHost>${fluentHost}</remoteHost>
        <port>${fluentPort}</port>
        <fileBackupDir>${logPath}</fileBackupDir>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern><![CDATA[%msg]]></pattern>
        </layout>
    </appender>
    <logger name="monitor" class="ch.qos.logback.classic.AsyncAppender" additivity="false">
        <appender-ref ref="FLUENT" />
        <appender-ref ref="STDOUT" />
    </logger>
    <logger name="business" class="ch.qos.logback.classic.AsyncAppender" additivity="false">
        <appender-ref ref="FLUENT" />
    </logger>
    <logger name="stats" class="ch.qos.logback.classic.AsyncAppender" additivity="false">
        <appender-ref ref="FLUENT" />
    </logger>
    

    2. 控制台

    监控日志还可以输出到控制台。

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    

    3.文件

    重要的日志可以输出到文件作为备份。

    可以设置保存文件个数和磁盘占用总容量限制。

    <appender name="FILE"
        class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${logPath}/business.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- hourly rollover -->
            <fileNamePattern>${logPath}/business.%d{yyyy-MM-dd-HH}.log</fileNamePattern>
            <!-- keep 30 days' worth of history capped at 3GB total size -->
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
        </encoder>
    </appender>
    

    五、记录日志

    参考阿里巴巴Java开发手册

    应用中不可直接使用日志系统(Log4j、Logback)中的 API,而应依赖使用日志框架 SLF4J 中的 API,使用门面模式的日志框架,有利于维护和各个类的日志处理方式统一。

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    private static final Logger monitorLogger = LoggerFactory.getLogger("monitor");
    private static final Logger businessLogger = LoggerFactory.getLogger("business");
    private static final Logger statsLogger = LoggerFactory.getLogger("stats");
    

    接下来按照 三、日志的触发点和级别 的说明,在程序中记录日志。

    注意点:

    1. 使用占位符而不是字符串拼接

    参考阿里巴巴Java开发手册

    说明:logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
        如果日志级别是 warn,上述日志不会打印,但是会执行字符串拼接操作,如果 symbol 是对象, 会执行 toString()方法,浪费了系统资源,执行了上述操作,最终日志却没有打印。 
    正例:(条件) 
    if (logger.isDebugEnabled()) {
        logger.debug("Processing trade with id: " + id + " and symbol: " + symbol);
    }     
    正例:(占位符)
    logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);
    
    1. 异常输出适当的日志

    捕获不可控的异常,应该输出现场信息和异常堆栈信息,不要将异常再抛至上层,避免上层再次输出。

    日志例:

    logger.error(各类参数或者对象 toString + "_" + e.getMessage(), e);
    

    异常堆栈信息是多行,在Kibana中会出现多条,不便于查看。建议在Fluent中添加合并插件,将异常堆栈信息合并为一行再输出到Elasticsearch。

    相关文章

      网友评论

        本文标题:服务器端日志规约和实践

        本文链接:https://www.haomeiwen.com/subject/ucrgpftx.html