login4j 可以把slf4j 日志级别输出到其他服务器吗

IBM Bluemix
点击按钮,开始云上的开发!
developerWorks 社区
针对 JVM 的 CPU 使用及内存占用的性能分析,已经有各种剖析 (Profiling) 工具可供使用。但是如果想要得具体的调用栈,这些工具往往会给应用程序服务器增加大量额外压力。Perf4j 则是通过对自定义监控范围进行日志记录,再经统计分析生成所需性能数据,Perf4j 提供了对常用日志工具的扩展以方便与产品集成,它产生的数据可用于生成可视化的性能图表。在实际部署的生产环境能够以较低的风险及成本实现对业务逻辑级别性能问题的追踪。本文将介绍如何集成 Perf4j 到 Java 应用程序中并生成性能数据。
, 软件工程师,
商涛工作于 IBM 中国软件开发中心,目前从事 IBM Connections 的开发工作.有过 IBM Connections 及 IBM Docs 性能测试分析工作经历. 对 Java EE 平台前端及后台的性能优化感兴趣。
, 软件工程师, IBM
姚黎,在 IBM Connections 产品的测试领域有近两年的工作经验,主要负责产品的博客、书签、日历等功能模块的功能测试,自动化测试,无障碍化测试等工作。在使用 Rational Functional Tester 进行自动化脚本的开发和执行上有近一年的经验。
引言系统日志是应用程序问题诊断及运行维护的重要工具。Logback、Log4j 是常用于 Java 平台的日志记录 API. 目前大部分产品只是将系统重要参数、状态的变化及异常信息通过日志输出。本文将要介绍的 Perf4j 是一款专门用于 Java 服务器端代码计时、记录日志和监控结果的开源工具包。Perf4j 对常用日志工具包进行了扩展,能够将得到的原始性能数据进行统计并发布到可定制的输出源,如控制台、日志文件、JMX 等。Perf4j 提供了多种方式与 Java 代码集成,开发和系统维人员能够灵活地将 Perf4j 的 API 嵌入到各种不同架构的应用程序中。Perf4j 目前依托于开源项目协作平台 Codehaus 进行文档及代码管理,下一步该项目计划迁移到 Github 平台,以便更多的社区及开发人员可以参与到开发及维护中来。Perf4j 欢迎使用者提出新的功能需求并且鼓励将定制或扩展的代码贡献到 Perf4j 源码中。本文中示例代码使用的 Perf4j 版本是 0.9.16,读者需在下载类包或配置 Maven 时留意。阅读文章之前,您要对 Java 注解、JMX、面向方面编程有一些了解。特别是 JConsole 的使用及 Spring AOP 的配置方式要较为熟悉。文章首先阐明在何种应用场景下应优先考虑使用 Perf4j。然后是具体讲解 Pef4j 与应用程序的集成方式。最后会介绍如何将收集的数据生成便于分析的可视化图表。应用场景在 Java 平台上遇到性能问题时,如 CPU 占用过高、系统响应缓慢,通常的分析方法是使用 JVM 剖析工具在系统瓶颈临界点前一段时间抓取 CPU 占用分布,再对 CPU 占用率最高的几个方法排查。Perf4j 的优势在于能够持续跟踪统计所关注功能代码的执行效率,对于前后两个版本出现较大差异的方法进行深入分析,可以在开发周期中尽早发现问题。Perf4j 还可以用在产品环境中,从运营的早期开始,将其统计的数据做为系统的性能和健康指标长期监测。首选 Perf4j 的应用场景:
Java 本地代码调用(JNI)
分布式系统、集群部署
面向服务体系结构(SOA)
远程方法调用(RMI)开发人员必须将本地方法、远程方法及 Web services 的性能问题隔离出来,以防干扰对 Java 应用程序本身的分析。通过日志记录则是最简单的方式;采用分布式架构或集群部署的系统相对复杂,不同的网络环境、基础硬件和操作系统的差异、虚拟主机中资源与配置的差异等造成很难采用统一的工具来监测代码级别的性能指标。而日志记录则可以轻松加入到各种程序中,且是资源与时间成本最低的方式。Perf4j 提供了 CSV 格式的转换工具,开发人员可以借助第三方工具方便地将统计结果汇总分析。集成到应用程序下面将分两种方式具体讲述如何利用 Per4j 提供的 API。在实际的项目中,应根据现有的程序框架及监测目的灵活选择。另外,针对 WebSphere 应用服务器的自有日志系统,还必须采取额外的措施来确保 Perf4j 的正常工作。对代码段计时Perf4j 中 org.perf4j.StopWatch 是整个 API 中的基础工具。这是一个封装良好的计时器。可以把 StopWatch 嵌入到代码中任何地方。这种方式往往使得复杂的方法得到分解,从而有利于精确定位问题的根源。以下通过清单 1 和清单 2 来介绍其具体用法。清单 1.StopWacth 基本用法 public static void basicStopWatch() throws InterruptedException{
// 创建 StopWacth 时开始计时,之后也可以用 stopWatch.start() 重新设定计时开始时间点
StopWatch stopWatch = new StopWatch("TransactionA");
// 执行需要计时的代码
Thread.sleep(2 * 1000L);
String result = stopWatch.stop();
System.out.print(result);
} 清单 1 中最后输出的结果示例:start[6] time[1995] tag[TransactionA]。在构造函数中设定 tag[TransactionA] 用来区分不同的业务逻辑,可以把它看成是性能分析中的事务(Transaction)。 如果需要将多段代码分开统计,可采用 LoggingStopWatch 类的 lap() 方法定义多个事务。清单 2.LoggingStopWatch 用法 public static void loggingStopWacth() throws InterruptedException{
LoggingStopWatch stopWatch = new LoggingStopWatch();
// 设定阈值,小于此阈值的结果将不会被记录下来
stopWatch.setTimeThreshold(1*1000L);
Thread.sleep(2 * 1000L);
// 停止当前计时,开始新的起始时间点
stopWatch.lap("TransactionB");
Thread.sleep(500L);
stopWatch.stop("TransactionC");
} 清单 2 中使用了 LoggingStopWatch 类,其 stop() 方法只是将执行时间数据通过 System.err.println() 输出。若与 Log4j 框架集成,则需要使用 LoggingStopWatch 的子类 Log4JStopWatch, 目前 Perf4j 还支持 Apache Commons Logging、java.util.logginLogback,对应使用 CommonsLogStopWatch、 JavaLogStopWatch、Slf4JStopWatch。 以 Log4j 为例,在 Log4j.xml 中要为 Log4JStopWatch 加入异步输出源 AsyncCoalescingStatisticsAppender。尽量使专用于 Perf4JAppender 的 fileAppender,从而保证记录的性能数据输出到独立的日志文件中。清单 3.Log4j 配置文件 &appender name="Perf4jAppender"
class="org.perf4j.log4j.AsyncCoalescingStatisticsAppender"&
TimeSlice 用来设置聚集分组输出的时间间隔,默认是 30000 ms,
在产品环境中可以适当增大以供减少写文件的次数 --&
&param name="TimeSlice" value="10000" /&
&appender-ref ref="fileAppender" /&
&/appender&
&appender name="fileAppender" class="org.apache.log4j.FileAppender"&
&param name="File" value="perfermanceData.log" /&
&layout class="org.apache.log4j.PatternLayout"&
&param name="ConversionPattern" value="%m%n" /&
&/appender&
Perf4j 默认用名称为 org.perf4j.TimingLogger 的 Logger --&
&logger name="org.perf4j.TimingLogger" additivity="false"&
&level value="INFO" /&
&appender-ref ref="Perf4jAppender" /&
&/logger& 清单 3 中设置了 TimeSlice 为 10 秒, Perf4jAppender 则以 10 秒为采样间隔,统计后按时间分组输出。清单 4 中是一个采样单位的数据。清单 4. 日志输出数据示例 Performance Statistics
21:45:30 -
LogicalBlock1
LogicalBlock2 499.0
1对方法计时 若要避免 Perf4j 与系统的紧耦合,不在程序中加入额外的第三方代码,还可以借助面向方面编程(AOP),通过简单的配置在运行中动态地对指定的方法计时。Perf4j 对常用的 AOP 工具如 AspectJ 及 Spring AOP 均提供了良好支持 . 在此主要介绍下 Per4j 与后者集成的配置方式。首先确保工程中已有如图 1 中的 Jar 包:图 1. 必需引入的 Lib其次在 Spring 的配置文件(一般是 applicationContext.xml 或 spring-config.xml)中加入 &aop:config& 及申明 org.perf4j.log4j.aop.TimingAspect 做为 &aop:aspect&。具体配置参考清单 5:清单 5.Spring AOP 申明 &aop:config&
&aop:aspect id="timing" ref="timingAspect"&
&aop:pointcut id="timingcut"
expression="execution(* cn.test.perf4j.example..*.*(..)) and @annotation(profiled)"/&
&aop:around pointcut-ref="timingcut" method="doPerfLogging"/&
&/aop:aspect&
&/aop:config&
&bean id="timingAspect" class="org.perf4j.log4j.aop.TimingAspect"/&
&!-- 用户自定义任意的业务处理类 --&
&bean id="processService" class="cn.test.perf4j.example.ProcessService" /&其中切入点 &aop:pointcut& 的表达式(expression)中包的作用域可以按实际需求进行修;@annotation(profiled) 会把 @org.perf4j.aop.Profiled 做为参数传给 TimingAspect,在此则不能删除此条件。当然还可以采用 &aop:aspectj-autoproxy/& 替换 &aop:pointcut& 复杂的配置,在 org.perf4j.log4j.aop.TimingAspect 的父类 ProfiledTimingAspect 中已用注解定义过全局的切入点。&aop:config& 具有更大的灵活性,可以任意设置监测的范围,建议产品环境使用。运行时如果遇到如下异常:
“The matching wildcard is strict, but no declaration can be found for element 'aop:config'”说明之前没有设置过 AOP 的命名空间,在 xsi:schemaLocation 最后加相对应版本的 URI 即可。清单 6. 加入 spring-aop-x.x.xsd 的 URI &beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"&现在如果要记录包 cn.test.perf4j.example 下某些方法的执行时间,只需在方法签名加上注解 @Profiled。org.perf4j.aop.Profiled 也提供了细颗粒度的定制。具体属性设置方法如下 :清单 7. 注解 Profiled 设置 /** 1. 默认以方法名做标记 tag 的名称 */
public void doService(){...}
自定义标记 tag 的名称并设定阈值 */
@Profiled(tag=”doTimedService”,timeThreshold =500L )
public void doService(){...}其它支持的属性还有:
boolean el : tag 和 message 的设置是否支持 Java EL 表达式语法;
设定日志级别;
boolean logFailuresSeparately : 若为真,正常和异常抛出的执行时间数据将分开统计;
Sring logger :
log4.xml 中设置的 logger 名称。如果是默认值,则此属性可省去。在产品环境中,不方便重新编译代码,建议使用 ScopedTimingAspect,完全通过配置文件控制监测的范围,不用在方法上加 Profiled 注解。具体用法可以参考 AspectJ 的用法。另外如果系统已采用 EJB3,可以把 org.perf4j.log4j.aop.EjbTimingAspect 做为拦截器加入。具体可以参考有关 EJB3@Interceptors 的用法。在 WebSphere 应用服务器中使用 Perf4jWebSphere 应用服务器默认使用基于 JDK 中 java.util.logging 的日志 API 并且集中管理了整个系统的日志输出。Perf4j 必须单独生成自己的数据文件,以便于分析。如果应用程序要部署到 WebSphere 应用服务器中,如下方法能够帮助我们将 Perf4j 记录的日志独立出来。1. 指定 LogFactory 实现类:
在 &app root&/META-INF/services 目录中创建名为 mons.logging.LogFactory 的文件,在文件中分别设定相对 Log4j 的配置,内容为 mons.logging.impl.Log4j;还有一种方式是在 classpath 下创建 commons-logging.properties 文件,文件内容为:priority=1
mons.logging.LogFactory=mons.logging.impl.LogFactoryImpl
mons.logging.Log=mons.logging.impl.Log4JLogger2. 在 Admin 控制台中,选择 Applications & Enterprise Applications &
''app name'' ,设定 ClassLoader 的模式为 PARENT_LAST。3. 将之前配置的 log4j.xml 同样放在 classpath 下。在 log4j.xml 中只须设定 Perf4jAppender。程序其它调用 java.util.logging 的日志仍由 WebSphere 统一控制。生成可视化数据目前我们已经可以得到 Perf4j 生成的原始数据,不过为了易于分析这些数据,方便直观地将统计结果展现出来才是我们最终需要的。这里介绍的两种方式均是利用 Perf4j 提供的特定 Appender 来发布数据到相应可视化工具。通过 Java 管理扩展接口发布
Java 管理扩展接口(JMX)常用来监控 JVM 的运行状态以及动态管理配置系统。通过 JmxAttributeStatisticsAppender 能将数据封装成标准的 JMX 管理构件的 MBean。配置见清单 8。清单 8. 添加 JMX Appender &appender name="Perf4jAppender"
class="org.perf4j.log4j. AsyncCoalescingStatisticsAppender"&
&appender-ref ref="fileAppender" /&
&appender-ref ref="perf4jJmxAppender"/&
&/appender&
&appender name="perf4jJmxAppender"
class="org.perf4j.log4j.JmxAttributeStatisticsAppender"&
&!-- 设定要发布的事务
&param name="TagNamesToExpose" value="doServiceA,doServiceB"/&
设定阈值 此处为 doServiceA 的最小值超过 200ms 才发布出去。
若设定范围可用区间表示,如 (200-500) --&
&param name="NotificationThresholds" value="doServiceAMin(&200)"/&
&/appender&
JConsole 是 Oracle JDK 自带的的 JMX 监控工具,当然也有很多第三方 JMX 工具可供选择。图 2 是 JConsole 界面的截图,显示了 Perf4j MBean 具体内容及图表。图 2.JConsole 实时显示 Perf4j MBean通过 GraphingServlet 生成统计图 这种方式需要用到 AsyncCoalescingStatisticsAppender,通过其记录的是每个时间片各事务的执行时间统计信息,在此还要加上 GraphingStatisticsAppender,将指定的监测指标数据单独抽出,再由 Perf4j 的 GraphingServlet 展现在页面上。一般可做为子页面加入到系统管理界面中。清单 9 中只是加入了一个用于生成平均执行时间图示的 Appender 做为示例,当然 Perf4j 也允许加入多个 GraphingStatisticsAppender 以同时显示不同指标的数据。清单 9. 加入生成可视化数据的 Appender &appender name="Perf4jAppender"
class="org.perf4j.log4j. AsyncCoalescingStatisticsAppender"&
&appender-ref ref="fileAppender" /&
&appender-ref ref="meanExecutionTime"/&
&/appender&
&appender name="meanExecutionTime"
class="org.perf4j.log4j.GraphingStatisticsAppender"&
&param name="GraphType" value="Mean"/&
&param name="TagNamesToGraph" value="doServiceA,doServiceB"/&
&appender-ref ref="meanTimeFileAppender"/&
&/appender&在 GraphType 中可以设定的性能指标有平均执行时间(Mean)、最长执行时间(Max)、最短执行时间(Min)、执行时间标准差(StdDev)、执行次数(Count)和 每秒事务处理量(TPS)。TagNamesToGraph 是可选项,用来指定需要输出的事务,如果不设定则会输出全部事务。同时在 web.xml 中还要加入 GraphingServlet 的映射。如清单 10。清单 10. 在 web.xml 中配置 GraphingServlet &servlet&
&servlet-name&perf4jMonitor&/servlet-name&
&servlet-class&org.perf4j.log4j.servlet.GraphingServlet&/servlet-class&
&init-param&
&param-name&graphNames&/param-name&
&!-- 此处设置清单 9 中配置的 Appender 名称 --&
&param-value&meanExecutionTime,executionTPS&/param-value&
&/init-param&
&/servlet&
&servlet-mapping&
&servlet-name&perf4jMonitor&/servlet-name&
&url-pattern&/perf4jMonitor&/url-pattern&
&/servlet-mapping&至此在系统的运行过程中,访问 /perf4jMonitor 就可以实时的观测指定事务的性能数据图示。总结本文介绍了配置与使用 Perf4j 的诸多细节。在实际项目中,我们还应该设计一个易扩展的体系结构,使第三方 API 能轻易加入。如果只是用 Perf4j 协助发现性能问题的源头,开发人员可采用临时代码中嵌入 StopWatch 类的方式。若是计划长期对系统性能跟踪,应设计一个完善的日志框架集成方案,能够轻易地将 Perf4j 无缝的加入和脱离尤为重要。尽管 Perf4j 中使用的是异步的输出源,在大量用户并发的性能测试和产品环境下,额外的 CPU 内存占用也是不容忽视的。因此务必确保 Perf4j 只用于对性能跟踪及瓶颈分析,而不要用于对系统负载能力的评估。
主页,获得 Perf4j 工具包及帮助文档。
在 developerWorks 查找 ,深入了解 AOP 应用的资源。:这里有数百篇关于 Java 编程各个方面的文章。
加入 。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
developerWorks: 登录
标有星(*)号的字段是必填字段。
保持登录。
单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件。
在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。
所有提交的信息确保安全。
选择您的昵称
当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。昵称长度在 3 至 31 个字符之间。
您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。
标有星(*)号的字段是必填字段。
(昵称长度在 3 至 31 个字符之间)
单击提交则表示您同意developerWorks 的条款和条件。 .
所有提交的信息确保安全。
文章、教程、演示,帮助您构建、部署和管理云应用。
立即加入来自 IBM 的专业 IT 社交网络。
为灾难恢复构建应用,赢取现金大奖。
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=Java technologyArticleID=846902ArticleTitle=通过日志监控并收集 Java 应用程序性能数据publish-date=作为一个菜鸟来深入学习slf4j框架。
什么是slf4j框架?
The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.
这个是官方的介绍,意思就是slf4j是一个简单的java日志框架facade,facade是门面的意思,相当于一个服务的接口,具体的日志功能由具体的日志(如java的util包中的logging、logback、log4j)框架提供,使用slf4j可以在部署的时候接上想要使用的日志框架。
从这里可以理解,slf4j不提供任何服务,它只是一个facade,相当于一个通用的接口。
使用slf4j需要用到
slf4j-api-1.x.xx.jar
从包名可以看出来这个包是和api有关的,仅仅是api肯定是无法工作的。如果我们想要使用slf4j需要依赖另外的jar包,而这些依赖的jar包称为"SLF4J bindings"。官方原文解释SLF4J bindings:
The SLF4J distribution ships with several jar files referred to as "SLF4J bindings", with each binding corresponding to a supported framework.
按照官方介绍的SLF4J bindings有如下几个:
slf4j-log4j12-1.7.21.jar
& &&slf4j-log4j用于整合log4j,使用非常广泛,使用时需要在依赖里加上log4j的jar包。
slf4j-jdk14-1.7.21.jar
& &&slf4j-jdk用于整合java.util.logging。只要是jdk1.4以上就OK。
slf4j-nop-1.7.21.jar
& &&slf4j-nop提供了一个没有任何实现代码的实现。什么意思呢,我截图slf4j包下的一个方法。
&&&&可以看出来,方法体里面啥都没有。
&&&&slf4j-simple-1.7.21.jar
& & slf4j-simple提供了简单的实现,除了info或者更高级别的日志会print外,全部都打印到System.err上。
slf4j-jcl-1.7.21.jar
& &&slf4j-jcl整合jcl,jcl没听过。。。先无视。
logback-classic-1.0.13.jar
& & 没听过logback。。。无视
从这里可以知道想要使用slf4j不仅仅是slf4j-api这个包就行了,还需要具体的日志框架。比如我之前做过的项目都用log4j,所以我必须有slf4j-log4j这个包和原本的log4j包。
如何使用slf4j?
我猜大部分人在深入了解一个框架前就会用这个框架了。因为如果都没用过根本不会去深入了解。
用slf4j很简单,下面是我在项目里的用法
public class xxx {
public static final Logger logger = LoggerFactory.getLogger(xxx.class);
public void login(){
("ID为{},名为{}的用户登录了服务器!",xx,xx);
在类里面定义一个静态的Logger属性,属性由LoggerFactory的getLogger方法初始化。getLogger方法接收一个class对象,作用是输出时把类名作为日志的前缀。
这里我在用户登录服务器的时候通过logger对象的info方法来输出了一段日志。
需要注意的是slf4j到1.7版本之后才支持可变参数。
如info方法:void info(String var1, Object... var2);
在此之前多参数都是通过数组实现的:void info(String var1, Object[]&var2);
从源码分析slf4j
从使用过程来看,slf4j的核心类很明显是Logger类,但是看了源码会发现Logger类只是一个接口。这个不难理解,因为slf4j只是一个 Facade。
浏览一遍Logger接口,会发现里面的方法有规律,根据规律可以把接口的方法分成5大类
从方法名可以看出来这些方法是日志的5个级别,也就是Logger类是一个提供输出不同级别日志的接口。
Logger类的初始化方式是通过LoggerFactory来创建的。从名字一看就知道这里采用了工厂设计模式。Logger可以是不同的实现,但是创建过程我们不过关心,交给工厂来操作就OK了。
通过LoggerFactory的getLogger(Class&?& clazz)方法可以创建一个Logger &&&&&LoggerFactory.getLogger(xxx.class);
方法内部其实是调用了另外一个重载的方法Logger logger = getLogger(clazz.getName());
也就是使用了类的全限定名来作为参数。
getLogger(String name)方法又调用了getILoggerFactory()方法,这个方法的作用是获得一个Logger工厂。getILoggerFactory方法很关键,它调用了SLF4J bindings的StaticLoggerBinder类。比如我的项目里用了Log4j,这里StaticLoggerBinder会返回一个Log4jLoggerFactory对象。
得到了Log4jLoggerFactory就可以得到Log4j的Logger了吗?也没那么快。因为Log4jLoggerFactory是slf4j-log4j包的类。也就是说,还没有真正调用Log4j。slf4j-log4j相当于只是一个中间件,来协调Log4j和Slf4j。
我们来看看Log4jLoggerFactory的getLogger方法,方法里面调用了LogManager的getLogger方法。LogManager才是log4j的类。从名字可以看出来LogManager是用来管理Logger的类。暂时称它为log管理器吧,log管理器里面也有一个getLogger方法,这里才是真正创建Log4j的Logger的地方。调用了log管理器的getLogger后,Log4jLoggerFactory的getLogger方法就得到了一个Log4j的Logger。
Log4jLoggerFactory得到了Log4j的Logger对象之后会把Logger返回给Slf4j-api嘛?我们看源码,并不是这样。这里使用了一个适配器Log4jLoggerAdapter。看Log4jLoggerAdapter的源码会发现它也实现了Logger接口,所以Log4jLoggerFactory可以直接把适配器返回给Slf4j-api。
Log4jLoggerAdapter是干嘛的呢,适配器嘛,就是为了适应某一个东西,比如这里是为了适配Log4j。也就是说吧Log4j封装,在调用Logger接口的时候能够使用Log4j的实现。
好了下面给大家看一个我自己做的时序图,第一次做,感觉有地方没做好,因为还不熟练,之后的博客会经常给大家画时序图。
& 开源中国(OSChina.NET) |
开源中国社区(OSChina.net)是工信部
指定的官方社区Spring Boot 日志记录 SLF4J
在开发中打印内容,使用 System.out.println() 和 Log4j 应当是人人皆知的方法了。
其实在开发中我们不建议使用 System.out 因为大量的使用 System.out 会增加资源的消耗。
而Log4j 更为灵活在性能上也相比 System.out 要高,我们可以配置输出级别,可以指定多个日志文件分别记录不同的日志。
使用 System.out 是在当前线程执行的,写入文件也是写入完毕后才继续执行下面的程序。而使用Log工具不但可以控制日志是否输出,怎么输出,它的处理机制也是通知写日志,继续执行后面的代码不必等日志写完。
如非必要,建议大家不要使用控制台输出,因为控制台输出没有优先级会显得输出太乱。
个人推荐使用 SLF4J(Simple Logging Facade For )的logback来输出日志,其比log4j 要好,因为他效率更高。
Spring Boot 提供了一套日志,logback是最优先的选择。配置了logback.xml可以利用Spring Boot提供的默认日志配置:
这样就定义了一个 捕获 org.springframework.web 的日志,日志级别是 DEBUG,上面引用的base.xml 文件内容为:
Spring Boot的日志系统预先定义了一些系统变量:
PID,当前进程ID{LOG_FILE},Spring Boot配置文件(application.properties|.yml)中logging.file的值
${LOG_PATH}, Spring Boot配置文件中logging.path的值
同时默认情况下包含另个appender&&一个是控制台,一个是文件,分别定义在console-appender.xml和file-appender.xml中。同时对于应用的日志级别也可以通过application.properties进行定义:
logging.level.org.springframework.web=DEBUG
logging.level.org.springboot.sample=TRACE
这样相当于我们在logback.xml 中配置的对应的日志级别。名称以logging.level开头,后面跟要输入日志的包名。
* 如果在 logback.xml 和 application.properties 中定义了相同的配置(如都配置了 org.springframework.web)但是输出级别不同,则实际上 application.properties 的优先级高于 logback.xml *
我们既然使用了maven来管理项目,我们就可以根据不同环境来定义不同的日志输出,在 logback.xml 中使用 springProfile 节点来定义,方法如下:
如上我们默认为 org.springboot.sample 定义了TRACE级别的输出,下面又定义两个 springProfile ,分别是 dev 和 staging,输出级别分别是 DEBUG 和 INFO
我们可以启动服务的时候指定 profile (如不指定使用默认),如指定staging 的方式为:
java -jar myapp.jar --spring.profiles.active=staging
下面介绍两种常用的Appender
ConsoleAppender
Logback使用appender来定义日志输出,在开发过程中最常用的是将日志输出到控制台:
.%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %n
表示对日志进行编码
%d{HH:mm:ss.SSS}&&日志输出时间 %thread&&输出日志的进程名字,这在Web应用以及异步任务处理中很有用 %-5level&&日志级别,并且使用5个字符靠左对齐 %logger{36}&&日志输出者的名字 %msg&&日志消息 %n&&平台的换行符
在这种格式下一条日志的输出结果如下:
10:12:51.012 [threadName] DEBUG o.c.d.r.util.LoggingResponseFilter
RollingFileAppender
另一种常见的日志输出到文件,随着应用的运行时间越来越长,日志也会增长的越来越多,将他们输出到同一个文件并非一个好办法。RollingFileAppender用于切分文件日志:
/data/log/app.log
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n
其中重要的是rollingPolicy的定义,上例中rest-demo.%d{yyyy-MM-dd}.log定义了日志的切分方式&&把每一天的日志归档到一个文件中,30表示只保留最近30天的日志,以防止日志填满整个磁盘空间。同理,可以使用%d{yyyy-MM-dd_HH-mm}来定义精确到分的日志切分方式。
Sentry是一个统一的日志跟踪平台,在传统的日志管理中,都是在服务器上通过tail, vim等工具查看日志,并且不同的日志位置也个不相同,而Sentry则是将这些日志(主要是错误日志)通过统一的接口收集起来,并且提供跟踪、管理的功能,使得应用程序的错误、Bug能够即时被解决。
Sentry提供了Java库&&Raven Java,Java应用程序能够在捕获异常后将其发送到Sentry服务器中,另一方面它包含了各类日志框架的支持,以Logbakc为例:
net.kencochrane.raven
raven-logback
在logback.xml中定义appender:
https://publicKey:secretKey@host:port/1?options
tag1:value1,tag2:value2
我们推荐在这个中加入用于过滤 ERROR 级别的日志。
在Spring Boot 中记录日志只需两步:
1、在 src/main/resources 下面创建logback.xml 文件,并按上面讲述的进行配置。
或者使用最简单的方法在 application 配置文件中配置。
2、在Java代码中创建实例,并在需要输出日志的地方使用。
// 在Java类中创建 logger 实例
private static final Logger logger = LoggerFactory.getLogger(SpringBootSampleApplication.class);
// 在方法中使用日志输出,如
public void logTest() {
logger.debug(&日志输出测试 Debug&);
logger.trace(&日志输出测试 Trace&);
(&日志输出测试 Info&);
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'

我要回帖

更多关于 logger4j 日志等级 的文章

 

随机推荐