Slf4j 搭配云日志系统

基本概念

性能

应该满足这几个关键点:

(1)易使用,一行代码搞不定都属于是有问题。

(2)易集成,Ctrl C/V两分钟搞定的那种。

(3)高性能,对业务本身不能造成影响,或者必要情况下影响最低,如果一个业务耗费了10毫秒,有9毫秒是花在日志上,那就别扯了。

(4)易维护,容易管理,不容易丢,单主机就存主机,集群就找个统一的地方存。

(5)易查,在遇到问题的能快速定位到地方。

分类

(1)TREC - 罗里吧嗦的日志(绝大部分可直接忽略)

(2)DEBUG - 调试日志

(3)INFO - 日常日志

(4)WARN - 警告日志

(5)ERROR - 错误日志

规范

似乎都没有一个比较统一的规范,做好分级即可,然后日志采集的时候尽可能的详细、流程清晰,至于表现形式,无特殊要求。

采集方式

Slf4j等主流的框架已经实现按需按量打印到控制台并按照指定文件格式写入指定文件了,所以这探讨的不是这种。

因为采用的是腾讯云的日志系统(用云的或者是用自建的,都是同样的逻辑),那边也提供有相关的SDK,所以只需要在合适的地方将日志上传上去就好。

(1)在Slf4j之前上传,说白了就是自己再封装一层,写个Log,ALog啥的。

(2)在Slf4j上传,主要是继承他原本的过滤器,然后在过滤器中上传。

第一种方式感觉也没啥好说的了,这里采用的是第二种方式。

开搞

导包

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>

这玩意是一个工具包,里面集成了Slf4j和其他实用的一些东西,集成了这玩意之后,打印只需要log.info()即可,十分方便。

配置

在项目的resources目录下新建一个logconfig目录,里面放了四个文件,logconfig_dev.xml、logconfig_test.xml、logconfig_prod.xml、logconfig_pre.xml,分别对应四种不同的环境。

然后在application.xml合适的位置加上配置

logging:
  level:
    com.alibaba.nacos.client.config.impl: WARN
    root: INFO
    org.hibernate: INFO
    org.hibernate.type.descriptor.sql.BasicExtractor: INFO
    com.ys.adage.mapper: INFO
    org.springframework: INFO
  config: classpath:logconfig/logconfig_dev.xml

level-指定一些库的日志级别

config-配置文件的路径

贴上某个logconfig_xxx.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--输出日志格式-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                %d - %msg%n
            </pattern>
        </layout>
    </appender>
    <!--只保存info日志-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>/root/logs/email/info/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存warn日志-->
    <appender name="fileWarnLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>/root/logs/email/warn/warn.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存error日志-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>/root/logs/email/error/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileWarnLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>

</configuration>

这里主要定义了日志文件的文件规则,哪些日志类型需要打印和写入文件中,哪些不需要。

分为三个级别(error/info/warn),这三个级别这是写入文件的级别,具体你可以定义这三个级别分别要打印什么级别的日志,如开发环境的话,info就可以打印info级别跟debug级别的日志。

过滤

核心就在这个logconfig配置文件这里,这里需要过滤掉一些跟等级无关的日志,所以配置了两个日志过滤器LevelFilter、ThresholdFilter,两者的区别在于LevelFilter只打印指定级别的日志,ThresholdFilter打印高于当前设置级别的日志。

所以,我们只需要重写一下这两个过滤类(一个也够了),把日志打印出来之前传到腾讯的SDK即可。

重写好的类其实也很简单

public class LogFilter extends LevelFilter {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        FilterReply filterReply = super.decide(event);
        if (FilterReply.DENY != filterReply) {
            //确定是需要打印的日志级别
            TencentLog.putLog(event.getLevel().levelStr, event.getMessage());//传到SDK
        }
        return filterReply;
    }
}

然后改一下ipconfig_xxx.xml配置文件里面的filter标签,把过滤器的路径指定到我们重写的LogFilter类即可。

最后,传到SDK的代码那里,最好是开个线程池处理。

上一篇:学习笔记——二分答案


下一篇:Educational Codeforces Round 115 (Rated for Div. 2)