1. 项目结构

实现 (a) A B C D 类都有对应的独立日志文件 (b) 一个全局的info级别日志文件并保留历史日志 (c) 一个全局的error级别的日志文件并保留历史日志
1.1 配置logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- 使用caller, 可以像log4j一样, 在日志中输出带有跳转的链接 -->
<pattern>
%date [%thread] %-5level %replace(%caller{1}){'(\bCaller(.+?)at\b)|\r|\n|\s*|\t', ''} - %msg%n
</pattern>
</encoder>
</appender>
<!-- 用于记录所有的error级别的日志 -->
<appender name="all_error"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- 存放error级别日志的文件. -->
<file>log/all_error/error.log</file>
<!--
按照序列生成滚动日志文件
单个日志文件的生命周期 eg: error.log -r(ename)-> error-his-1.log -r-> ... -r-> error-his-5.log -delete-> null
-->
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>log/all_error/error-his-%i.log</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>5</maxIndex>
</rollingPolicy>
<!-- 触发条件 -->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>1MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>
%date [%thread] %-5level [%logger:%method:%line] - %msg%n
</pattern>
</encoder>
</appender>
<!-- 用于记录所有的info及以上级别的日志 -->
<appender name="all_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<file>log/all_info/info.log</file>
<!-- 按照时间规则生成日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>log/all_info/info_his_%d{yyyyMMdd_HH/mm}.log
</fileNamePattern>
<!-- 保留最多5个历史日志 -->
<maxHistory>5</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
%date [%thread] %-5level [%logger:%method:%line] - %msg%n
</pattern>
</encoder>
</appender>
<appender name="a" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/a/a_debug.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>log/a/a_debug.%i.log</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>5</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>5MB</MaxFileSize>
</triggeringPolicy>
<encoder>
<pattern>
%date [%thread] %-5level [%logger:%method:%line] - %msg%n
</pattern>
</encoder>
</appender>
<appender name="b" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/b/b_info.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>log/b/b_info.%i.log</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>5</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>5MB</MaxFileSize>
</triggeringPolicy>
<encoder>
<pattern>
%date [%thread] %-5level [%logger:%method:%line] - %msg%n
</pattern>
</encoder>
</appender>
<appender name="c" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/c/c_warn.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>log/c/c_warn.%i.log</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>5</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>5MB</MaxFileSize>
</triggeringPolicy>
<encoder>
<pattern>
%date [%thread] %-5level [%logger:%method:%line] - %msg%n
</pattern>
</encoder>
</appender>
<appender name="d" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>log/d/d_error.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<FileNamePattern>log/d/d_error.%i.log</FileNamePattern>
<MinIndex>1</MinIndex>
<MaxIndex>5</MaxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>5MB</MaxFileSize>
</triggeringPolicy>
<encoder>
<pattern>
%date [%thread] %-5level [%logger:%method:%line] - %msg%n
</pattern>
</encoder>
</appender>
<root level="ALL">
<appender-ref ref="all_info" level="ALL"></appender-ref>
<appender-ref ref="all_error"></appender-ref>
<appender-ref ref="STDOUT"></appender-ref>
</root>
<!-- 记录logger name为com.homeway.logger.a.* 输出的 debug级别及以上的日志, 并保存到独立的日志文件中 -->
<logger name="com.homeway.logger.a" level="DEBUG" additivity="false">
<appender-ref ref="a"></appender-ref>
</logger>
<logger name="com.homeway.logger.b" level="INFO">
<appender-ref ref="b"></appender-ref>
</logger>
<logger name="com.homeway.logger.c" level="WARN">
<appender-ref ref="c"></appender-ref>
</logger>
<logger name="com.homeway.logger.d" level="ERROR">
<appender-ref ref="d"></appender-ref>
</logger>
</configuration>
常用模板
<!-- simple caller -->
%date{HH:mm:ss.SSS} %-5level %replace(%caller{1}){'(Caller(.+?)(?=\())|\r|\n|\s*|\t', ''} - %msg%n
<!-- fully caller -->
%date %-5level %replace(%caller{1}){'(\bCaller(.+?)at\b)|\r|\n|\s*|\t', ''} - %msg%n
1.2 测试代码
1.2.1 com.homeway.logger.a.A.java (classes B,C,D类似)
package com.homeway.logger.a;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class A {
static final Logger log = LoggerFactory.getLogger(A.class);
public A(){
log.debug(" A - debug ");
log.info(" A - info ");
log.warn(" A - {} ", "warn");
log.error(" {} - {} ", "A" , "error");
}
}
1.2.2 com.homeway.logger.LoggerTest.java
package com.homeway.logger;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.homeway.logger.a.A;
import com.homeway.logger.b.B;
import com.homeway.logger.c.C;
import com.homeway.logger.d.D;
public class LoggerTest {
static final Logger logger = LoggerFactory.getLogger(LoggerTest.class);
public static void log(){
logger.debug("hello {}", "world");
A a = new A();
B b = new B();
C c = new C();
D d = new D();
logger.warn("logged classes: {}, {}, {}, {}",
a.getClass(), b.getClass(), c.getClass(), d.getClass());
}
public static void main(String[] args) throws Exception {
logger.info("start logger test.");
// 定时任务
ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);
exec.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
log();
}
}, 0, 1, TimeUnit.MINUTES);
}
}
1.3 运行后生成的日志文件目录结构 
项目代码附件 : Logger.7z
本文详细介绍了如何配置日志系统,包括实现日志文件的结构、全局信息和错误级别的日志文件,并提供了测试代码及运行后生成的日志文件目录结构。
3496

被折叠的 条评论
为什么被折叠?



