zoukankan      html  css  js  c++  java
  • logback使用总结

    filter: http://aub.iteye.com/blog/1110008

    http://aub.iteye.com/blog/1101222

    Logback

      Log4j的创始人Ceki Gülcü重写了Log4j的内部实现,改进后形成了Logback,相比Log4j速度更快,资源占用更少,也更稳定。(另外Log4j 2.0又是在Logback基础上进行了改进,但还未广泛使用)

    官方网站:http://logback.qos.ch/

    Logback包括3个部分:

    • logback-core(基础核心模块)
    • logback-classic(log4j改良版,完整实现SLF4J API接口,可方便的与其他日志系统切换)
    • logback-access(与Servlet容器集成提供通过Http访问日志的功能)

    特性:

    • Logback传统方法是使用XML保存配置,0.9.22+版本支持Groovy配置转换工具)。配置文件中支持条件处理。
    • Logback-classic可以在配置修改后自动重新载入。
    • FileAppender和它的子类,包括RollingFileAppender,可以优雅的从I/O错误中恢复。
    • 通过设置TimeBasedRollingPolicy 或者 SizeAndTimeBasedFNATP的 maxHistory 属性,你就可以控制日志归档文件的最大数量,清除旧的日志。
    • RollingFileAppender可以在回滚操作中,自动压缩归档日志文件。
    • Lilith是logback的一个记录和访问事件查看器。它相当于log4j的 chainsaw。
    • 强大的日志过滤功能
    • SiftingAppender全能追加器
    • 日志中堆栈信息包含依赖包名和版本
    • 谨慎模式下,多个JVM的多个FileAppender可以安全写入统一的日志文件。

    Logback的核心对象和用法与Log4j是相承的,主要对象有:

    • Logger
    • Appender
    • Layout
    • Filter:Logback-classic提供两种类型的过滤器:常规过滤器和TuroboFilter过滤器。

    Logback整体流程:

    • Logger 产生日志信息;
    • Layout修饰这条msg的显示格式;
    • Filter过滤显示的内容;
    • Appender具体的显示,即保存这日志信息的地方。

    Logback应用示例

    1.包引入

    •  logback-classic.jar  (依赖logback-core.jar,如果用maven等能够自动处理依赖的工具可以不用引入core包)
    •  slf4j-api.jar           (如果应用中使用slf4j API而不是logback自身的api才需引入)

    2.配置文件

    因为核心对象与Log4J相承,所有配置的思路也类似于log4j的.properties文件。

    Log4j, logback配置中的输出log目录: 使用Tomcat时,相对于CATALINA_HOME/bin目录

    A.XML版配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <configuration>
        <property name="LOG_HOME" value="log"/>
        
        <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>(%d{HH:mm:ss.SSS} [%thread]) %-5level %logger{32} %L - %msg%n</pattern>
            </encoder>
        </appender>
        
        <!--discardingThreshold: 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 --> 
        <!--queueSize:  更改默认的队列的深度,该值会影响性能.默认值为256 --> 
        <!--appender-ref:  添加附加的appender,最多只能添加一个 -->
        <!-- 包装其他的Appender,支持异步输出
        <appender name ="asyncFlume" class= "ch.qos.logback.classic.AsyncAppender">  
             <discardingThreshold >0</discardingThreshold>
             <queueSize>512</queueSize>      
             <appender-ref ref ="flume"/>  
        </appender>  
         -->
    
        <appender name="info2File" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY </onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${LOG_HOME}/info.%d{yyyy-MM-dd}.log
                </FileNamePattern>
                <MaxHistory>100</MaxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%-26(%d{HH:mm:ss SSS,Asia/Chongqing} [%thread]) %-5level
                    %logger{32} - %msg%n %caller{1, DISP_CALLER_EVAL}</pattern>
            </encoder>
        </appender>
        
        <appender name="error2File" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>ERROR</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY </onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${LOG_HOME}/error.%d{yyyy-MM-dd}.log
                </FileNamePattern>
                <MaxHistory>100</MaxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%-26(%d{HH:mm:ss SSS,Asia/Chongqing} [%thread]) %-5level
                    %logger{32} - %msg%n %caller{1, DISP_CALLER_EVAL}</pattern>
            </encoder>
        </appender>
          
          <appender name="login2File" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 特定过滤含有某字符串的日志
            <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
                <evaluator>
                    <expression>message.contains("str")</expression>
                </evaluator>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
             -->
             <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <FileNamePattern>${LOG_HOME}/login.%d{yyyy-MM-dd-HH}.log</FileNamePattern>
                <MaxHistory>2400</MaxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%m%n</pattern>
            </encoder>
          </appender>
          
          
        <appender name="all2db" class="ch.qos.logback.classic.db.DBAppender">
            <connectionSource
                class="ch.qos.logback.core.db.DriverManagerConnectionSource">
                <driverClass>com.mysql.jdbc.Driver</driverClass>
                <url>jdbc:mysql://host_name:3306/datebase_name</url>
                <user>username</user>
                <password>password</password>
            </connectionSource>
        </appender>
            
        <logger name="loginLog" level="INFO" additivity="false">
            <appender-ref ref="login2File"/>
        </logger>
        
        <logger name="errorLog" level="WARN" additivity="true">
            <appender-ref ref="error2File"/>
        </logger>
        
        <root>
            <level value="INFO"/>
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="info2File"/>
            <appender-ref ref="error2File"/>
        <appender-ref ref="all2db"/>
        </root>
    </configuration>

    appender/filter

    LevelFilter  元素会严格限制输出级别,级别必须相同才输出,而不是高于该级别的都输出。 

    ThresholdFilter   临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。

     <level>INFO</level>   

    EvaluatorFilter   求值过滤器,评估、鉴别日志是否符合指定条件。需要额外的两个JAR包,commons-compiler.jar和janino.jar有以下子节点

    <expression>   暴露字段: event(LoggingEvent), message(String),formatedMessage(String), logger(String), loggerContext(LoggerContextVO), level(int), timeStamp(long), marker(Marker), mdc(Map), throwable(Throwable), throwableProxy(IThrowableProxy)

    1. <evaluator<!-- 默认为 ch.qos.logback.classic.boolex.JaninoEventEvaluator -->   
    2.         <expression>return message.contains("billing");</expression>   
    3.       </evaluator>

    <matcher> 

    1. <evaluator>           
    2.         <matcher>   
    3.           <Name>odd</Name>   
    4.           <!-- filter out odd numbered statements -->   
    5.           <regex>statement [13579]</regex>   
    6.         </matcher>   
    7.            
    8.         <expression>odd.matches(formattedMessage)</expression>   
    9.       </evaluator>   

    3.代码中调用

     A.使用SLF4J API

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class LogbackDemo {
        private static Logger log = LoggerFactory.getLogger(LogbackDemo.class); 
        private static Logger loginlog = LoggerFactory.getLogger("loginLog"); 
        public static void main(String[] args)
        {
            log.info("normal message");
            log.warn("warning message");
            log.error("error message");
            loginlog.warn("login message");
        }
    }

    其他

    关于SLF4J

      Simple Logging Facade for Java。SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时,在应用不作任何改动的情况下,决定或切换使用的具体的日志系统。

      如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用SLF4J的必要。

      SLF4J提供了各个日志系统通用的接口以及一个LoggerFactory的工厂类。程序中使用SLF4j API时,不需要在代码或配置文件中指定具体要用哪个日志系统(如java.util.logging、 Log4j、logback等)。要切换成哪个日志系统,只需要把该系统对应的jar包加入到项目中,SLF4J就能自动选择使用你加入的这种日志系统了。这种方法被称之为动态绑定。当然,这个具体的日志系统的相关类库和配置是不能少,如果你打算使用log4j,那么还需要log4j的类库,可能还有配置配置log4j.properties。

      有些具体的日志系统在绑定时还需要桥接包(slf4j-xxx.jar),如slf4j-log412.jar(Log4j), slf4j-jdk14.jar(java.util.logging), slf4j-jcl.jar(commons-logging)。logback不需要桥接。具体日志系统绑定到slf4j如下图。

      

      有时候应用中已经使用了具体的日志系统,slf4j也可以为这些具体日志系统提供底层服务而不需要修改应用。通过另一类桥接包(xxx-over-slf4j.jar、xxx-to-slf4j.jar),能将slf4j绑定到已适用的具体日志系统中,如下图所示。

    关于common-logging

      common-logging是apache提供的一个通用的日志接口,动态绑定。作用与SLF4J相同。早期名为Jakarta Commons Logging,JCL。

    关于ContextDetachingSCL监听器

       为了在单个web项目重启和关闭的时候,对应的logger Context可以被回收,最好配置ContextDetachingSCL监听器。

    <listener>
        <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class>
    </listener>

    说明文档:http://www.blogjava.net/watchzerg/archive/2014/07/13/415754.html

    参考文档

    logback配置:http://blog.csdn.net/haidage/article/details/6794529

    http://www.cnblogs.com/yongze103/archive/2012/05/05/2484753.html

    各个日志系统及其绑定关系: http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html

  • 相关阅读:
    6.25作业
    博客园第一篇
    532. 数组中的K-diff数对
    echarts
    跨域问题
    数组中第三大的数 leetcode 414
    除自身以外数组的乘积leetcode 238
    xshell工具
    插入、删除和随机查询时间复杂度都为O(1) leetcode 381
    组合总和3 leetcode 216
  • 原文地址:https://www.cnblogs.com/pixy/p/4980603.html
Copyright © 2011-2022 走看看