Java 中的日志

来源:互联网 发布:华为网盘windows版 编辑:程序博客网 时间:2024/06/16 00:14

日志在服务器体系中是最重要的一个部分。服务器定位错误的时候都是通过日志来检查的。好的日志系统能让程序员更加舒服的写日志,只有舒服的状态才能写出思路清晰的日志。

本文是从网上收集一些关于Java slf4j的日志信息,记录成文,方便今后查阅。
官网传送门

简介

The Simple Logging Facade for Java (SLF4J) 当做一种对于多种类型的日志系统 (e.g. java.util.logging, logback, log4j)的 Facade(外观) 或 abstraction,他允许最终用户在部署的时候再去指定日志系统。在使用SLF4J之前,官方强烈建议阅读SLF4J Manual文档。

实例:

 1: import org.slf4j.Logger; 2: import org.slf4j.LoggerFactory; 3:  4: public class Wombat { 5:   6:   final Logger logger = LoggerFactory.getLogger(Wombat.class); 7:   Integer t; 8:   Integer oldT; 9:10:   public void setTemperature(Integer temperature) {11:    12:     oldT = t;        13:     t = temperature;14:15:     logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT);16:17:     if(temperature.intValue() > 50) {18:       logger.info("Temperature has risen above 50 degrees.");19:     }20:   }21: } 

日志系统应该有以下几个特点:

1.日志需要分级;2.输出能设置回调函数,将日志输出重定向;3.支持按时间,或者按照大小做日志分割;

比较logback和log4j
引用

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。" 

引用

二、logback取代log4j的理由:    Logback和log4j是非常相似的,如果你对log4j很熟悉,那对logback很快就会得心应手。下面列了logback相对于log4j的一些优点:    1、更快的实现  Logback的内核重写了,在一些关键执行路径上性能提升10倍以上。而且logback不仅性能提升了,初始化内存加载也更小了。    2、非常充分的测试  Logback经过了几年,数不清小时的测试。Logback的测试完全不同级别的。在作者的观点,这是简单重要的原因选择logback而不是log4j。    3、Logback-classic非常自然实现了SLF4j    Logback-classic实现了 SLF4j。在使用SLF4j中,你都感觉不到logback-classic。而且因为logback-classic非常自然地实现了SLF4J,  所 以切换到log4j或者其他,非常容易,只需要提供成另一个jar包就OK,根本不需要去动那些通过SLF4JAPI实现的代码。    4、非常充分的文档  官方网站有两百多页的文档。    5、自动重新加载配置文件  当配置文件修改了,Logback-classic能自动重新加载配置文件。扫描过程快且安全,它并不需要另外创建一个扫描线程。这个技术充分保证了应用程序能跑得很欢在JEE环境里面。    6、Lilith   Lilith是log事件的观察者,和log4j的chainsaw类似。而lilith还能处理大数量的log数据 。    7、谨慎的模式和非常友好的恢复  在谨慎模式下,多个FileAppender实例跑在多个JVM下,能 够安全地写道同一个日志文件。RollingFileAppender会有些限制。Logback的FileAppender和它的子类包括 RollingFileAppender能够非常友好地从I/O异常中恢复。    8、配置文件可以处理不同的情况   开发人员经常需要判断不同的Logback配置文件在不同的环境下(开发,测试,生产)。而这些配置文件仅仅只有一些很小的不同,可以通过,和来实现,这样一个配置文件就可以适应多个环境。    9、Filters(过滤器)  有些时候,需要诊断一个问题,需要打出日志。在log4j,只有降低日志级别,不过这样会打出大量的日志,会影响应用性能。在Logback,你可以继续 保持那个日志级别而除掉某种特殊情况,如alice这个用户登录,她的日志将打在DEBUG级别而其他用户可以继续打在WARN级别。要实现这个功能只需 加4XML配置。可以参考MDCFIlter 。   10、SiftingAppender(一个非常多功能的Appender)  它可以用来分割日志文件根据任何一个给定的运行参数。如,SiftingAppender能够区别日志事件跟进用户的Session,然后每个用户会有一个日志文件。   11、自动压缩已经打出来的log  RollingFileAppender在产生新文件的时候,会自动压缩已经打出来的日志文件。压缩是个异步过程,所以甚至对于大的日志文件,在压缩过程中应用不会受任何影响。   12、堆栈树带有包版本  Logback在打出堆栈树日志时,会带上包的数据。   13、自动去除旧的日志文件  通过设置TimeBasedRollingPolicy或者SizeAndTimeBasedFNATP的maxHistory属性,你可以控制已经产生日志文件的最大数量。如果设置maxHistory 12,那那些log文件超过12个月的都会被自动移除。    总之,logback比log4j太优秀了,让我们的应用全部建立logback上吧 !

Java日志的渊源
引用

Java日志系统确实比较丰富,常用的有log4j、JUL、logback等等,同时伴随着日志系统的发展,出现了日志框架commons-logging和slf4j。简短地描述下日志发展,最先出现的是apache开源社区的log4j,这个日志确实是应用最广泛的日志工具,成为了java日志的事实上的标准。然而,当时Sun公司在jdk1.4中增加了JUL日志实现,企图对抗log4j,但是却造成了混乱,这个也是被人诟病的一点。当然也有其他日志工具的出现,这样必然造成开发者的混乱,因为这些日志系统互相没有关联,替换和统一也就变成了比较棘手的一件事。想象下你的应用使用log4j,然后使用了一个其他团队的库,他们使用了JUL,你的应用就得使用两个日志系统了,然后又有第二个库出现了,使用了simplelog。这个时候估计让你崩溃了,这是要闹哪样?这个状况交给你来想想办法,你该如何解决呢?进行抽象,抽象出一个接口层,对每个日志实现都适配或者转接,这样这些提供给别人的库都直接使用抽象层即可。不错,开源社区提供了commons-logging抽象,被称为JCL,也就是日志框架了,确实出色地完成了兼容主流的日志实现(log4j、JUL、simplelog),基本一统江湖,就连顶顶大名的spring也是依赖了JCL。看起来事物确实是美好,但是美好的日子不长,接下来另一个优秀的日志框架slf4j的加入导致了更加混乱的场面。比较巧的是slf4j的作者(Ceki Gülcü)就是log4j的作者,他觉得JCL不够优秀,所以他要自己搞一套更优雅的出来,于是slf4j日志体系诞生了,并为slf4j实现了一个亲子——logback,确实更加优雅,但是由于之前很多代码库已经使用JCL,虽然出现slf4j和JCL之间的桥接转换,但是集成的时候问题依然多多,对很多新手来说确实会很懊恼,因为比单独的log4j时代“复杂”多了,可以关注下这个,抱怨声确实很多。到此本来应该完了,但是Ceki Gülcü觉得还是得回头拯救下自己的“大阿哥”——log4j,于是log4j2诞生了,同样log4j2也参与到了slf4j日志体系中,想必将来会更加混乱。接下来详细解读日志系统的配合使用问题。

下载安装

依赖jar文件

    logback-access-1.0.0.jar    logback-classic-1.0.0.jar    logback-core-1.0.0.jar    slf4j-api-1.6.0.jar

官网:

http://logback.qos.chhttp://www.slf4j.org

maven依赖配置pom.xml配置

<dependency>  <groupId>org.slf4j</groupId>  <artifactId>slf4j-api</artifactId>  <version>1.7.10</version></dependency><dependency>  <groupId>ch.qos.logback</groupId>  <artifactId>logback-classic</artifactId>  <version>1.1.2</version></dependency><dependency>  <groupId>ch.qos.logback</groupId>  <artifactId>logback-core</artifactId>  <version>1.1.2</version></dependency>

logback配置中的概念

Logger、appender及layout

Logger作为日志的记录器,把它关联到应用的对应的context上后,主要用于存放日志对象,也可以定义日志类型、级别。
Appender主要用于指定日志输出的目的地,目的地可以是控制台、文件、远程套接字服务器、 MySQL、PostreSQL、 Oracle和其他数据库、 JMS和远程UNIX Syslog守护进程等。
Layout 负责把事件转换成字符串,格式化的日志信息的输出。

logger context

各个logger 都被关联到一个 LoggerContext,LoggerContext负责制造logger,也负责以树结构排列各logger。其他所有logger也通过org.slf4j.LoggerFactory 类的静态方法getLogger取得。 getLogger方法以 logger名称为参数。用同一名字调用LoggerFactory.getLogger 方法所得到的永远都是同一个logger对象的引用。

rollingPolicy

官网说明

TimeBasedRollingPolicy

在里面考虑了时间拆分日志文件,也涉及到日志保留的天数的配置项。

<configuration>  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">    <file>logFile.log</file>    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">      <!-- daily rollover -->      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>      <!-- keep 30 days' worth of history capped at 3GB total size -->      <maxHistory>30</maxHistory>      <totalSizeCap>3GB</totalSizeCap>    </rollingPolicy>    <encoder>      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>    </encoder>  </appender>   <root level="DEBUG">    <appender-ref ref="FILE" />  </root></configuration>

FixedWindowRollingPolicy

循环日志:

<configuration>  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">    <file>test.log</file>    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">      <fileNamePattern>tests.%i.log.zip</fileNamePattern>      <minIndex>1</minIndex>      <maxIndex>3</maxIndex>    </rollingPolicy>    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">      <maxFileSize>5MB</maxFileSize>    </triggeringPolicy>    <encoder>      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>    </encoder>  </appender>  <root level="DEBUG">    <appender-ref ref="FILE" />  </root></configuration>
0 0
原创粉丝点击