上一篇里,笔者将DAO做了一个通用的实现,不过在继续之前,我们好像忘了些什么。就是做任何程序都不可缺少的东东,一个对程序的功能没什么用,很容被遗忘,但是每个方法里都需要有的东西,那就是日志。
笔者以往的经验都是将Log4j配置到Spring中去用,顺着这一点,访问了下log4j的官网,进而看到了新东东log4j2,粗略地看了一下介绍:比log4j更好的性能,做了些logback的实现甚至还解决了些logback的固有的问题,支持多种facade框架。听起来还不错,于是动了把这玩意儿加到Spring中的想法,到网上去搜娄了一翻后。。。
好吧,我承认东西很少,只能是苦读官方的英文文档加debug状态看源码了。
在log4j2的官网http://logging.apache.org/log4j/2.x/上,瞅一眼左侧的导航栏,大致都点进去看一下:API里说的需要JDK1.5以上,Architecture里的类架构图,以及与log4j的集成或转换等等。这些都不重要,因为目前没有用到,需要时候再来看不迟。我们的重点是Configuration.
进入Configuration页面,细读一下吧。
看到Configuration中所述,配置可以是xml形式,可以是json形式,也可以是编码的方式(Programmatically),我们要的是可以配到前面所写的由Spring@Configuration标注的ApplicationContext.java中的方式,当然就是编码方式,二话不说,直接按其所指,看看ExtendingLog4j
2 里怎么说。一堆诸如@Plugin的注解式配置,大喜。不过整了半天,没奏效。想想即使好用,配置到Spring中也是一件费力的事儿,还是去Debug吧。Log的用法还是这样:
Logger logger = LogManager.getLogger(this.getClass());
顺着这条藤,自是能摸到瓜的。LogManager中有Log4jContextFactory,用来选择生成LoggerContext.我们看到Context这个词,很容易就想到它是要干什么的:一个装载了很多通过名字得到的唯一单例的容器,所说的单例自然是Logger。正因如此,LogManager里的这个LoggerContext可以通过类名将logger一一对应。OK,不废话了,继续:在LoggerContext被实例化时,它有个属性Configuration也被同时实例化,这个实例是DefaultConfiguration类型.实例化后Facotry又将Context启动,调用了LoggerContext.start()方法,该方法会reconfiguraion()。这个reconfiguration()会进行系统下的配置找寻,也就是按照我们看到的官网中AutomaticConfiguration里所写的配置顺序进行找寻。(多一嘴:这里Debug过程中也确认了它在找系统默认ClassLoader中去找被注解所注的配置,而且看到我注解的类确实在ClassLoader里,至于为什么没有被加载,始终搞不明白)。继续Debug会看到最后它什么也没找到又加载一遍DefaultConfiguration。
然后笔者就开动脑筋,用Eclipse的代码提示功能去找用没有public的方法可以将配置重定向了。果不其然,找到了,方法如下:
Logger logger = LogManager.getLogger(this.getClass());
LoggerContext loggerContext =(LoggerContext)LogManager.getContext();
loggerContext.setConfiguration(new BaseConfiguration(){});
找起来很费劲的说,毕竟框架它做为通用性的库,考虑的东西需要很周到,我们目前要用的就只有这么些,直接贴上来为大家理解与使用更方便快捷。至于想更深层次看清它的朋友们,就不扰乱你们在Debug过程中的乐趣了。
上文BaseConfiguration类体中,直接那样匿名实现它就行,至于为什么用它而不用接口Configuration,想来你看了就知道,DefaultConfiguration很简单地写了构造方法继承了它就可以用,而如果匿名实现Configuration接口,会比较繁琐。笔者这样匿名写了个config()方法,直接returnthis
,在类体后面直接.config()调用会简易明了的展现这主要就是在做Configuration。不过试了一下,还是没好用。再去看DefaultConfiguration是如何做到的,如法炮制吧:覆写doConfigure()为空,因为在Configuration.start()后,它会被调用从而加载了很多appender把自己配制的都盖掉了。综上所述,上面代码中的最后一句就变成
loggerContext.setConfiguration(new BaseConfiguration(){
public BaseConfiguration config(){
setName("MyConfig");
Layout<?> layout = PatternLayout.createLayout("%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n",null, null, null);
Appender<?> appender = ConsoleAppender.createAppender(layout, null, "SYSTEM_OUT", "Console", "true");
appender.start();
addAppender(appender);
LoggerConfig root = getRootLogger();
root.addAppender(appender, null, null);
String levelName = System.getProperty("org.apache.logging.log4j.level");
Level level = levelName != null && Level.valueOf(levelName) != null ? Level.valueOf(levelName) : Level.ERROR;
root.setLevel(level);
return this;
}
@Override
protected void doConfigure() {}
}.config());
测试一下,对了,前面一直说某些操作没好用,是如何看出?答案是只需将所写代码的layout的Patten中的一些格式化参数换一下位置看看输出,是否按所配Layout输出来的就可以了。因为上文中的config方法内的代码完全是DefaultConfiguration构造方法中的语句,所以变一下layout如果控制台输出的字符串还是按原来的顺序打出,那它的配置还是DefaultConfiguration.以下四行代码放到普通JUnit4的@Test方法中,可以测试出logger确实是一个类名永远只得到一个实例,并且控制台输出的字符按照自己配置的layout输出来了。证明配置成功。
Logger logger = loggerContext.getLogger(this.getClass().getName());
Logger logger0 = loggerContext.getLogger(this.getClass().getName());
Assert.assertSame(logger,logger0);
logger.error("Test Error2");
下面就是将这个log4j2的配置放到Spring中了,我想看了第一篇的话,这个配置应该是很简单了,在Spring的@Configuration注解的ApplicationContext.java中,写一个@Bean注解的方法,Return出一个LoggerContext即可,这个LoggerContex就可以注入到任意Spring的Bean中以供该Bean作Log用。当然还可以生成个通用的Log
Bean. 那就贴上代码段如下:
@Bean
public LoggerContext log4j2Context() {
LoggerContext loggerCtx = (LoggerContext) LogManager.getContext();
loggerCtx.setConfiguration(new BaseConfiguration() {
public BaseConfiguration config() {
setName("webmodel-log-Config");
Layout<?> consolelayout = PatternLayout.createLayout(
"%d{HH:mm:ss.SSS} [%thread] %logger{36} %-5level - %msg%n",null, null, null);
Appender<?> consoleAppender = ConsoleAppender.createAppender(consolelayout,null, "SYSTEM_OUT", "Console","true");
Layout<?> fileLayout = HTMLLayout.createLayout("true", "Webmodel Error Log", "text/html", null, "x-small", "arial,serif");
String fileName =this.getClass().getResource("/").getFile().replace("/classes/", "/log/")+"systemErrorLog.html";
Appender<?> fileAppender = FileAppender.createAppender(fileName, "true", "false", "errorLog","true","true", "true", fileLayout, null);
this.addAppender(consoleAppender);
this.addAppender(fileAppender);
LoggerConfig root = getRootLogger();
root.setLevel(Level.ALL);
root.addAppender(consoleAppender, Level.ERROR, null);
root.addAppender(fileAppender, Level.INFO, null);
return this;
}
@Override
protected void doConfigure() {}
}.config());
return loggerCtx;
}
@Configuration
static class LoggerConfiguration{
private LoggerContext lctx;
public LoggerContext getLctx() {
return lctx;
}
@Resource
public void setLctx(LoggerContext lctx) {
this.lctx = lctx;
}
@Bean
public Logger commonLogger(){
return lctx.getLogger("com.gxino.webmodel.CommonLogger");
}
}
这段代码的配置较上面有所update,因为想要做一个在控制台只输出Error以上级别的,而保存一个系统日志文件以输出INFO以上级别的日志,所以又做了很多Debug工作。首先一点,Appender不用start(),因为BaseConfiguration.start()时会去做;其次,并不是root.addAppender(appender,appenderLevel,appenderFilter);后,log就能按这个Level去做日志。因为在一个logEvent被响应时,logger会isEnable来判断这个响应奏不奏效,这里面就会根据LoggerConfig即root去判断,然后在logEvent被响应时,才去看每个Appender的具体Level.
而不管是哪里,所有的Level都默认是Level.ERROR,所以我们需要把root的Level调到ALL,让它过了isEnable,再去看具体的Appender的Level.最后,Html的文件日志还是不错嘛。贴个图以结束这一篇内容。
有老手们应该已经发觉,到处充斥着的日志,加起来很繁琐,或说总是忘记去写,有没有方法可以解决?也就是说,在每一个方法的固定位置让它自动写一段日志。那这个固定位置可不可以看成是切面Aspect呢?
OK,下一篇,就引入AOP,面向切面编程。
分享到:
相关推荐
Log4j和Log4j2是两种广泛使用的Java日志框架,它们提供了灵活的日志配置和高性能的日志处理能力。本文将详细介绍如何在SpringBoot项目中配置Log4j和Log4j2。 ### SpringBoot与Log4j Log4j是Apache的一个开源项目,...
本篇文章将深入探讨如何在Spring 5中整合Log4j2日志工具,以实现高效、灵活的日志管理。 首先,我们来理解Spring 5和Log4j2的基本概念。Spring 5是Spring框架的一个主要版本,提供了更强大的功能和性能优化,支持...
标题中的“log4jdbc-log4j2配置简记”指的是在Java开发中使用log4jdbc-log4j2库来监控和记录SQL查询的过程。log4jdbc是一个开源项目,它允许开发者通过日志系统来追踪数据库操作,而log4j2是log4j的升级版,提供了更...
**标题与描述解析** 标题提及的是"log4j-API-最新稳定版本log4j-1.2.17",这表明我们关注的是日志框架...对于使用Log4j的开发者来说,理解和掌握API的各个方面至关重要,以实现有效的日志管理并优化应用程序的监控。
在SpringBoot应用中使用Log4j2,需要在`pom.xml`中添加Log4j2的依赖,并在`application.properties`或`log4j2.xml`/`log4j2.json`文件中进行相应配置。 **Log4j2的配置** 1. **Maven依赖**:在`pom.xml`中添加Log4...
Log4j是Java编程语言中广泛使用的日志记录框架,其设计目标是提供一个灵活、高效且易于配置的日志系统。这个压缩包包含了Log4j的多个版本,具体提到的是"log4j-1.2.4.jar",这是一个较早的版本。Log4j的各个版本在...
Java EE Web Application Primer Building Bullhorn A Messaging App with JSP, Servlets, JavaScript, Bootstrap and Oracle 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 查看此书详细信息请...
常用的日志框架包括 Java.Util.Logging、Log4j、Logback 和 Log4j2。其中,Log4j2 是 Log4j 的一个升级版本,具有更好的性能和可配置性。 SLF4J SLF4J(Simple Logging Facade for Java)是一个抽象层,它允许...
首先,我们来看看标题提及的“Tomcat5.5日志管理log4j包文件”,这涉及到的是在Apache Tomcat 5.5版本中集成和配置开源日志框架log4j,以提升日志记录的效率和灵活性。 log4j是Apache软件基金会的一个项目,提供了...
至于WSAD(WebSphere Application Developer)5.1配置log4j的步骤,可以通过编辑服务器的类加载器配置,将log4j的相关JAR文件添加到服务器的类路径,并确保`log4j.properties`文件在正确的位置。`WSAD5.1配置log4j....
【Java Web信息管理系统详解】 Java Web技术是互联网应用开发中的重要组成部分,主要用于构建动态、交互式的Web应用程序。在这个“java web信息管理系统”项目中,我们可以深入理解Java Web的基础知识及其在实际...
2. **配置Log4j**:在Android项目中,通常将Log4j的配置写入一个XML文件,如log4j2.xml,然后将其放在res/xml目录下。以下是一个基本配置示例: ```xml [%t] %-5level %logger{36} - %msg%n"/> ...
Build a Twitter-like web application called Bullhorn using Java, Oracle, and more Create web applications using Eclipse Design web pages with HTML forms, tables, and more Use SQL along with Java ...
Log4j是Apache组织提供的一款强大的Java日志框架,它提供了灵活的日志配置,允许开发者控制日志信息的输出级别、输出位置以及格式。而Eclipse作为一款流行的Java集成开发环境(IDE),提供了强大的调试功能,使得...
1. **引入Log4j配置**:在项目的`src/main/resources`目录下创建`log4j2.xml`或`log4j2.json`文件,用于定义日志级别、输出位置、格式等。 ```xml [%t] %-5level %logger{36} - %msg%n"/> ...
Apache的Log4J是Java平台上的一个开源日志框架,被广泛用于后台开发中,以提供灵活、高效和可配置的日志记录。Log4J以其简单易用、性能优秀和功能强大而备受开发者喜爱。它提供了多种级别的日志输出,如DEBUG、INFO...
Digital Java EE 7 Web Application Development 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除
Log4j是一款广泛使用的Java日志框架,由Apache软件基金会开发。它允许程序员在应用程序中插入日志语句,以跟踪程序运行时的行为,帮助调试和优化代码。Log4j的核心功能包括定义日志级别(如DEBUG、INFO、WARN、ERROR...
2. **配置log4j**:`log4j`的配置通常通过一个XML或properties文件完成,如`log4j.properties`或`log4j.xml`。在Android中,由于安全和权限限制,直接在设备上创建和读取配置文件可能较为复杂。因此,你可能需要将...