日志组件一:Log4j
log4j是Apache的一个开源项目,陪伴了我们多年,但是现在已经不更新了。官网原文如下:
Log4j 1.x has been widely adopted and used in many applications. However, through the years development on it has slowed down. It has become more difficult to maintain due to its need to be compliant with very old versions of Java and became End of Life in August 2015. Its alternative, SLF4J/Logback made many needed improvements to the framework. So why bother with Log4j 2? Here are a few of the reasons.
一、log4j简介
1、log4j支持.properties或xml这两种文件类型的配置文件。
2、log4j只需要引入一个jar包即可:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
3、.properties配置文件属性
### 设置根logger###
log4j.rootLogger = debug,stdout,D,E ### 输出信息到控制台###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n ### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/log.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
根Logger:log4j.rootLogger = [ level ] , appenderName, appenderName2
level:日志级别,如果级别设置为INFO,则优先级大于等于INFO级别的日志信息将被输出,小于该级别的不会被输出。
appenderName:日志信息输出目的地,可以是控制台,可以是文件。
配置log输出目的地
org.apache.log4j.ConsoleAppender:输出到控制台
org.apache.log4j.FileAppender:文件
org.apache.log4j.DailyRollingFileAppender:每天产生一个文件
org.apache.log4j.RollingFileAppender:文件大小到达指定尺寸时产生一个新文件
选项
Append = false:默认值是true,将日志追加到文件的最后,false是指将新的日志消息覆盖文件原有的内容
Threshold = INFO:指定日志输出的最低层次,这里INFO及以上层次的日志都将被输出
filter.F=org.apache.log4j.varia.LevelRangeFilter:这个是对Threshold的一个补充,如果Threshold配置成DEBUG,则debug.log会记录debug、info、error等所有级别大于debug的日志
这样在通过日志定位问题的时候有点杂乱,我们想debug、info、error的日志分别记录到对应的文件中该怎么办?
filter.F.LevelMin=DEBUG
filter.F.LevelMax=DEBUG
这样就能通过该文件里记录的日志级别(最大和最小的都是debug,则只能记录debug)
layout = org.apache.log4j.PatternLayout:日志信息的输出格式,PatternLayout指可以灵活地指定布局模式
layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}:配置具体的日志格式
%d:输出日志时间点的日期或时间,也可以指定格式,如:%d{yyyy-MM-dd HH:mm:ss}
%c:输出日志信息所属的类目,通常就是所在类的全名
%t:输出产生该日志事件的线程名
%L:输出代码中的行号
%n:输出一个回车换行符
二、 普通的JAVA工程
1、pom.xml
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j只需要引入这一个jar
2、log4j.properties的配置
### 设置根logger###
log4j.rootLogger = debug,stdout,D,E ### 输出信息到控制台###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%d{yyyyMMdd HH:mm:ssSSS\}%-5p]{%m} %l%n ### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = E://logs/debug.log
log4j.appender.D.Append = true
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = [%d{yyyyMMdd HH:mm:ssSSS\}%-5p]{%m} %l%n
log4j.appender.D.filter.F=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.D.filter.F.LevelMin=DEBUG
log4j.appender.D.filter.F.LevelMax=DEBUG ### 输出ERROR 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = [%d{yyyyMMdd HH:mm:ssSSS\}%-5p]{%m} %l%n
log4j.appender.E.filter.F=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.E.filter.F.LevelMin=ERROR
log4j.appender.E.filter.F.LevelMax=ERROR
该配置文件我有意放在src目录下,项目启动的时候能直接查找到。后面会专门介绍log4j配置文件的加载
3、测试类:
package cd.com.log4j; import org.apache.log4j.Logger; public class App
{
private static Logger logger = Logger.getLogger(App.class); public static void main( String[] args )
{
//日志记录
logger.debug("debug: hello log4j");
logger.info("info: hello log4j");
logger.warn("warn: hello log4j");
logger.error("error: hello log4j");
}
}
4、控制台输出:
[20170524 10:38:02401DEBUG]{debug: hello log4j} cd.com.log4j.App.main(App.java:12)
[20170524 10:38:02401INFO ]{info: hello log4j} cd.com.log4j.App.main(App.java:13)
[20170524 10:38:02401WARN ]{warn: hello log4j} cd.com.log4j.App.main(App.java:14)
[20170524 10:38:02401ERROR]{error: hello log4j} cd.com.log4j.App.main(App.java:15)
5、输出的日志文件:
6.日志内容:
通过前面的配置,我们可以将不同级别的日志输出到对应的文件中
三、WEB工程
对于不同的应用服务器(或者web服务器)来说,classloader的层次不尽相同。这里以最简单的tomcat来说,如果你的应用是部署到 tomcat下的,使用log4j配置文件的顺序就是$TOMCAT_HOME/lib/log4j.xml或者log4j.properties;你自己web应用/WEB-INF/classes(或者lib)/log4j.xml
log4j的jar默认就是到src目录下去找log4j.properties 这个配置文件的。但是如果你没有将这个文件放在src下的。这个情况下就需要自己去加载了
我这里的工程是基于SpringMVC模式的
1、pom.xml:导入的还是跟上面一样的jar包
2.需要在web.xml中配置log4j.properties,这样在容器启动的时候可以加载到log4j的配置文件
3、测试类:
package com.cd.mvc.controller; import javax.servlet.ServletRequest; import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import com.cd.mvc.bean.Product; @Controller
public class DemoController implements EnvironmentAware
{
private Environment environment = null;
@Autowired
private Product product;
static Logger logger = Logger.getLogger(DemoController.class); @RequestMapping(value = "index/{id}", method = RequestMethod.GET,params="age=14")
public String index(@PathVariable int id,ServletRequest request,Model model)
{
logger.info("info id =" + id);
logger.warn("warn id =" + id);
logger.error("error id =" + id);
// String age = (String)request.getParameter("age");
// System.out.println(age);
// this.product.sayHello();
// model.addAttribute("title","hello hangzhou");
return "index";
} @Override
public void setEnvironment(Environment environment)
{
this.environment = environment;
}
}
4、使用postman进行访问:
5、控制台打印信息:
这样我们介绍了普通的JAVA工程和web工程两种方式集成log4j,后面一种应该是比较常见的场景:可以自己配置log4j.properties的存放位置,只需要在web.xml中正确引用即可。
四、spring + log4j的Junit测试
由于Junit测试非常方便,也是开发过程中必不可少的一个环节。但是这种整合起来比较复杂,由于spring+log4j的整合,是在web.xml中配置的,如上一个示例所示。在tomcat启动时,spring会主动去加载log4j的配置文件。而Junit测试是不需要启动tomcat的,所以会造成文件找到的报错。
这里提供两种方法:
一、被动查找
1、将配置文件放在src下面,log4j的jar包会默认从src目录下查找:
这里配置文件是放在src/main/resources下的,log4j的jar包会自动到该目录下寻找。
2、Junit测试类:
package com.cd.mvc.controller; import java.io.IOException; import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/spring/springContext.xml")
public class TestLog4j
{
private final static Logger logger = Logger.getLogger(TestLog4j.class); @Test
public void test() throws IOException
{
logger.info("info layout");
logger.warn("warn layout");
logger.error("error layout");
}
}
该测试类中的两个注解都是跟Junit相关的,与log4j无关。这里我们没有手动去加载log4j的配置文件。
3、测试结果:
[20170524 15:57:04030INFO ]{Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]} org.springframework.test.context.support.AbstractTestContextBootstrapper.getDefaultTestExecutionListenerClassNames(AbstractTestContextBootstrapper.java:256)
[20170524 15:57:04038INFO ]{Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]} org.springframework.test.context.support.AbstractTestContextBootstrapper.instantiateListeners(AbstractTestContextBootstrapper.java:204)
[20170524 15:57:04039INFO ]{Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]} org.springframework.test.context.support.AbstractTestContextBootstrapper.instantiateListeners(AbstractTestContextBootstrapper.java:204)
[20170524 15:57:04040INFO ]{Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@79560ca4, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@582138, org.springframework.test.context.support.DirtiesContextTestExecutionListener@19ece3b5]} org.springframework.test.context.support.AbstractTestContextBootstrapper.getTestExecutionListeners(AbstractTestContextBootstrapper.java:182)
[20170524 15:57:04130INFO ]{Loading XML bean definitions from class path resource [META-INF/spring/springContext.xml]} org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(XmlBeanDefinitionReader.java:317)
[20170524 15:57:04236INFO ]{Refreshing org.springframework.context.support.GenericApplicationContext@602f958: startup date [Wed May 24 15:57:04 CST 2017]; root of context hierarchy} org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:582)
[20170524 15:57:04297INFO ]{Loading properties file from file [D:\workspace\SpringMVC\target\classes\META-INF\log4j.properties]} org.springframework.core.io.support.PropertiesLoaderSupport.loadProperties(PropertiesLoaderSupport.java:172)
[20170524 15:57:04335INFO ]{info layout} com.cd.mvc.controller.TestLog4j.test(TestLog4j.java:23)
[20170524 15:57:04336WARN ]{warn layout} com.cd.mvc.controller.TestLog4j.test(TestLog4j.java:24)
[20170524 15:57:04336ERROR]{error layout} com.cd.mvc.controller.TestLog4j.test(TestLog4j.java:25)
[20170524 15:57:04339INFO ]{Closing org.springframework.context.support.GenericApplicationContext@602f958: startup date [Wed May 24 15:57:04 CST 2017]; root of context hierarchy} org.springframework.context.support.AbstractApplicationContext.doClose(AbstractApplicationContext.java:987)
控制台上打印了info以上级别日志,有spring启动过程中的日志,有业务中输出的日志。
二、主动查找
1、Junit测试类:
package com.cd.mvc.controller; import java.io.IOException; import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.Log4jConfigurer; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/spring/springContext.xml")
public class TestLog4j
{
private final static Logger logger = Logger.getLogger(TestLog4j.class); @Test
public void test() throws IOException
{
Log4jConfigurer.initLogging("classpath:META-INF/log4j.properties");
logger.info("info layout");
logger.warn("warn layout");
logger.error("error layout");
}
}
2、这里比示例1多了一行用红色标记的代码,作用就是主动去查找log4j.properties,该配置文件不在默认的src目录下,log4j的jar包无法找到。
3、测试结果:
由于这种方式中配置文件灵活可配置,建议采用这种方式进行单元测试。
日志组件一:Log4j的更多相关文章
- java日志组件介绍(common-logging,log4j,slf4j,logback )
转自:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging是apache提供的一个通用的日志 ...
- java中的日志组件-log4j
1.为什么使用日志组件 Log4J是Apache的一个开放源代码项目,它是一个日志操作包,通过使用Log4J,可以指定日志信息输出的目的地,如控制台.文件.CUI组件.NT的事件记录器:还可以控制每一 ...
- 转:java日志组件介绍(common-logging,log4j,slf4j,logback )
原网址:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging common-logging是 ...
- 【转】java日志组件介绍(common-logging,log4j,slf4j,logback )
common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, comm ...
- Java日志组件2---Log4j(org.apache.log4j.Logger)
如果我们在项目中,需要记录的东西并不多,而且也不需要有太多区分,使用jdk的自带Log完全可以解决问题.但是,在开发的过程中,大多数项目都比较大,为方便找到程序的bug,都是需要系统的记录日志的.这里 ...
- Log4J日志组件
Log4j, log for java, 开源的日志组件! 使用步骤: 1. 下载组件,引入jar文件; log4j-1.2.11.jar 2. 配置 : src/log4j.properties ...
- 关于log4j、jul、jcl、slf4j等等日志组件的理解
日志组件: 我们经常在开发项目的时候,需要打印记录项目过程中的一些日志.那我们经常大概会用到 log4j.jul.jcl.slf4j.simple.nop.logback 等等,那我们就详细介绍下这些 ...
- 你的日志组件记录够清晰嘛?--自己开发日志组件 Logger
现在现成的日志组件实在是太多太多,为什么我还需要自己实现呢????? 需求来源于java的log4j, [07-31 16:40:00:557:WARN : com.game.engine.threa ...
- 快速入门系列--Log4net日志组件
Log4net是阿帕奇基金会的非常流行的开源日志组件,是log4j的.NET移植版本,至今已经有11年的历史,使用方便并且非常稳定,此外很重要的一点是其和很多开源组件能很好的组合在一起工作,例如NHi ...
- Java学习笔记(十九)——Java 日志记录 AND log4j
[前面的话] 学习的进度应该稍微在快一点. Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用.基础性文章,选择性阅读. [结构] java日志对调试,记录运行,问题定位都起到了很重要的 ...
随机推荐
- 基于Spring Security 的JSaaS应用的权限管理
1. 概述 权限管理,一般指根据系统设置的安全规则或者安全策略,用户可以访问而且只能访问自己被授权的资源.资源包括访问的页面,访问的数据等,这在传统的应用系统中比较常见.本文介绍的则是基于Saas系统 ...
- oracle定时执行一个存储过程
首先需要新建存储过程 一 存储过程: create or replace procedure Insertdata is begin INSERT INTO tab_dayta select * fr ...
- android 4.4.3 css hack 写法
最近发现android在4.4.3上面出现很多怪异的现象,现在虽然没有找到原因和解决方案,但是突然间找到一个css hack写法: button{ display:none; width:$rem*4 ...
- ionic打包项目,运行时报错A problem occurred configuring root project 'android'。。。
运行报错的原因是sdk没有下载完整 解决办法: 1,打开sdk manage.分别下载android support repository.Google play services.google re ...
- selenium操作拖拽实现无效果的替代方案
如果碰到这种情况,无论你是直接通过draganddrop()还是分步执行clickandhold(),dragtoelement(),或通过by_offset位移都无法实现元素拖拽.只能物理模拟了 w ...
- 实体类和数据表的映射异常(XXX is not mapping[ ])
在使用SSH框架开发过程,使用hibernate框架提供的工具类实现与数据库数据交互,在执行cmd操作时,如果出现以下异常: org.hibernate.hql.ast.QuerySyntaxExce ...
- Facebook 宣布开源Python重写后的OnlineSchemaChange
本文会简要介绍,OnlineSchemaChange在经历从PHP到Python重写后的改进和变化 文章欢迎转载,但转载时请保留本段文字,并置于文章的顶部 作者:卢钧轶(cenalulu) 本文原文地 ...
- UML总结(对九种图的认识和如何使用Rational Rose 画图)
UML是一种建模语言,是系统建模的标准.我们之所以建模是因为大规模的系统设计时相当复杂的,当系统比较复杂时就会涉及到以下这几个问题: 开发人员如何与用户进行沟通来了解系统的需求? 开发人员之间如何沟通 ...
- Flume总结(1)
一.日志采集:从网络端口接收数据,下沉到logger 文件netcat-logger.conf: # Name the components on this agent #给那三个组件取个名字 a1. ...
- MapControl Application 添加自定义的工具条
现在想用二次开发做一些东西,然后需要自定义的工具条,但是如何向MapControl Application 添加自定义的工具条呢,经过多次试验后,终于找到了相应的方法(左图是添加自定义的工具条之前,右 ...