###系列文章已完成,目录如下:
- jdk-logging、log4j、logback日志介绍及原理
- commons-logging与jdk-logging、log4j1、log4j2、logback的集成原理
- slf4j与jdk-logging、log4j1、log4j2、logback的集成原理
- slf4j、jcl、jul、log4j1、log4j2、logback大总结
#1 需要解决的疑惑
目前的日志框架有jdk自带的logging,log4j1、log4j2、logback
目前用于实现日志统一的框架apache的commons-logging、slf4j
为了理清它们的关系,与繁杂的各种集成jar包,如下:
- log4j、log4j-api、log4j-core
- log4j-1.2-api、log4j-jcl、log4j-slf4j-impl、log4j-jul
- logback-core、logback-classic、logback-access
- commons-logging
- slf4j-api、slf4j-log4j12、slf4j-simple、jcl-over-slf4j、slf4j-jdk14、log4j-over-slf4j、slf4j-jcl
分成3篇文章来阐述
- jdk自带的logging、log4j1、log4j2、logback的使用与原理简述
- slf4j、apache的commons-logging与上述日志框架的集成原理
- slf4j目前与commons-logging混用的境况
#2 jdk自带的logging
##2.1 使用案例
private static final Logger logger=Logger.getLogger(JdkLoggingTest.class.getName());
public static void main(String[] args){
logger.info("jdk logging info: a msg");
}
其中的Logger是:java.util.logging.Logger
##2.2 简单过程分析:
不想看源码的请略过
- ###创建一个LogManager
默认是java.util.logging.LogManager,但是也可以自定义,修改系统属性"java.util.logging.manager"即可,源码如下(manager就是LogManager):
try {
cname = System.getProperty("java.util.logging.manager");
if (cname != null) {
try {
Class clz = ClassLoader.getSystemClassLoader().loadClass(cname);
manager = (LogManager) clz.newInstance();
} catch (ClassNotFoundException ex) {
Class clz = Thread.currentThread().getContextClassLoader().loadClass(cname);
manager = (LogManager) clz.newInstance();
}
}
} catch (Exception ex) {
System.err.println("Could not load Logmanager \"" + cname + "\"");
ex.printStackTrace();
}
if (manager == null) {
manager = new LogManager();
}
- ###加载配置文件
默认是jre目录下的lib/logging.properties文件,也可以自定义修改系统属性"java.util.logging.config.file",源码如下:
String fname = System.getProperty("java.util.logging.config.file");
if (fname == null) {
fname = System.getProperty("java.home");
if (fname == null) {
throw new Error("Can't find java.home ??");
}
File f = new File(fname, "lib");
f = new File(f, "logging.properties");
fname = f.getCanonicalPath();
}
InputStream in = new FileInputStream(fname);
BufferedInputStream bin = new BufferedInputStream(in);
try {
readConfiguration(bin);
}
-
###创建Logger,并缓存起来,放置到一个Hashtable中,并把LogManager设置进新创建的logger中
以tomcat为例,它就自定义了上述配置:
***在tomcat的启动文件catalina.bat中,有如下设置: ***
- ###修改属性"java.util.logging.manager",自定义LogManager,使用自己的ClassLoaderLogManager
if not "%LOGGING_MANAGER%" == "" goto noJuliManager
set LOGGING_MANAGER=-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
:noJuliManager
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_MANAGER%
- ###修改属性"java.util.logging.config.file",自定义配置文件,使用自己的%CATALINA_BASE%\conf\logging.properties文件
if not "%LOGGING_CONFIG%" == "" goto noJuliConfig
set LOGGING_CONFIG=-Dnop
if not exist "%CATALINA_BASE%\conf\logging.properties" goto noJuliConfig
set LOGGING_CONFIG=-Djava.util.logging.config.file="%CATALINA_BASE%\conf\logging.properties"
:noJuliConfig
set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG%
所以如果想研究tomcat的日志,可以从上面入手。
jdk自带的logging不再详细介绍,有兴趣的参见这篇文章JDK Logging深入分析
#3 log4j1
##3.1 使用案例
###3.1.1 需要的jar包
- ####log4j
maven依赖如下:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
###3.1.2 使用方式
- ####第一步:编写log4j.properties配置文件,放到类路径下
log4j.rootLogger = debug, console
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} %m%n
配置文件的详细内容不是本博客关注的重点,不再说明,自行搜索
- ###第二步:代码中如下使用
public class Log4jTest {
private static final Logger logger=Logger.getLogger(Log4jTest.class);
public static void main(String[] args){
if(logger.isTraceEnabled()){
logger.debug("log4j trace message");
}
if(logger.isDebugEnabled()){
logger.debug("log4j debug message");
}
if(logger.isInfoEnabled()){
logger.debug("log4j info message");
}
}
}
- ####补充:
- 上述方式默认到类路径下加载log4j.properties配置文件,如果log4j.properties配置文件不在类路径下,则可以选择如下方式之一来加载配置文件
-
使用classLoader来加载资源
PropertyConfigurator.configure(Log4jTest.class.getClassLoader().getResource("properties/log4j.properties"));
-
使用log4j自带的Loader来加载资源
PropertyConfigurator.configure(Loader.getResource("properties/log4j.properties"));