Java——日志框架

3 篇文章 0 订阅
2 篇文章 0 订阅

目录

日志接口

日志实现

关系

Commons Logging实现机制

Slf4j实现机制

日志实现框架

Java 日志框架的选择

log4j配置文件

logback配置文件


日志接口

commons-loggin

slf4j

日志实现

log4j

logback

关系

  • Log4j 2与Log4j 1都是Apache旗下的日志框架,Log4j 2与Log4j 1发生了很大的变化,Log4j 2不兼容Log4j 1。

  • Commons Logging和Slf4j是日志门面(门面模式是软件工程中常用的一种软件设计模式,也被称为正面模式、外观模式。它为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用)。Log4j和Logback则是具体的日志实现方案。可以简单的理解为接口与接口的实现,调用者只需要关注接口而无需关注具体的实现,做到解耦。

  • 比较常用的组合使用方式是Slf4j与Logback组合使用,Commons Logging与Log4j组合使用。

  • Logback必须配合Slf4j使用。由于Logback和Slf4j是同一个作者,其兼容性不言而喻。

Commons Logging实现机制

Commons Logging是通过动态查找机制,在程序运行时,使用自己的ClassLoader寻找和载入本地具体的实现。详细策略可以查看commons-logging-*.jar包中的org.apache.commons.logging.impl.LogFactoryImpl.java文件。由于Osgi不同的插件使用独立的ClassLoader,Osgi的这种机制保证了插件互相独立, 其机制限制了Commons Logging在Osgi中的正常使用。

Slf4j实现机制

Slf4j在编译期间,静态绑定本地的Log库,因此可以在Osgi中正常使用。它是通过查找类路径下org.slf4j.impl.StaticLoggerBinder,然后在StaticLoggerBinder中进行绑定。

日志实现框架

  • Jul:Java Util Logging,自Java1.4以来的官方日志实现。

  • Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在则是Apache软件基金会的一个项目。

  • Apache Log4j 2是apache开发的一款Log4j的升级产品,并且不兼容Log4j。

  • Logback是一个日志框架,Log4j是同一作者,都出自Ceki Gülcü之手。

Java 日志框架的选择

  • 成本考虑:Logback文档免费。Logback的所有文档是全面免费提供的,不象Log4J那样只提供部分免费文档而需要用户去购买付费文档。

  • 资源开销:Commons Logging相比较与SLF4J开销更高.

  • 性能:Logback相比Log4j、Log4j2拥有更好的性能。Logback声称:某些关键操作,比如判定是否记录一条日志语句的操作,其性能得到了显著的提高。这个操作在Logback中需要3纳秒,而在Log4J中则需要30纳秒。LogBack创建记录器(logger)的速度也更快:13毫秒,而在Log4J中需要23毫秒。更重要的是,它获取已存在的记录器只需94纳秒,而Log4J需要2234纳秒,时间减少到了1/23。跟JUL相比的性能提高也是显著的。

log4j配置文件

### 注:log4j.properties配置文件要放在resources目录下
# 指定日志的输出级别与输出端(输出级别,自定义输出端名称,自定义输出端名称....)
log4j.rootLogger = trace,console,myFile,rollingFile,dailyFile,dbFile

###### 控制台输出配置
log4j.appender.console = org.apache.log4j.ConsoleAppender
# 使用PatternLayout来声明日志用自定义格式
log4j.appender.console.layout = org.apache.log4j.PatternLayout
# 针对PatternLayout来用conversionPattern设置格式
log4j.appender.console.layout.conversionPattern = %d [%t] %-5p [%c] - %m%n

###### 文件输出配置
log4j.appender.myFile = org.apache.log4j.FileAppender
log4j.appender.myFile.layout = org.apache.log4j.PatternLayout
log4j.appender.myFile.layout.conversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %m%n
# 是否以追加日志的形式添加(默认就是true)
log4j.appender.myFile.append = true
# 指定日志的输出路径
log4j.appender.myFile.file = ./fileLog.log
# 指定日志的文件编码
log4j.appender.myFile.encoding = utf-8

###### 文件自动按大小拆分配置
log4j.appender.rollingFile = org.apache.log4j.RollingFileAppender
log4j.appender.rollingFile.layout = org.apache.log4j.PatternLayout
log4j.appender.rollingFile.layout.conversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %m%n
log4j.appender.rollingFile.append = true
log4j.appender.rollingFile.file = ./fileRollingFileLog.log
log4j.appender.rollingFile.encoding = UTF-8
# 文件内容超过2KB则进行拆分,拆分的最多文件由maxBackupIndex定义
log4j.appender.rollingFile.maxFileSize = 2KB
# 文件拆分的数量(这里是3),当文件拆分的数量超限时则最新拆分出的文件覆盖最老的日志文件
log4j.appender.rollingFile.maxBackupIndex = 3

###### 文件自动按日期拆分配置
log4j.appender.dailyFile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.layout = org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.conversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [%t:%r] - [%p] %m%n
log4j.appender.dailyFile.append = true
log4j.appender.dailyFile.file = ./dailyRollingFile.log
log4j.appender.dailyFile.encoding = UTF-8
# 文件拆分的日期 正常按照 '.'yyyy-MM-dd 以天为拆分,这里我以每秒拆分一次
log4j.appender.dailyFile.datePattern = '.'yyyy-MM-dd HH-mm-ss

# MySQL输出配置
log4j.appender.dbFile = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.dbFile.layout = org.apache.log4j.PatternLayout
log4j.appender.dbFile.layout.conversionPattern = %p %r %c %t %d{yyyy/MM/dd HH:mm:ss:SSS} %m %l %F %L %% %n
log4j.appender.dbFile.URL = jdbc:mysql://localhost:3306/log4j?serverTimezone=GMT%2B8&useAffectedRows=true&useSSL=false
log4j.appender.dbFile.User = root
log4j.appender.dbFile.Password = 123
log4j.appender.dbFile.Sql=INSERT INTO log(project_name, create_date, level, category, file_name, thread_name, line, all_category, message) \
  values('log4j_xiaofeng', '%d{yyyy-MM-dd HH:mm:ss}', '%p', '%c', '%F', '%t', '%L', '%l', '%m')

logback配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志格式参数,后面可以通过${myPattern}使用-->
    <property name="myPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/>
    <!--定义日志路径参数,后面可以通过${myPattern}使用-->
    <property name="file_dir" value="D:/logs"/>

    <!--定义FileAppender 用于在文件上输出日志-->
    <appender name="fileAppend" class="ch.qos.logback.core.FileAppender">
        <!--日志文件名称-->
        <file>${file_dir}/fileLogback.log</file>
        <!--配置日志输出格式,并引用 myPattern 自定的日志格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${myPattern}</pattern>
        </encoder>
    </appender>

    <!--定义FileAppender 用于在文件上输出日志-->
    <appender name="fileHtmlAppend" class="ch.qos.logback.core.FileAppender">
        <file>${file_dir}/fileLogback.html</file>
        <!--因为是要输出HTML格式,所以需要布局包装器一下-->
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <!--设置最终的输出样式-->
            <layout class="ch.qos.logback.classic.html.HTMLLayout">
                <pattern>%level%d{yyyy-MM-dd HH:mm:ss}%c%M%L%thread%m</pattern>
            </layout>
        </encoder>
    </appender>
    
    <!--配置日志记录器并设置日志记录器的打印级别-->
    <root level="ALL">
        <!--引入appender....-->
        <appender-ref ref="fileAppend"/>
        <appender-ref ref="fileHtmlAppend"/>
    </root>
</configuration>

拆分文档

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志格式参数,后面可以通过${myPattern}使用-->
    <property name="myPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/>
    <!--定义日志路径参数,后面可以通过${myPattern}使用-->
    <property name="file_dir" value="D:/logs"/>

    <!--定义RollingFileAppender 用于在文件上输出日志并拆分归档-->
    <appender name="rollFileAppend" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--定义日志输出的路径-->
        <!--这里的scheduler.manager.server.home 没有在上面的配置中设定,所以会使用java启动时配置的值-->
        <!--比如通过 java -Dscheduler.manager.server.home=/path/to XXXX 配置该属性-->
        <file>${scheduler.manager.server.home}/fileRollLogback.log</file>
        <!--配置日志输出格式,并引用 myPattern 自定的日志格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${myPattern}</pattern>
        </encoder>
        <!--基于大小和时间滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--按照时间和压缩格式声明文件名 压缩文件为.gz-->
            <fileNamePattern>${scheduler.manager.server.home}/roll.%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
            <!--按照文件大小拆分 每个文件达到500MB会自动压缩归档-->
            <maxFileSize>500MB</maxFileSize>
        </rollingPolicy>
    </appender>

    <!--配置日志记录器并设置日志记录器的打印级别-->
    <root level="ALL">
        <!--引入appender....-->
        <appender-ref ref="rollFileAppend"/>
    </root>
</configuration>

过滤器及异步打印

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志格式参数,后面可以通过${myPattern}使用-->
    <property name="myPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/>

    <!--定义ConsoleAppender 用于在屏幕上输出日志-->
    <appender name="consoleAppend" class="ch.qos.logback.core.ConsoleAppender">
        <!--显示控制台日志颜色 System.err【红色】 System.out【默认白色】-->
        <target>System.err</target>
        <!--配置日志输出格式,并引用 myPattern 自定的日志格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${myPattern}</pattern>
        </encoder>

        <!--LevelFilter: 级别过滤器,根据日志级别进行过滤。如果日志级别等于配置级别,
        过滤器会根据onMath 和 onMismatch接收或拒绝日志。-->
        <!--例如:将过滤器的日志级别配置为INFO,所有INFO级别的日志交给appender处理,非INFO级别的日志,被过滤掉。-->
<!--        <filter class="ch.qos.logback.classic.filter.LevelFilter">-->
<!--        <level>INFO</level>-->
<!--        <onMatch>ACCEPT</onMatch>-->
<!--        <onMismatch>DENY</onMismatch>-->
<!--        </filter>-->
        <!--ThresholdFilter: 临界值过滤器,过滤掉低于指定临界值的日志。当日志级别等于或高于临界值时,
        过滤器返回NEUTRAL;当日志级别低于临界值时,日志会被拒绝。-->
        <!-- 过滤掉所有低于 DEBUG 级别的日志,留下DEBUG及以上级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>
    
    <!--配置异步日志-->
    <appender name="asyncAppend" class="ch.qos.logback.classic.AsyncAppender">
        <!--要使用到异步的Appender-->
        <appender-ref ref="consoleAppend"/>
    </appender>
    
    <!--配置日志记录器并设置日志记录器的打印级别-->
    <root level="ALL">
        <!--引入appender....-->
        <appender-ref ref="asyncAppend"/>
    </root>
</configuration>

自定义logger

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志格式参数,后面可以通过${myPattern}使用-->
    <property name="myPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %c [%thread] %-5level %msg%n"/>
    <!--定义ConsoleAppender 用于在屏幕上输出日志-->
    <appender name="consoleAppend" class="ch.qos.logback.core.ConsoleAppender">
        <!--显示控制台日志颜色 System.err【红色】 System.out【默认白色】-->
        <target>System.err</target>
        <!--配置日志输出格式,并引用 myPattern 自定的日志格式-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${myPattern}</pattern>
        </encoder>
    </appender>

    <!--additvity="false" 不继承父元素-->
    <logger name="cn.xw" level="INFO" additvity="false">
        <!--自定义logger中配置appender-->
        <appender-ref ref="consoleAppend"/>
    </logger>
</configuration>

加载顺序

logback在启动的时候,会按照下面的顺序加载配置文 ①:如果java程序启动时指定了logback.configurationFile属性,就用该属性指定的配置文件。 如java -Dlogback.configurationFile=/path/to/mylogback.xml Test , 这样执行Test类的时候就会加载/path/to/mylogback.xml配置 ②:在classpath中查找 logback.groovy 文件 ③:在classpath中查找 logback-test.xml 文件 ④:在classpath中查找 logback.xml 文件 ⑤:如果是jdk6+,那么会调用ServiceLoader 查找com.qos.logback.classic.spi.Configurator接口的第一个实现类 ⑥:自动使用ch.qos.logback.classic.BasicConfigurator,在控制台输出日志 注:上面的顺序表示优先级,使用java -D配置的优先级最高,只要获取到配置后就不会再执行下面的流程。 相关代码可以看ContextInitializer#autoConfig()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值