java日志组件总结

java日志组件总结

一、常用日志组件关系图
java日志组件总结
从上图中,我们可以看到 4 部分。
接口:将所有日志实现适配到了一起,用统一的接口调用。
实现:目前主流的日志实现
旧日志到 slf4j 的适配器:如果使用了 slf4j ,但是只想用一种实现,想把 log4j 的日志体系也从 logback 输出,这个是很有用的。
slf4j 到实现的适配器:如果想制定 slf4j 的具体实现,需要这些包。

二、slf4J与旧日志框架的关系
slf4j 等于commons-logging,是各种日志实现的通用入口,会根据classpath中存在下面哪一个Jar来决定具体的日志实现库。
logback-classic(默认的 logback实现 )
slf4j-jcl.jar(apache commons logging)
slf4j-logj12.jar(log4j 1.2.4)
slf4j-jdk14(java.util.logging)
将所有使用旧式日志 API 的第三方类库或旧代码的日志调用转到 slfj
jcl-over-slf4j.jar/jcl104-over-slf4japache commons logging 1.1.1/1.0.4,直接替换即可。
log4j-over-slf4j.jarlog4j,直接替换即可。
jul-to-slf4jjdk logging,需要在程序开始时调用 SLF4JBridgeHandler.install()来注册 listener参考 JulOverSlf4jProcessor,可在 applicationContext.xml中定义该 bean来实现初始化。注意原有的 log4j.properites将失效, logback网站上提供转换器,支持从 log4j.properties 转换到 logback.xml 

三、优势:转移到logback的理由
    slf4j支持参数化的 logger.error("帐号 ID{}不存在 ", userId);告别了 if(logger.isDebugEnable()) 时代。
    另外 logback的整体性能比 log4j也较佳, hibernate等项目已经采用了 slf4j:"某些关键操作,比如判定是否记录一条日志语句的操作,其性能得到了显著的提高。这个操作在 LOGBack中需要 3纳秒,而在 Log4J中则需要 30纳秒。  LOGBack创建记录器( logger)的速度也更快: 13毫秒,而在 Log4J中需要 23毫秒。更重要的是,它获取已存在的记录器只需 94纳秒,而  Log4J需要 2234纳秒,时间减少到了 1/23"

slf4j logback的使用
1.如果日志的参数超过 3个,需要写成
Object[] params = {newVal, below, above}; logger.debug("Value {} was inserted between {} and {}.", params);
commons-logging slf4j的代码比较: commons-logging 示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
  
public class TestLog {
    Log log = LogFactory.getLog(TestLog.class);
  
    public void print() {
        if (log.isDebugEnabled()) {
            log.debug(sql);
            log.debug("My name is " + name + ", I am " + age + " years old.");
        }
    }
}


slf4j的示例代码:

1
2
3
4
5
6
7
8
9
10
11
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  
public class TestLogBySlf4J {
    Logger logger = LoggerFactory.getLogger(TestLogBySlf4J.class);
  
    public void print() {
        logger.debug(sql);
        logger.debug("My name is {}, I am {} years old.", name, age);
    }
}

2.因为内部已优化,作者认为 slf4jlogger不需要定义为 static
3.可设置缓存后批量写日志文件 (但服务器如果重启,可能会丢失未写到磁盘的记录 )
4.MDC,用 Filter,将当前用户名等业务信息放入 MDC中,在日志 format定义中即可使用该变量。
5.JMS Appender用于告警 , DB Appender用于业务日志等

 

四、相关配置

日志配置参数说明

%m

输出代码中指定的消息

%p

输出优先级,即DEBUGINFOWARNERRORFATAL

%r

输出自应用启动到输出该log信息耗费的毫秒数

%c

输出所属的类目,通常就是所在类的全名

%t

输出产生该日志事件的线程名

%n

输出一个回车换行符,Windows平台为“\r\n”Unix平台为“\n”

%d

输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:20021018 221028921

%l

输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

 

以下是一个完整的log4j.properties

1
2
3
4
5
6
7
8
9
10
log4j.rootCategory=error, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p : %c(%L) -> %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=/home/httpd/html/gameStatistics/log/stats.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d %p : %c(%L) -> %m%n
log4j.logger.org.apache.commons=error
log4j.logger.com.danga.MemCached.MemCachedClient=ERROR

其中 R ,代表 RollingFileAppender ,指定文件大小到达指定尺寸的时候产生一个新的日志文件, R.File 配置了文件路径和名称, R.layout 使日志以指定布局模式输出,
R.layout.ConversionPattern 采用类似 C 语言中的 printf 函数的打印格式格式化日志信息;
log4j.logger.com.danga.MemCached.MemCachedClient=ERROR ,指单独设置 memcached 日志级别
在工程的 src 根目录下创建 logback.xml 文件 ( 名字是固定的,转载过程自动完成,不需要手动控制 )
这里 logback 有一个专门用来读取 logback.xml 的机制, logback 框架初始化时,会调用类文件来读取 logback.xml 文件,若是没有找到,则调用默认设备文件,按照默认设备文件进行设备。
以下是一个完整的 logback.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   <!--定义时间戳-->
   <timestamp key="byDay" datePattern="yyyy-MM-dd"/>
   <!--定义指定文件名称的输出-->
   <appender name="RootFileAppender" class="ch.qos.logback.core.FileAppender">
      <!--此处设定的文件名称是动态设置的  即每天生成一个文件用于记录当天的文件信息-->
      <file>/home/httpd/html/gameStatistics/log/stats-${byDay}.log</file>
      <append>true</append>
       
      <layout class="ch.qos.logback.classic.PatternLayout">
         <pattern>%d{yyyy-MM-dd HH:mm:ss}, %p, %c, %t, %F, %L, %C{1}, %M %m%n</pattern>
      </layout>
       
      <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
         <level>debug</level>
       </filter>
       <!--过滤器指定该类的日志级别-->
   </appender>
    
   <!--定义控制台输出-->
   <appender name="RootConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
      <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
         <level>debug</level>
      </filter>
       
      <layout class="ch.qos.logback.classic.PatternLayout">
         <pattern>%d{yyyy-MM-dd HH:mm:ss}, %p, %c, %t, %F, %L, %C{1}, %M %m%n</pattern>
       </layout>
   </appender>
    
   <!-- 设置根 的日志级别,根元素是配置文件的入口-->
   <root>
      <level value="error"/>
       <appender-ref ref="RootFileAppender"/> <!-- 配置对RootFileAppender的引用-->
      <appender-ref ref="RootConsoleAppender"/> <!-- 配置对RootConsoleAppender的引用-->
   </root>
</configuration>


log4j.xml


2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
   
<log4j:configuration xmlns:log4j=' http://jakarta.apache.org/log4j/' >
   
    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
           <param name="ConversionPattern"  
                  value="[%d{dd HH:mm:ss,SSS\} %-5p] [%t] %c{2\} - %m%n" />
        </layout>
        <!--过滤器设置输出的级别-->
        <filter class="org.apache.log4j.varia.LevelRangeFilter">
            <param name="levelMin" value="debug" />
            <param name="levelMax" value="warn" />
            <param name="AcceptOnMatch" value="true" />
        </filter>
    </appender>
 
    <appender name="myFile" class="org.apache.log4j.RollingFileAppender">  
        <param name="File" value="D:/output.log" /><!-- 设置日志输出文件名 -->
        <!-- 设置是否在重新启动服务时,在原有日志的基础添加新日志 -->
        <param name="Append" value="true" />
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
        </layout>
    </appender>
  
    <appender name="activexAppender" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="E:/activex.log" /> 
        <param name="DatePattern" value="'.'yyyy-MM-dd'.log'" /> 
        <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" 
            value="[%d{MMdd HH:mm:ss SSS\} %-5p] [%t] %c{3\} - %m%n" />
        </layout> 
    </appender>
   
    <!-- 指定logger的设置,additivity指示是否遵循缺省的继承机制-->
    <logger name="com.runway.bssp.activeXdemo" additivity="false">
        <priority value ="info"/> 
        <appender-ref ref="activexAppender" /> 
    </logger>
 
    <!-- 根logger的设置-->
    <root>
        <priority value ="debug"/>
        <appender-ref ref="myConsole"/>
        <appender-ref ref="myFile"/>
    </root>
</log4j:configuration>

你可能感兴趣的:(log4j,logback,slf4j)