一般情况下,我们不需要关注log4j的使用,只需要写配置文件就可以实现定制。例如在spring boot的工程中,我们只需要在resource中通过logback.xml文件来配置就可以使用日志系统,但是很多时候,我们需要自我定制日志的配置。例如,我们的程序是一个二方包提供给别人使用的时候,我们该怎么定制我们的二方包的日志呢? 本文要解决的就是这个问题
先回忆下基本概念,先分清楚java现有的几个log系统
common-logging 是一个日志接口,背后可以接具体的实现,使得业务方只依赖于common-logging,而可以方便的更换背后的实现
slf4j : 同common-logging也是日志的一个接口的封装
log4j:日志的具体实现
logback: 日志的另一个实现
具体的详细的区别,网络上有很多资料,可以自行了解,不是本文的重点。
我们看一下在一个spring boot中,配置一个每天回滚的日志是怎样的, 其中maxHistory是保留多少天的日志,日志每天凌晨会产出一份新文件。
logs/select_task.log logs/select_task.log.%d{yyyy-MM-dd} 30 UTF-8 %d{yyyy-MM-dd HH:mm:ss} %-5p %c{0}.%M:%L # %m%n true
具体的不详细解释,下面是本文的重点,如果你是以二方包的形式提供服务,那么怎么才能打自己的log而不依赖于别人项目工程的配置呢? 这里就要解释这几个类了. FileAppender的类的职责就是把日志按照一定的格式,追加到日志文件中。
RollingFileAppender: 可以按照大小将文件进行切割,当日志文件达到一定大小以后则重新创建新文件
DailyRollingFileAppender: 逐日生成日志文件,具体的切换的时间也可以自定义
PatternLayout: 则是定义日志的输出格式
下面的表格解释了上面模式中用到的字符,以及所有定制模式时能用到的字符:
| 转换字符 | 含义 |
|---|---|
| c | 使用它为输出的日志事件分类,比如对于分类 "a.b.c",模式 %c{2} 会输出 "b.c" 。 |
| C | 使用它输出发起记录日志请求的类的全名。比如对于类 "org.apache.xyz.SomeClass",模式 %C{1} 会输出 "SomeClass"。 |
| d | 使用它输出记录日志的日期,比如 %d{HH:mm:ss,SSS} 或 %d{dd MMM yyyy HH:mm:ss,SSS}。 |
| F | 在记录日志时,使用它输出文件名。 |
| l | 用它输出生成日志的调用者的地域信息。 |
| L | 使用它输出发起日志请求的行号。 |
| m | 使用它输出和日志事件关联的,由应用提供的信息。 |
| M | 使用它输出发起日志请求的方法名。 |
| n | 输出平台相关的换行符。 |
| p | 输出日志事件的优先级。 |
| r | 使用它输出从构建布局到生成日志事件所花费的时间,以毫秒为单位。 |
| t | 输出生成日志事件的线程名。 |
| x | 输出和生成日志事件线程相关的 NDC (嵌套诊断上下文)。 |
| X | 该字符后跟 MDC 键,比如 X{clientIP} 会输出保存在 MDC 中键 clientIP 对应的值。 |
| % | 百分号, %% 会输出一个 %。 |
详细的可以参考: http://wiki.jikexueyuan.com/project/log4j/log4j-patternlayout.html
我们通过具体的代码来演示在你的二方包中如何打印自己的日志:
public class MyClassLog {
//保证全局唯一
static public Logger logger() {
return MyClassLog.logger;
}
static final Logger logger;
static {
FileAppender appender = new DailyRollingFileAppender();
appender.setAppend(true);//不设置会覆盖
appender.setEncoding("GBK");//设置编码
appender.setFile("~/log");//设置路径
appender.setLayout(new PatternLayout("%d %-5p - %m%n%n"));//设置格式,格式参考上面的表格
appender.activateOptions();
logger = Logger.getLogger("top.huster.myTest");
logger.setLevel(Level.INFO);
logger.setAdditivity(false);
logger.addAppender(appender); //设置append,默认是覆盖
}
}