日志组件slf4j简单使用

/ 技术 / 无站内评论 / 310浏览

公司都在用slf4j,平时都在用,配置什么的也忘光了,闲着就查了下资料回顾。

SLF4J对比Log4J,logback和java.util.Logging的优势

正如我之前说的,在你的代码中使用SLF4J写日志语句的主要出发点是使得你的程序独立于任何特定的日志类库,依赖于特定类库可能需要使用不同于你已有的配置,并且导致更多维护的麻烦。除此之外,还有一个SLF4J API的特性是使得我坚持使用SLF4J而抛弃我长期间钟爱的Log4j的理由,是被称为占位符(place holder),在代码中表示为“{}”的特性。占位符是一个非常类似于在String的format()方法中的%s,因为它会在运行时被某个提供的实际字符串所替换。这不仅降低了你代码中字符串连接次数,而且还节省了新建的String对象。通过使用SLF4J,你可以在运行时延迟字符串的建立,这意味着只有需要的String对象才被建立。而如果你已经使用log4j,那么你已经对于在if条件中使用debug语句这种变通方案十分熟悉了,但SLF4J的占位符就比这个好用得多。

这是你在Log4j中使用的方案,但这并不有趣,而且降低了代码可读性,因为它增加了不必要的繁琐重复代码(boiler-plate code):

if (logger.isDebugEnabled()) {
    logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}

另一方面,如果你使用SLF4J的话,你可以得到更简洁格式的结果,就像以下展示的一样:

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);

在SLF4J,我们不需要字符串连接而且不会导致暂时不需要的字符串消耗。取而代之,我们在一个以占位符和参数传递实际值构成的模板格式下写日志信息。你可能会在想万一我有很多个参数怎么办?嗯,那么你可以选择使用变量参数版本的日志方法或者以Object数组传递。这是一个相当方便和高效方法的打日志方法。记住,在生产最终日志信息字符串之前,这个方法会检查一个特定的日志级别是不是打开了,这不仅降低了内存消耗而且预先降低了CPU去处理字符串连接命令的时间。这里是使用SLF4J日志方法的代码,来自于slf4j-log4j12-1.6.1.jar中的Log4j的适配器类Log4jLoggerAdapter。

public void debug(String format, Object arg1, Object arg2) {
    if (logger.isDebugEnabled()) {
        FormattingTuple ft = MessageFormatter.format(format, arg1, arg2);
        logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
    }
}

同时,我们应该知道打日志是对应用程序性能有着很大影响,在生产环节上我们建议只进行必要的日志记录。

使用配置

maven依赖

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.21</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.21</version>
</dependency>

代码使用

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger logger = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        int status = 0;
        if (status == 0) {
            logger.info("status:{}", status);
        } else {
            logger.info("status:{}", status);
        }
        logger.info("end!");
    }
}

properties文件

log4j.properties

log4j.rootLogger=info, ServerDailyRollingFile, stdout
log4j.appender.ServerDailyRollingFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.ServerDailyRollingFile.DatePattern='.'yyyy-MM-dd
log4j.appender.ServerDailyRollingFile.File=logs/notify-subscription.log
log4j.appender.ServerDailyRollingFile.layout=org.apache.log4j.PatternLayout
log4j.appender.ServerDailyRollingFile.layout.ConversionPattern=%d - %m%n
log4j.appender.ServerDailyRollingFile.Append=true
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH\:mm\:ss} %p [%c] %m%n

输出结果为

2016-05-12 16:08:21 INFO [club.chuxing.learn.Main] status:0 
2016-05-12 16:08:21 INFO [club.chuxing.learn.Main] end!

一个示例配置文件

log4j.debug=true   
log4j.rootLogger=DEBUG,D,E

log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = logs/logs.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = DEBUG
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH🇲🇲ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH🇲🇲ss}  [ %t:%r ] - [ %p ]  %m%n

整理来源:http://blog.csdn.net/foreverling/article/details/51385128

召唤蕾姆
琼ICP备18000156号

鄂公网安备 42011502000211号