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的更多相关文章

  1. java日志组件介绍(common-logging,log4j,slf4j,logback )

    转自:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging是apache提供的一个通用的日志 ...

  2. java中的日志组件-log4j

    1.为什么使用日志组件 Log4J是Apache的一个开放源代码项目,它是一个日志操作包,通过使用Log4J,可以指定日志信息输出的目的地,如控制台.文件.CUI组件.NT的事件记录器:还可以控制每一 ...

  3. 转:java日志组件介绍(common-logging,log4j,slf4j,logback )

    原网址:http://www.blogjava.net/daiyongzhi/archive/2014/04/13/412364.html common-logging common-logging是 ...

  4. 【转】java日志组件介绍(common-logging,log4j,slf4j,logback )

    common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的logging, comm ...

  5. Java日志组件2---Log4j(org.apache.log4j.Logger)

    如果我们在项目中,需要记录的东西并不多,而且也不需要有太多区分,使用jdk的自带Log完全可以解决问题.但是,在开发的过程中,大多数项目都比较大,为方便找到程序的bug,都是需要系统的记录日志的.这里 ...

  6. Log4J日志组件

    Log4j,  log for java, 开源的日志组件! 使用步骤: 1. 下载组件,引入jar文件; log4j-1.2.11.jar 2. 配置 :  src/log4j.properties ...

  7. 关于log4j、jul、jcl、slf4j等等日志组件的理解

    日志组件: 我们经常在开发项目的时候,需要打印记录项目过程中的一些日志.那我们经常大概会用到 log4j.jul.jcl.slf4j.simple.nop.logback 等等,那我们就详细介绍下这些 ...

  8. 你的日志组件记录够清晰嘛?--自己开发日志组件 Logger

    现在现成的日志组件实在是太多太多,为什么我还需要自己实现呢????? 需求来源于java的log4j, [07-31 16:40:00:557:WARN : com.game.engine.threa ...

  9. 快速入门系列--Log4net日志组件

    Log4net是阿帕奇基金会的非常流行的开源日志组件,是log4j的.NET移植版本,至今已经有11年的历史,使用方便并且非常稳定,此外很重要的一点是其和很多开源组件能很好的组合在一起工作,例如NHi ...

  10. Java学习笔记(十九)——Java 日志记录 AND log4j

    [前面的话] 学习的进度应该稍微在快一点. Java日志到了必须学习怎么使用的时候了,因为在项目中要进行使用.基础性文章,选择性阅读. [结构] java日志对调试,记录运行,问题定位都起到了很重要的 ...

随机推荐

  1. [Linux] PHP程序员玩转Linux系列-Nginx中的HTTPS

    1.PHP程序员玩转Linux系列-怎么安装使用CentOS 2.PHP程序员玩转Linux系列-lnmp环境的搭建 3.PHP程序员玩转Linux系列-搭建FTP代码开发环境 4.PHP程序员玩转L ...

  2. Win10《芒果TV》商店版更新v3.4.0:率先支持创意者画中画,工作娱乐两不误

    在Win10创新者更新中,微软为Windows10 PC系统添加了UWP应用窗口置顶功能(亦称画中画功能),Win10版<芒果TV>更新v3.4.0,率先宣布支持画中画新特性,为广大用户带 ...

  3. Hibernate基础学习(五)—对象-关系映射(下)

    一.单向n-1 单向n-1关联只需从n的一端可以访问1的一端. 域模型: 从Order到Customer的多对一单向关联.Order类中定义一个Customer属性,而在Customer类不用存放Or ...

  4. 用 js 的 selection range 操作选择区域内容和图片

    原创文章,转载请注明出处并保留地址.原文地址:http://www.cnblogs.com/muge10/p/6723894.html 最近在做编辑器相关的东西,遇到一个需求,用户在编辑器中插入或者粘 ...

  5. java多线程基本概述(三)——同步块

    1.1.synchronized方法的弊端 package commonutils; public class CommonUtils { public static long beginTime1; ...

  6. struts2 之 struts2数据处理

    开门见山,struts2的数据处理总结: 1. 在servlet中,如果要获取页面提交的数据要使用requerst.getParameter方法来获取,并且每次需要进行相关的类型转换工作,数据的获取及 ...

  7. Reids详解-抄本

    1.redis是什么 Redis 是一个基于内存的高性能key-value数据库.是一个开源的.使用C语言编写的.支持网络交互的.可基于内存也可持久化的Key-Value数据库. 2.redis的特点 ...

  8. css系列:input的placeholder在safari下设置行高失效

    在项目中遇到input的placeholder在safari下设置行高失效的问题,问度娘后未得治原因,倒是有解决办法: 方法一:使用padding使提示文字居中,如果font-size:14px,UI ...

  9. xLua中导出Dotween

    前言 在xlua的lua脚本中使用dotween,官方的文档中有提到可以导出,但未介绍详细的步骤,相信比较多的朋友有需要,刚好项目中也在使用xlua和dotween,所以做个笔记. 基础知识: xLu ...

  10. Python 三级菜单与优化(一层循环嵌套)

    优化的思路是使用单层循环嵌套完成三级菜单,这个优化思路我非常喜欢,我喜欢在编程的时候用最少的东西写出同样的效果,通常这样会绕来绕去,但非常有趣!!! 需求: 1.运行程序输出第一级菜单: 2.选择一级 ...