`
clannadyue
  • 浏览: 5350 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

Java日志框架研究及常见配置

阅读更多
    按照基本的定义,日志即是对程序运行过程中关键事件的记录;大体日志分为运行日志和开发日志,运行日志在业务层面记录一些关键事件,为后面的跟踪运行提供帮助,而开发日志大多数时候是调试日志,根据事件流的输出来调试程序;因为开发人员本身的关注领域,运行日志可能制作的比较少,难以达到跟踪业务流的作用,而即使是开发日志,因为开发的调试有各种技巧,即使是跟踪事件流,使用println也比日志配置简单多了,这是一个投资回报的问题,而人经常性的是短视的,调试可能在这些人眼里根本不需要认真对待,没有前期的事件记录规划,随着系统规模膨胀,执行流增多,执行事件保障,这时候没有一种合理的“开关”机制来选择查看感兴趣事件流,那结局是明晰的,日志不止提供了一种树形的开关结构,它还有灵活的输出控制,在Java常用日志框架Log4J还提供了JMX等接口,可以通过管理面板来监控和修改日志记录行为,这无疑是非常诱人的。
    大体上Java体系中比较常用的日志框架如下

日志框架

支持日志级别

Log4J

FATAL ERROR WARN INFO DEBUG TRACE

Java Logging API

SEVERE WARNING INFO CONFIG FINE FINER FINEST

Apache Commons Logging

FATAL ERROR WARN INFO DEBUG TRACE

SLF4J

ERROR WARN INFO DEBUG TRACE

Logback

ERROR WARN INFO DEBUG TRACE

Jboss logging

FATAL ERROR WARN INFO DEBUG TRACE

按照我比较有限的经验,我大多时候使用的是Log4J1.x版本,在配置一些开源框架时,可能需要到Apache Commons LoggingSLF4J,在配置Jboss系工具和框架的时候需要用到Jboss logging(例如Hibernate),其他日志框架如Java Logging,为Java自带的,功能上比较简单,用的也不是很多 ,而另一个Logback,这是一个号称Log4J继承者的新一代日志框架,因为我对“新一代”这个名词比较不感冒,我还没有怎么看,感兴趣的可以看看。
    基本上,日志级别是很相似的,这不仅仅是Java生态范围内,整个编程行业应该都有共识,通过日志级别来标记事件的轻重缓急,我们可以通过这个条件进行过滤,显示我们感兴趣的内容,关于日志级别之间的相互关系,这个比较简单,这里就不再说了。
    优秀的编程设计原则中有一条“依赖倒置”,要依赖抽象,不要依赖具体,具体的实践就是面向接口设计了,优秀的项目都会定义高层次抽象,通过封装隐藏多余的信息,这样在代码变动或者想不修改原有代码扩展的时候(开闭原则),能够相对容易的满足这些需求,而这些日志框架设计结构中则充分发挥了面向接口设计的优良传统,日志框架的核心接口是Logger类(接口),其他部分则是围绕此类(接口)展开,这里我们看两个定义例子,SLF4J的Logger定义如下


 
Apache Commons Logging的Log定义如下


 
因为其他的日志框架实在都太“重量级”了,方法太多,这里就不贴出定义了,日志框架定义了基本的接口,通过提供一个Facade,而后端由谁去实现就不那么重要了,这里面Apache Commons Logging、SLF4J、Jboss logging都容许其他后端实现为别的日志框架(大部分为Java Logging 、Log4J,差异化的部分在讲这些日志框架的时候再详细叙述),如何将Facade的请求转为后端可识别请求,知道一点设计模式的人应该马上想到适配器模式,这里,我们想给出几个日志框架如何实现这个接口适配的解决方法,我们一一道来。
     Apache Commons Logging


 
这是标准的适配器模式,没有什么好讲的,Apache Commons Logging提供的实际工作类如下


 
这里面我们比较熟悉的是JDK自带的Java Logging和Log4J,其他几个因为不怎么常用就不说了,关于Apache Commons Logging如何选择具体的实现类,这个可以从LogFactory的实现类中查找到逻辑,逻辑代码如下:


 

 
因为代码比较长,这里只贴出关键部分逻辑,可以看得很清楚,用户通过配置文件指定后端实现,反之通过查找类路径来选择具体实现类。
SLF4J
SLF4J也存在上述类似的适配方式,这里我们给出SLF4J有些不同的bridge方式,其形式类似适配,如下


 
这个结构有些复杂,这里是SLF4J到Log4J的桥接,我们看到Log4jLoggerFactory提供了类似的适配功能,这种方式的好处,按照官方文档的说法是提供了编译时绑定,排除了运行时的探测方式,性能会好一些,看着这图有些抽象,这里给出一个具体的应用场景,如下
   Spring日志配置
    Spring项目使用了Apache Commons Logging日志框架,因为该日志框架比较老旧,我们一般使用Log4J作为其后端实现,通过上面的介绍,我们知道只要将Log4J放入ClassPath中就可以了,如果使用maven,在依赖中添加Log4J就可以了,这里如何使用SLF4J的桥接,结果有些复杂,首先需要去掉Apache Commons Logging依赖,然后添加Spring到SLF4J的Bridge,然后使用一个后端实现Log4J,因此在添加一个SLF4J到Log4J的Bridge,最后是Log4J实现,用maven管理的话,结果如下
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.2.2.BUILD-SNAPSHOT</version>
        <exclusions>
            <exclusion>
                <!--排除commons-logging依赖-->
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <!--commons-logging到SLF4J之间的Bridge-->
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.5.8</version>
    </dependency>
<dependency>
        <!--SLF4J接口-->
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.8</version>
    </dependency>
    <dependency>
        <!--SLF4J到Log4J之间的Bridge-->
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.8</version>
    </dependency>
    <dependency>
        <!--Log4J实现-->
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.14</version>
    </dependency>
</dependencies>

这种方式比较复杂,因为在平时工作中没有用过SLF4J日志框架,所以这种方式看起来有些多此一举,但考虑到SLF4J作为事实上的Java Logging标准,如何更加有效的在不同前端Facade Logger接口到后端实现之间自由适配,SLF4J提供了一个很好的形式,如下


 
 
前端到后端的适配能够更加方便,这确实是一个非常有趣的想法。
Jboss logging
    事实上这个日志框架貌似不是很出名,但是基本上Jboss系的产品、框架都会使用这个日志框架,因此,我们也需要好好的学习一下,该日志结构如下


 
这里的也是一种适配器方式,只是最终暴露的使用接口是特定的LoggerProvider,查找特定日志框架的LoggerProvider是由LoggerProviders提供的,代码如下


 
代码显示在LoggerProviders加载时就开始查找特定LoggerProvider,具体查找逻辑如下


 
上面看到的是通过配置文件查找


 
后半部分是根据ClassPath查找。
Jboss logging比较奇特的地方是其提供了一个JBossLogManagerLogger,这个Logger使用的内部Logger为JBoss容器托管日志管理器,这个可以注意一下
 
上面分析了日志框架前端Facade和后端实现如何适配,现在我们选取一个具体的框架来给出一些常见配置,希望能够对大家有用,我们选取的就是Log4J,因为其他框架我使用的频率比较低,二来因为日志框架的概念都类似,熟悉了一个其他的应该也可以快速掌握,下面让我们展开对Log4J的论述。
    Log4J来自于Apache社区,是目前应用最广的一个日志框架,官方提供了两个大的版本,为Log4J 1.x和Log4J 2.x,这两个主版本连官网链接都不一样,看来Log4J 2.x应该针对前一版本问题而重新设计,以至于导致和前一版本的不兼容,但因为Log4J 1.x普及的根深蒂固,很多日志框架没有及时跟上对Log4J 2.x后端的支持,Log4J 2.x彻底替换掉Log4J 1.x还有很长的一段路要走。
    这里我们给出的是Log4J 1.x的版本介绍,关于Log4J 2.x,我们有机会再进行探索;在Log4J的体系里,有三个最重要的概念:Logger、Appender、Layout,Logger即为日志写入入口,Appender定义了将日志时间输出的策略,Layout给出输出的格式,三者的关系如下


 
因为Log4J中有Category的概念,这里我把它看成一个Logger,三者的关系这样看起来比较明显,Logger接收日志记录,Appender接收Logger发来的日志事件,然后根据Layout定义格式进行输出,这里没有什么好讲的,我们开始讲如何配置。
    Log4J 1.x有两种配置方式,一种是Java properties文件,一种是XML,第一种用的比较多一些,这个和Log4J 2.x正好相反,配置文件配置主要配置上面三个对象,配置Logger,然后配置使用哪种具体Appender,然后定义格式,看一个例子,如下:
 
log4j.rootLogger=DEBUG, A1
 
log4j.appender.A1=org.apache.log4j.ConsoleAppender
 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
 
log4j.appender.A1.layout.ConversionPattern=%-4r %-5p [%t] %37c %3x - %m%n
如上,一定要定义的Logger是root Logger,这里构成了一个类似树形结构,顶部节点定义默认行为,子节点可以对行为进行修改定制,这里定义rootLogger使用DEBUG级别,使用A1这个Appender,注意这里的写法:第一个为日志级别,后面可以跟很多个Appender;线面定义了这个具体的Appender A1,我们看到其使用的是ConsoleAppender,后面我们给这个Appender指定Layout,这里的Layout为PatternLayout,这个比较常用,最后一行定义了日志格式,这种格式写法类似于printf那种格式化字符串,里面的占位符构成为"%[格式修饰符]日志含义符号"(中括号里的为可选),格式修饰符比较简单,“-”代表靠左对其,不加就是靠右对其,后面的数字代表了该日志内容部分的最少显示长度,如果有“.”,"."之后为该日志内容最长显示长度,超过长度会进行裁短;后面的日志含义符号如下表
 

符号

意义

c(小写)

输出日志的类别

C(大写)

输出触发日志请求的类的全称

d

输出日志事件的日期时间

F

输出日志请求类文件名

l

输出请求日志调用位置信息

L

输出请求日志代码行号

m

输出应用提供的日志消息

M

输出请求日志方法名

n

输出平台特定的行分隔符

p

输出日志级别

r

输出从程序启动到现在的毫秒数

t

输出生成这个日志事件线程的名字

 
这里在给出一个例子
log4j.rootLogger=DEBUG, A1
 
log4j.appender.A1=org.apache.log4j.ConsoleAppender
 
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) - %m%n
 
log4j.logger.org.apache.log4j.examples=INFO, A2
 
log4j.appender.A2=org.apache.log4j.FileAppender
log4j.appender.A2.File=${user.home}/test
 
#如果test文件存在就先清空它
log4j.appender.A2.Append=false
 
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
log4j.appender.A2.layout.ConversionPattern=%5r %-5p [%t] %c{2} - %m%n
上面的例子稍微复杂一些,这里设定了一个rootLogger,并制定了其日志级别和Appender,后面定义了一个名为org.apache.log4j.examples 的Logger,这个Logger又定义了日志级别和Appender,通过这里的例子可以看出Log4J这种树形的关系具有足够的灵活性。
    关于XML的配置,这里给出一个实例,大家可以根据上面对properties的理解来配置XML,如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
    <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
    </appender>
    <category name="org.apache.log4j.xml">
        <priority value="info" />
    </category>
    <Root>
        <priority value ="debug" />
        <appender-ref ref="STDOUT" />
    </Root>
</log4j:configuration>
这里的category如前面分析结构时所说,可以认为其就是一个Logger,这个结构也比较一目了然,没有什么要讲的,大家可以根据自己的实际需要来调整结构。
这里还有个问题是配置文件命名的问题,默认情况下,如果配置文件命名为log4j.xml或log4j.properties时Log4J会自动加载,如果因为某种原因不能这样命名,那么久需要编码来实现配置的加载了,代码片段如下
String resource =
                "/app/resources/example.properties";
        URL configFileResource =
                InitUsingPropertiesFile.class.getResource(resource);
        PropertyConfigurator.configure(configFileResource);
 
日志框架就写这些吧,希望能对大家有所帮助,对单一常用日志框架的详细解析,有机会在写吧

 

  • 大小: 127.1 KB
  • 大小: 10.4 KB
  • 大小: 9.9 KB
  • 大小: 16.8 KB
  • 大小: 16.1 KB
  • 大小: 2.5 KB
  • 大小: 17.9 KB
  • 大小: 34.8 KB
  • 大小: 14.1 KB
  • 大小: 5.5 KB
  • 大小: 48.9 KB
  • 大小: 26.9 KB
  • 大小: 12.4 KB
分享到:
评论

相关推荐

    JAVA上百实例源码以及开源项目

    Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字  Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象...

    JAVA上百实例源码以及开源项目源代码

    Java波浪文字制作方法及源代码 1个目标文件 摘要:Java源码,初学实例,波浪文字  Java波浪文字,一个利用Java处理字符的实例,可以设置运动方向参数,显示文本的字符数组,高速文本颜色,显示字体的 FontMetrics对象...

    Java思维导图xmind文件+导出图片

    Nginx Location ReWrite 等语法配置及原理分析 Nginx提供https服务 基于Nginx+lua完成访问流量实时上报Kafka的实战 Netty 高性能NIO框架 IO 的基本概念、NIO、AIO、BIO深入分析 NIO的核心设计思想 Netty产生...

    达内java培训目录

    Servlet/JSP Servlet生命周期及Servlet服务器、Tomcat部署配置、JSP语法、自定义标记、JSTL和EL表达式、JSP 新特性、Java Web 设计模式。 透彻理解Servlet核心原理;熟练掌握Servlet API;透彻理解JSP引擎工作原理;...

    auto-log:The auto log tool for java.(java 自动日志输出,基于字节码,兼容 spring)

    自动适配常见的日志框架 支持编程式的调用 支持注解式,完美整合 spring 支持整合 spring-boot 支持慢日志阈值指定,耗时,入参,出参,异常信息等常见属性指定 支持 traceId 特性 支持类级别定义注解 支持自定义...

    [Java]Ibatis Spring Integration Demo

    不知道为啥Spring这家伙为啥在java下有那么高的地位,感觉走到哪里都要用到它,不过无可否认java下Spring本身对于常见的框架都提供了很好的集成。很早以前.net和java程序员互相说自己好,对方不好的时候,看过过一句...

    TLog:轻量级分布式日志标签跟踪框架

    支持常见的log4j,log4j2,logback三大日志框架,并提供自动检测,完成适配 支持dubbo,dubbox,springcloud三大RPC框架 支持日志标签的自定义模板的配置,提供多个系统级埋点标签的选择 支持异步线程的追

    StudentInfoManage2.rar

    在Java编程中,信息管理通常涉及数据的存储、处理和系统的组织。以下是一些Java中信息管理的常见技术和方法: 1. **数据结构和集合类...6. **日志记录**:Java中流行的日志框架(如Log4j、Logback)可以帮助记录程序运

    TLog分布式日志标记追踪器-其他

    支持常见的log4j,log4j2,logback三大日志框架,并提供自动检测,完成适配 支持dubbo,dubbox,springcloud三大RPC框架 支持日志标签的自定义模板的配置,提供多个系统级埋点标签的选择 支持异步线程的追踪,包括...

    logparser:通过Java,Hadoop,Hive,Pig,Flink,Beam,Storm,Drill等轻松解析Apache HTTPD和NGINX访问日志。

    这是一个Logparsing框架,旨在简化和访问日志文件的解析。 基本思想是,您应该能够拥有一个解析器,您可以通过简单地告诉该行写入了哪些配置选项来构造该解析器。 这些配置选项是访问日志行的架构。 因此,我们...

    Java面试宝典2020修订版V1.0.1.doc

    3、什么是TOMCAT,怎样启动停止,配置文件,日志文件的存储。 31 4、解释一下什么是servlet;什么是servlet容器; 32 5、说一说Servlet的生命周期,执行过程? 32 6、实例化servlet有几种方式 32 7、谈谈你对http协议的...

    kumuluzee:轻量级开源框架,用于使用标准Java EE技术开发微服务并将Java EE迁移到云原生架构

    库穆鲁兹 轻量级开源框架,用于使用标准Java / ... KumuluzEE还提供了扩展,用于在云原生架构中开发常见模式,包括配置,日志记录,发现,断路器的容错能力,指标,安全性,事件流等。 KumuluzEE旨在使用标准Java

    《程序天下:J2EE整合详解与典型案例》光盘源码

    1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE容器 1.3.1 容器服务 1.3.2 容器类型 1.4 J2EE核心技术 1.4.1 Servlet 1.4.2 JSP(Java服务页面...

    java web开发无纸化办公管理系统

    系统常见的数据字典配置、系统日志、业务日志、数据库表结构查看、数据库备份、系统参数配置等也在其中,如果还想加什么功能的话,可以自己再加菜单,相加什么就加什么,自己开发代码了。 本项目没有使用什么框架,...

    基于J2EE框架的个人博客系统项目毕业设计论文(源码和论文)

    由于J2EE的开源的框架中提供了MVC模式实现框架Struts、对象关系模型中的Hibernate 的框架及拥有事务管理和依赖注入的Spring。利用现存框架可以更快开发系统。所以选择Java技术作为blog 的开发工具。 为了增加系统的...

    搞定J2EE:STRUTS+SPRING+HIBERNATE整合详解与典型案例 (2)

    1.1.2 J2EE整体框架 1.1.3 从J2EE到JavaEE 1.2 J2EE组件 1.2.1 客户端组件 1.2.2 Web组件 1.2.3 业务逻辑组件 1.3 J2EE容器 1.3.1 容器服务 1.3.2 容器类型 1.4 J2EE核心技术 1.4.1 Servlet 1.4.2 JSP(Java服务页面...

Global site tag (gtag.js) - Google Analytics