1. java.util.logging.Logger ,jdk1.4后自带日志,很少使用
2.commons-logging 是apache提供的一个通用的日志接口 。我们可以自由选择第三方日志组件作为实现,例如log4j,或jjava.util.logging, commons-logging会通过动态查找的机制,在程序运行时自动找出真正使用的日志库。其内部有一个Simple logger的简单实现,但是功能很弱。通常配合着log4j来使用。使用它的好处就是,代码依赖是 common-logging而非log4j, 避免了和具体的日志方案直接耦合,在有必要时,可以更改日志实现的第三方库。
3.slf4j (Simple Logging Facade for Java)java简单日志门面,有着和commons-logging一样的初衷,功能上更加强大,支持多个参数,并通过{} 占位符进行替换,避免老写logger.isXXXEnabled 这种无奈的判断,带来性能提升,OSGI 机制的更好兼容支持。
4.log4j (Log for Java),是Apache的一个开源项目,使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。并且只需要一个配置文件来灵活地进行配置,而不需要修改应用的代码。
5. logback 同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现。
logback 主要分为三个模块,分别是:
logback-core:提供基础功能,是其他两个模块的基础 logback-classic : log4j的升级,实现了self4j api logback-access:用于与sevlet容器进行集成、提供网络访问日志的功能
logback初始化时,默认会去classpath下依次加载如下配置文件(logback.groovy、logback-test.xml、logback.xml ),当找不到配置文件时logback将为rootLogger 添加一个 ConsoleAppender ,用于将日志输出到控制台
小结:
日志门面(日志抽象层) 日志实现 JCL:Jakarta Commons Logging JUL:java.util.logging JDK自带 SLF4j(Simple Logging Facade for Java) Log4j 、Logback
使用一:commons-logging+ log4j
pom文件引入依赖
<dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
配置文件:log4j.properties
log4j.rootLogger=debug,stdout,file_debug
log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS} [%t] [%24F:%-3L:%-5p]%x %m%n
log4j.appender.file_debug=org.apache.log4j.RollingFileAppender log4j.appender.file_debug.File=/home/niel/tempfs/test.log log4j.appender.file_debug.MaxFileSize=10000KB log4j.appender.file_debug.MaxBackupIndex=10 log4j.appender.file_debug.layout=org.apache.log4j.PatternLayout log4j.appender.file_debug.layout.ConversionPattern=%d{MM-dd HH:mm:ss.SSS} [%t] [%24F:%-3L:%-5p]%x %m%n
参数详情可参考:https://www.cnblogs.com/30go/p/7200739.html
调用方式:
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory;
public class Test { private static Log log = LogFactory.getLog(Test.class); public static void main(String[] args) { log.debug( "Hello World!" ); } }
使用二:slf4j+ logback
pom文件引入依赖
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
配置文件:logback.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- scan:当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 scanPeriod:设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 --> <configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 上下文变量设置,用来定义变量值,其中name的值是变量的名称,value的值时变量定义的值。 通过<property>定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> <property name="CONTEXT_NAME" value="logback-test" /> <property name="logs.dir" value="D:/hh" />
<!-- 上下文名称:<contextName>, 每个logger都关联到logger上下文, 默认上下文名称为“default”。但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。 一旦设置,不能修改。 --> <contextName>${CONTEXT_NAME}</contextName>
<!-- <appender>是<configuration>的子节点,是负责写日志的组件。 有两个必要属性name和class。 name指定appender名称, class指定appender的实现类。 --> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <!-- 对日志进行格式化。 --> <encoder> <pattern> %d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%class|%thread|%method|%line|%msg%n </pattern> </encoder> </appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <!-- 被写入的文件名,可以是相对目录,也可以是绝对目录,如果上级目录不存在会自动创建,没有默认值。 --> <file>${logs.dir}/logback-test.log</file>
<!-- 当发生滚动时的行为 --> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <!-- 必须包含“%i”例如,假设最小值和最大值分别为1和2,命名模式为 mylog%i.log,会产生归档文件mylog1.log和mylog2.log。还可以指定文件压缩选项,例如,mylog%i.log.gz 或者 没有log%i.log.zip --> <FileNamePattern>${logs.dir}/logback-test.%i.log</FileNamePattern> <!-- 窗口索引最小值 --> <minIndex>1</minIndex> <!-- 窗口索引最大值 --> <maxIndex>1</maxIndex> </rollingPolicy>
<!-- 激活滚动的条件。 --> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <!-- 活动文件的大小,默认值是10MB --> <maxFileSize>30MB</maxFileSize> </triggeringPolicy>
<!-- 对记录事件进行格式化。 --> <encoder> <charset>UTF-8</charset> <Pattern> %d{yyyy-MM-dd HH:mm:ss.SSS}|%level|%class|%thread|%method|%line|%msg%n </Pattern> </encoder> </appender>
<!-- 特殊的<logger>元素,是根logger。只有一个level属性,应为已经被命名为"root". level:设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能设置为INHERITED或者同义词NULL。默认是DEBUG。 <root>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个loger。 --> <root> <level value="debug" /> <appender-ref ref="stdout" /> <appender-ref ref="file" /> </root>
<!-- 用来设置某一个 包 或者具体的某一个 类 的日志打印级别、以及指定<appender>, name:用来指定受此logger约束的某一个包或者具体的某一个类。 level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。如果未设置此属性,那么当前loger将会继承上级的级别。 additivity:是否向上级logger传递打印信息。默认是true。(这个logger的上级就是上面的root) <logger>可以包含零个或多个<appender-ref>元素,标识这个appender将会添加到这个logger。--> <!-- <logger name="cn.nielang.test.Log4jTest" level="DEBUG" additivity="true"> --> <!-- <appender-ref ref="demo" /> --> <!-- </logger> -->
</configuration>
调用方式:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Test {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(Test.class);
logger.debug("test........");
}
}
注意:
如果需要使用slf4j+log4j,只需要修改pom.xml,并添加log4j.xml
<!-- 导入slf4j-log4j12,依赖slf4j-api和log4j,自动导入 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
当同事引用了logback包和log4j包时会有提示:绑定了多个日志实现
那么这个地方就要注意了:如果有任意两个实现slf4j 的包同时出现,可能会出现问题。原因是这两个jar 包里都有各自的org.slf4j.impl.StaticLoggerBinder ,编译时候绑定的是哪个是不确定的。这个地方要特别注意!!出现过几次因为这个导致日志错乱的问题。
参考地址:https://www.cnblogs.com/yinz/p/5695367.html
https://www.cnblogs.com/30go/p/7200739.html
https://www.jianshu.com/p/696444e1a352
https://www.cnblogs.com/jpfss/p/9046848.html
有不对的地方,请指正