关于LOGBACK日志分包打印,过滤不需要的日志

  前景提要 

  最近收到个任务,由于定时任务日志打印跟其他任务日志打印在同一个文件中,导致其他日志可读性很差,基本都是十秒一个的定时任务的日志,这样原先的日志就失去了意义,需要将定时任务中的日志与其他任务的日志分开打印,于是就使用到了logback的日志分包打印,以及过滤器功能.

下面上一个小demo,其中也参考了很多博客,供大家参考.

 

  • 关于LOGBACK日志分包打印,过滤不需要的日志
    总体项目结构

首先的话是三个类的创建,service以及两个dao.

@Service
public class ObligationService {
    static final Logger log = LoggerFactory.getLogger(ObligationService.class);

    @Resource
    ObligationDao dao;

    @Resource
    Obligation2Dao obligation2Dao;

    public  void obligate(){
        log.debug("task:obligate start...");
        dao.queryObligations();
        obligation2Dao.queryObligations();
        log.error("task:An error occurred during the progress");
        log.debug("task:obligate end...");

    }

}
@Repository
public class ObligationDao {

    static final Logger log = LoggerFactory.getLogger(ObligationDao.class);

    public void queryObligations() {
        log.debug("task:query obligations start...");
        log.error("task: An error occurred during the query");
        log.debug("task: query obligations end...");
    }
}
@Repository
public class Obligation2Dao {

    static final Logger log = LoggerFactory.getLogger(Obligation2Dao.class);

    public void queryObligations() {
        log.debug("query obligations start...22222222222222");
        log.error("An error occurred during the query22222222222222");
        log.debug("query obligations end...222222222222222");
    }
}

二 接着是logback-spring.xml 的配置

<?xml version="1.0" encoding="UTF-8"?>

<configuration debug="true" scan="false">
    <springProperty scop="context" name="spring.application.name" source="spring.application.name" defaultValue="pig"/>
    <property name="log.path" value="logs/${spring.application.name}"/>

    <!-- Log file debug output -->
    <appender name="debug" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/ObligationService.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/ObligationService-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="debug1" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/ObligationDao.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/ObligationDao-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="debug2" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/common.log</file>
        <filter class="com.example.bootstart.logfilter.SampleFilter"/>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/common-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} - %msg%n</pattern>
        </encoder>
    </appender>


    <springProfile name="dev">
        <root level="DEBUG">
            <appender-ref ref="debug2"/>
        </root>
        <logger name="com.example.bootstart.log.ObligationService" level="DEBUG">
            <appender-ref ref="debug"/>
        </logger>
        <logger name="com.example.bootstart.log2.ObligationDao" level="DEBUG">
            <appender-ref ref="debug1"/>
        </logger>
    </springProfile>


</configuration>

<logger name="com.example.bootstart.log.ObligationService"> 这个属性指明了哪个包或者哪个类使用特殊的日志配置.大家可能注意到了filter,filter我只在debug2这个日志配置中使用,目的就是为了过滤掉下面两个已经日志特殊化处理的类.

三 filter的配置

  

public class SampleFilter extends Filter<ILoggingEvent> {

    @Override
    public FilterReply decide(ILoggingEvent event) {

        if (getPackName(event.getLoggerName()).equals("com.example.bootstart.log")
                ||getPackName(event.getLoggerName()).equals("com.example.bootstart.log2"))
        {
            return FilterReply.DENY;
        } else{
            return FilterReply.ACCEPT;
        }
    }

    public String getPackName(String className){
        String packName = className.substring(0,className.lastIndexOf("."));
        return packName;
    }


}

这是一个简单的fiter的配置,大家初次看的话可能对这段if不太理解. 

if (getPackName(event.getLoggerName()).equals("com.example.bootstart.log")
                ||getPackName(event.getLoggerName()).equals("com.example.bootstart.log2"))
        {
            return FilterReply.DENY;
        }

  这段if语句主要是为了判断每行日志都是一个event,其中有很多属性,LoggerName就是打印这一行日志的这个类,我通过字符串截取的方法获得这个类的包,然后再使用基本的equals语句去与我所要过滤的包比较,若是true,则返回FilterReply.DENY,表示不打印这段日志,而FilterReply.ACCEPT则表示打印这段日志.

四 测试用例

    最后就是启动我自己的测试用例,就可以在log文件夹中输出对应的类的日志.

@RunWith(SpringRunner.class)
@SpringBootTest
public class dispatchByPackageTest {

    @Autowired
    private ObligationService obligationService;

    @Test
    public void dispatchByPackageTest() {

        obligationService.obligate();
    }



}

    日志的截图的话就只上一个.

  

关于LOGBACK日志分包打印,过滤不需要的日志
其中一个dao层的日志

五 总结

  参考了很多博客,谢谢大家.