java 日志框架

日志介绍

  有数据表明,一个应用程序中大约有4%的代码用来打印日志。开发时,一般使用debug级别;生产环境,一般使用info级别。


日志分类

  SQL日志、异常日志、业务日志


日志接口

  Commons-logging、SLF4J。

  它们都提供了日志解耦功能。不过Commons-logging还提供了简单的日志实现;而SLF4J所提供的核心API只是一些接口以及一个LoggerFactory的工厂类,并没有具体的实现,所以SLF4J必需依赖其他的日志实现。

  Commons-logging 和 SLF4J 都能够自动选择使用哪个日志实现。
  Commons-logging 有两个基本的抽象类: Log( 基本记录器 ) 和 LogFactory( 负责创建 Log 实例 ) 。当 commons-logging.jar 被加入到 CLASSPATH之后,它会合理地猜测你想用的日志工具,然后进行自我设置,根本不需要用户做任何设置。默认的 LogFactory 是按照下列的步骤去发现并决定使用哪个日志实现的:
  ①首先在classpath下找commons-logging.properties文件。找到,就使用其中定义的Log实现类;找不到,则查找是否已定义系统环境变量org.apache.commons.logging.Log,找到就使用其定义的Log实现类;
  ②查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类;
  ③否则,使用JDK自身的日志实现类(JDK1.4以后才有日志实现类);
  ④否则,使用commons-logging自己提供的一个简单的日志实现类SimpleLog。

  Apache 曾成功说服 log4j 以及其他的日志框架都按照 commons-logging 的标准来实现,但由于 commons-logging 的类加载器有点问题,实现起来也不友好,所以log4j的作者又开发了SLF4J。

  从设计模式的角度考虑,SLF4J和commons-logging都有点类似于JDBC,如同使用JDBC基本不用考虑具体数据库一样。他们提供了统一的记录日志的接口,调用接口,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。不过它们比JDBC更简单,在JDBC中,你需要指定驱动程序,而在使用SLF4J和commons-logging的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。

  如果一个项目已经使用了log4j,而你加载了一个类库,比方说Apache Active MQ。而Apache Active MQ 依赖于另外一个日志框架logback,那么此时你就需要把logback也引入进来。但如果Apache Active MQ使用了SLF4J,你可以继续使用log4j而无需引入和维护logback。
  也就是说,如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,这样就不会影响最终用户选择哪种日志系统。而如果你开发的只是一个简单或者独立的应用,不被会别人当jar包使用,确定只有一种日志系统,那么就没有必要一定使用SLF4J。

  log4j用到了 isDebugEnable(),在项目刚运行时就拼接字符串到内存,不仅检查了两次日志级别,还占用了内存空间,导致性能比其他日志实现差。log4j结合slf4j后使用参数替代字符串拼接,只检查一次日志级别,且只在需要输出日志时才会拼接字符串,性能有提升。

  hibernate默认的日志框架是slf4j、log4j。


日志实现

1、jdk也提供的日志记录功能 java.logging

  没有日志级别;
  如果想写出到文件,需要自己使用IO流来实现

2、log4j是一个非常优秀的开源日志记录工具

  a、控制日志的输出级别
  b、控制日志信息输送的目的地是控制台、文件等
  c、控制每一条日志的输出格式

4、logback

  Logback是log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core,logback-classic和logback-access。logback-core是其它两个模块的基础模块,logback-classic是log4j的一个改良版本。


log4j的使用

1、添加 jar 包

  方案一:

  log4j-1.2.16.jar、commons-logging-1.1.3.jar 二个 jar 包

       方案二:

  log4j、slf4j-api、slf4j-log4j12 三个 jar 包

2、创建 log4j.properties 文件并配置,默认文件名就是它

3、代码实现

  // commons-logging 框架
  // private Log log = LogFactory.getLog(Log4jCommonsLogging.class);
  // slf4j 框架
  // private Logger log = LoggerFactory.getLogger(this.getClass());
  // log4j 框架
  // private Logger log = Logger.getLogger(this.getClass());
  // 输出日志
   log.info("方法开始...");

 


配置实例

# 设置日志级别和输出目的地
# 日志级别 fatal>error>warn>info>debug,开发时一般设置为debug最低级别,生产上可设置为info或warn级别
# 输出目的地的名称自定义,这里定义了stdout和logfile;其中stdout代表输出到控制台
log4j.rootLogger=debug,stdout,logfile
# 把日志信息输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
# 打印出来是红色字体
log4j.appender.stdout.Target=System.err
# 输出简单格式
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
# 把日志信息输出到文件
log4j.appender.logfile=org.apache.log4j.FileAppender
# 指定文件名
log4j.appender.logfile.File=zr.log
# 这里没有使用 simpleLayout,而是使用 PatternLayout
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
# 使用 PatternLayout 还要为其指定格式
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss}%l%F%p%m%n

输出格式配置

%p:输出日志级别,即debug、info、warn、error、fatal
%d:输出日志发生时间
%r:输出从应用启动到输出该log信息耗费的毫秒数
%l:输出日志发生位置,相当于%C.%M(%F:%L)的组合,包括类名、发生的线程、产生日志的文件、代码中的行数
如:TestLog4j.main(TestLog4j.java:10)
    TestLog4j         ------ 类名
    main           ------ 发生的线程
    TestLog4j.java      ------ 由哪个文件产生的日志
    10         ------ 代码中的行数
%F:输出产生日志文件,%l已经包含了%F
%L:输出代码中的行数,%l已经包含了%L
%m:输出日志内容
%n:输出换行符,windows为"\r\n",unix为"\n"

 

posted @ 2018-11-08 22:15  zhuangrunwei  阅读(236)  评论(0编辑  收藏  举报