SLF4j-Log4j-JCL-JUL

<!--
JCL(Jakarta Commons Logging)
    commons-logging.jar, log4j.jar + log4j.properties or log4j.xml
    commons-logging.properties //Is optional, but is recommended, if absent, will guess(discover) your preferred logging system dynamically in some order.
    
    Theory: 
        LogFactory guess (discover) your preferred logging system dynamically.
        1) LogFactory.getAttribute("org.apache.commons.logging.Log"), this attribute can be set by code LogFactory.setAttribute() or set it in commons-logging.properties(preferred)
        2) System property of org.apache.commons.logging.Log
        3) Log4J.jar
        4) If the application is executing on a JDK 1.4 system, use the corresponding wrapper class (Jdk14Logger).
        5) Fall back to the default simple logging wrapper (SimpleLog).

    Best practice:
        commons-logging.properties: If you have a particular preference then providing a simple commons-logging.properties file which specifies the concrete logging library to be used is recommended

    Log Level:
        1.trace (the least serious)
        2.debug
        3.info
        4.warn
        5.error
        6.fatal (the most serious)
    
    Fault:
        1) Use class loader to discover logging system dynamically, so it conflicts with OSGi.
        2) log.isInfoEnabled() deduces the code readability.

SLF4J(Simple Logging Facade for Java)
    A abstract layer of logging, like commons-logging, need a concrete log framework: JUL(java.util.logging), Log4j, Loback

    Features
        1) Binding log implementation statically, so it can be used with OSGi.
        2) No need  "if log.isInfoEnabled()"
        3) Use placeholder : log.info("Hello {0}, {1}", "Alice", "Bob");

    Usage
          Log4j: slf4j-api.jar, slf4j-log4j.jar, log4j.jar
        Logback: slf4j-api.jar, logback.jar
            JUL: slf4j-api.jar, slf4j-jdk14.jar
         Simple: slf4j-api.jar, slf4j-simple.jar
           None: slf4j-api.jar, slf4j-nop.jar

    Redirect to Slf4J
        log4j-over-slf4j.jar replace log4j.jar
        jcl-over-slf4j.jar   replace commons-logging.jar
        Add jul-to-slf4j.jar
    
    Error
        Exception in thread "main" java.lang.StackOverflowError
          at java.util.Hashtable.containsKey(Hashtable.java:306)
          at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:36)
          at org.apache.log4j.LogManager.getLogger(LogManager.java:39)

        Reason
            dependency cycle: Slf4j redirect to Log4j, and Log4j redirect to Slf4j
            classpath: slf4j-log4j.jar, log4j-over-slf4j.jar

Logback(https://logback.qos.ch, successor of Log4j, native implementation of slf4j, no need slf4j adapter)
    logback-classic will import logback-core and slf4j.

    logback.xml

    <?xml version="1.0" encoding="UTF-8"?>

    <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL -->
    <configuration scan="false" debug="false">
      <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
          <!--
          <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level %caller %msg%n</pattern>
          <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level %replace(%caller{1}){'\bCaller\+0\s\sat',''} - %msg%n</pattern> 
           -->
          <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %level %replace(%caller{1}){'\bCaller\+0\s\sat',''} - %msg%n</pattern>
        </encoder>
      </appender>

      <root level="debug">
        <appender-ref ref="STDOUT" />
      </root>
    </configuration>

JUL(java.util.logging)
    JUL log level: FINEST,FINER,FINE (TRACE), CONFIG (DEBUG), INFO, WARNING, SEVERE(ERROR), ALL, OFF

    import java.util.logging.Formatter;
    import java.util.logging.Level;
    import java.util.logging.LogRecord;
    import java.util.logging.Logger;
            
    public class Test {
        public static void main(String[] args) {
                Logger log = Logger.getLogger(ODNTest.class.getName());
                log.setLevel(Level.ALL); //Useless, solution:  \jdk8\jre\lib\logging.properties\java.util.logging.ConsoleHandler.level = ALL
        /*
                ConsoleHandler consoleHandler = new ConsoleHandler();
                consoleHandler.setLevel(Level.ALL);
                log.addHandler(consoleHandler);
        */
        /*
                FileHandler fileHandler = new FileHandler("C:/testlog%g.log");
                fileHandler.setLevel(Level.ALL);
                fileHandler.setFormatter(new MyLogFormater()); 
                log.addHandler(fileHandler);
        */
                log.severe("Severe 111");
                log.warning("Warning 222");
                log.info("Info 333");
                log.config("Config 444");
                log.fine("Fine 555");
                log.finer("Finer 666");
                log.finest("Finest 777");
        }
    }

    class MyLogFormater extends Formatter {
        public String format(LogRecord record) { 
            return record.getLevel() + ":" + record.getMessage()+"\n"; 
        }
    }

logback.xml
<!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE, ALL -->
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <property name="log_dir" value="c:/tmp" />
    <property name="maxHistory" value="7" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level [%thread] %replace(%caller{1}){'\bCaller\+0\s\sat',''} %m%n</pattern> 
            <!-- <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %level [%thread] %logger %m %n</pattern> -->
        </encoder>
    </appender>

    <appender name="fileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log_dir}/pim_%d{yyyyMMdd}.log</fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
         
        <encoder>
            <charset>UTF-8</charset>  
            <pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] %-5level [%thread] %logger [%file:%line] - %msg%n</pattern>
        </encoder>

        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <maxFileSize>10MB</maxFileSize>    
        </triggeringPolicy>
    </appender>
    
    <logger name="org.apache.ibatis" level="INFO"/>
    
    <root level="info">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="fileAppender"/>
    </root>
</configuration>
-->

 

posted @ 2018-01-22 10:59  Zenna  阅读(217)  评论(0编辑  收藏  举报