开发中最常见的事情就是输出程序的各种运行信息,在公司里看到同事各种syso,syse等,随意输出,写的多了,最后就显得杂乱无章了,比如说调试的时候只需要显示提示信息,发布之后就需要只显示严重错误信息。因此从笔记中翻出曾经的一点关日志记录的文章——Log4j。当然现在也有Log4j2了,至于区别下次有时间再写。

log4j详解

 

简介...............................................................................................................................1

安装...............................................................................................................................1

基本概念........................................................................................................................1

公共类 Logger.........................................................................................................2

公共接口 Appender..................................................................................................3

公共抽象类Layout...................................................................................................5

使用外部文件.................................................................................................................9

A、XML方式:.....................................................................................................10

B、文本方式..........................................................................................................13

在代码中使用Log4j.......................................................................................................18

简介

程序开发环境中的日志记录是由嵌入在程序中以输出一些对开发人员有用信息的语句所组成。例如,跟踪语句(trace),结构转储和常见的 System.out.println或printf调试语句。log4j提供分级方法在程序中嵌入日志记录语句。日志信息具有多种输出格式和多个输出级别。

使用一个专门的日志记录包,可以减轻对成千上万的System.out.println语句的维护成本,因为日志记录可以通过配置脚本在运行时得以控制。 log4j维护嵌入在程序代码中的日志记录语句。通过规范日志记录的处理过程,一些人认为应该鼓励更多的使用日志记录并且获得更高程度的效率。

安装

http://logging.apache.org/log4j/2.x/中下载jar,添加的路径中。

基本概念

使用log4j大概涉及3个主要概念:

公共类 Logger

Logger负责处理日志记录的大部分操作。

日志记录器(Logger)是日志处理的核心组件。log4j具有5种正常级别(Level)。日志记录器(Logger)的可用级别Level::

1、static Level  DEBUG

DEBUG Level指出细粒度信息事件对调试应用程序是非常有帮助的。

2、static Level  INFO

INFO level表明消息在粗粒度级别上突出强调应用程序的运行过程。

3、static Level  WARN

WARN level表明会出现潜在错误的情形。

4、static Level  ERROR

ERROR level指出虽然发生错误事件,但仍然不影响系统的继续运行。

5、static Level  FATAL

FATAL level指出每个严重的错误事件将会导致应用程序的退出。

级别顺序:DEBUG< INFO < WARN < ERROR < FATAL(优先级:低->高)

另外,还有两个可用的特别的日志记录级别:

static Level ALL

ALL Level是最低等级的,用于打开所有日志记录。

static Level OFF

OFF Level是最高等级的,用于关闭所有日志记录。

日志记录器(Logger)的行为是分等级的。日志记录器(Logger)将只输出那些级别高于或等于它的级别的信息。如果没有设置日志记录器(Logger)的级别,那么它将会继承最近的祖先的级别(也就是继承父包)。因此,如果在包com.foo.bar中创建一个日志记录器(Logger)并且没有设置级别,那它将会继承在包com.foo中创建的日志记录器(Logger)的级别。如果在com.foo中没有创建日志记录器(Logger)的话,那么在com.foo.bar中创建的日志记录器(Logger)将继承root日志记录器(Logger)的级别,root日志记录器(Logger)经常被实例化而可用,它的级别为DEBUG。

日志记录器的使用:

1、创建一个日志记录器(Logger)的方法:

1、Logger logger = Logger.getRootLogger();

2、Logger logger = Logger.getLogger("MyLogger");

3、static Logger logger = Logger.getLogger(test.class);

2、为日志记录器设置级别:

logger.setLevel((Level)Level.WARN);

可以使用7个级别中的任何一个; Level.DEBUG, Level.INFO, Level.WARN, Level.ERROR,Level.FATAL, Level.ALL and Level.OFF.

公共接口Appender

Appender负责控制日志记录操作的输出。

1、ConsoleAppender:使用用户指定的布局(layout)输出日志事件到System.out或者 System.err。默认的目标是System.out。

2、DailyRollingFileAppender扩展FileAppender,因此多个日志文件可以以一个用户选定的频率进行循环日志记录。

3、FileAppender把日志事件写入一个文件

4、RollingFileAppender扩展FileAppender备份容量达到一定大小的日志文件。

5、WriterAppender根据用户的选择把日志事件写入到Writer或者OutputStream。

6、SMTPAppender当特定的日志事件发生时,一般是指发生错误或者重大错误时,发送一封邮件。

7、SocketAppender给远程日志服务器(通常是网络套接字节点)发送日志事件(LoggingEvent)对象。

8、SocketHubAppender给远程日志服务器群组(通常是网络套接字节点)发送日志事件(LoggingEvent)对象。

9、SyslogAppender给远程异步日志记录的后台精灵程序(daemon)发送消息。

10、TelnetAppender一个专用于向只读网络套接字发送消息的log4j appender。

还可以实现 Appender接口,创建以自己的方式进行日志输出的Appender。

使用方法:

1、使用ConsoleAppender

ConsoleAppender appender = new ConsoleAppender(new PatternLayout());

创建了一个控制台appender,具有一个默认的PatternLayout。它使用了默认的System.out输出。

2、使用FileAppender

FileAppender appender = null;

try {

appender = new FileAppender(new PatternLayout(),"filename");

} catch(Exception e) {}

上面用到的构造函数:

FileAppender(Layout layout, String filename)

实例化一个FileAppender并且打开变量"filename"指定的文件。

另一个有用的构造函数是:

FileAppender(Layout layout, String filename, boolean append)

实例化一个FileAppender并且打开变量"filename"指定的文件。

这个构造函数还可以选择是否对指定的文件进行追加的方式输出。如果没有指定值,那么默认的方式就是追加。

3、使用WriterAppender

WriterAppender appender = null;

try {

appender = new WriterAppender(new PatternLayout(),new FileOutputStream("filename"));

} catch(Exception e) {}

这个WriterAppender使用的构造函数带有PatternLayout和OutputStream参数,在这种情况下, FileOutputStream用于向一个文件输出。当然,它还具有其他可用的构造函数。

公共抽象类Layout

Layout负责格式化Appender的输出。

Appender必须使用一个与之相关联的 Layout,这样它才能知道怎样格式化它的输出。当前,log4j具有四种类型的Layout:

HTMLLayout格式化日志输出为HTML表格。

PatternLayout根据指定的转换模式格式化日志输出,或者如果没有指定任何转换模式,就使用默认的转换模式。

SimpleLayout以一种非常简单的方式格式化日志输出,它打印级别Level,然后跟着一个破折号“-“,最后才是日志消息。

TTCCLayout 包含日志产生的时间、线程、类别等等信息

代码示例1:

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.SimpleLayout;

import org.apache.log4j.FileAppender;

public class simpandfile {

static Logger logger = Logger.getLogger(simpandfile.class);

public static void main(String args[]) {

SimpleLayout layout = new SimpleLayout();

FileAppender appender = null;

try {

appender = new FileAppender(layout,"output1.txt",false);

} catch(Exception e) {}

logger.addAppender(appender);

logger.setLevel((Level) Level.DEBUG);

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

代码示例2:

import java.io.*;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.HTMLLayout;

import org.apache.log4j.WriterAppender;

public class htmlandwrite {

static Logger logger = Logger.getLogger(htmlandwrite.class);

public static void main(String args[]) {

HTMLLayout layout = new HTMLLayout();

WriterAppender appender = null;

try {

FileOutputStream output = newFileOutputStream("output2.html");

appender = new WriterAppender(layout,output);

} catch(Exception e) {}

logger.addAppender(appender);

logger.setLevel((Level) Level.DEBUG);

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

代码示例3:

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.apache.log4j.PatternLayout;

import org.apache.log4j.ConsoleAppender;

public class consandpatt {

static Logger logger = Logger.getLogger(consandpatt.class);

public static void main(String args[]) {

// Note, %n is newline

String pattern = "Milliseconds since program start: %r %n";

pattern += "Classname of caller: %C %n";

pattern += "Date in ISO8601 format: %d{ISO8601} %n";

pattern += "Location of log event: %l %n";

pattern += "Message: %m %n %n";

PatternLayout layout = new PatternLayout(pattern);

ConsoleAppender appender = new ConsoleAppender(layout);

logger.addAppender(appender);

logger.setLevel((Level) Level.DEBUG);

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

使用外部文件

1、Log4j经常与外部日志文件联合使用,这样很多可选项不必硬编码在软件中。使用外部配置文件的优点就是修改可选项不需要重新编译程序。唯一的缺点就是,由于用到io指令,速度稍微有些减慢。

2、Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。

3、日志信息的优先级从高到低有ERROR、WARN、INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。

log4j可以使用3种配置器来初始化:

BasicConfigurator,DOMConfigurator,PropertyConfigurator。

对于一般的javaproject可以不使用上面的语句初始化log4j,log4j会自动在classpath下,找到配置文件并初始化。如果log4j不能自动初始化配置文件,那么就需要用上面的方法进行初始化。

注意:初始化配置文件,最好只在系统启动的时候执行一次,如果执行多次,一是浪费资源,二就是对于老版本的log4j,使用DailyRollingFileAppender时,可能会出现问题。

有两个方法可以用来指定外部配置文件:文本文件或者XML文件。

A、XML方式:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">

<layout class="org.apache.log4j.SimpleLayout"/>

</appender>

<root>

<priority value ="debug" />

<appender-ref ref="ConsoleAppender"/>

</root>

</log4j:configuration>

文件以标准的XML声明作为开始,后面跟着指出DTD(文档类型定义)的DOCTYPE声明,它定义了XML文件的结构,例如,什么元素可以嵌入在其他元素中等等。接着看看封装所有元素的 log4j:configuration元素,它在DOCTYPE声明中被指定为根元素。嵌入在根元素中有两个结构:

<appender name="ConsoleAppender" class="org.apache.log4j.ConsoleAppender">

<layout class="org.apache.log4j.SimpleLayout"/>

</appender>

这里创建一个名叫"ConsoleAppender"的Appender,注意,你可以选择任何名字,该示例之所以选择"ConsoleAppender",完全是为了示例的设计。接着这个appender类以全名形式给出,经常用规范(fullyqualified)类名。Appender必须具有一个指定的nameclass。嵌入在Appender之内的是layout元素,这里它被指定为SimpleLayout。Layout 必须具有一个class属性。

<root>

<priority value ="debug" />

<appender-ref ref="ConsoleAppender"/>

</root>

root元素必须存在且不能被子类化。示例中的优先级被设置为"debug",设置appender饱含一个appender-ref元素。还有更多的属性或元素可以指定。可以用下面这种方法把配置信息文件读入到Java程序中:

DOMConfigurator.configure("configurationfile.xml");

DOMConfigurator用一棵DOM树来初始化log4j环境。这里是示例中的XML配置文件:

示例1:

import org.apache.log4j.Logger;

import org.apache.log4j.xml.DOMConfigurator;

public class externalxmltest {

static Logger logger = Logger.getLogger(filetest.class);

public static void main(String args[]) {

DOMConfigurator.configure("xmllog4jconfig.xml");

logger.debug("Here is some DEBUG");

logger.info("Here is some INFO");

logger.warn("Here is some WARN");

logger.error("Here is some ERROR");

logger.fatal("Here is some FATAL");

}

}

这里是一个实现带有PatternLayoutFileAppender的日志记录器Logger的XML配置文件:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="appender" class="org.apache.log4j.FileAppender">

<param name="File" value="Indentify-Log.txt"/>

<param name="Append" value="false"/>

<layout class="org.apache.log4j.PatternLayout">

<param name="ConversionPattern" value="%d [%t] %p - %m%n"/>

</layout>

</appender>

<root>

<priority value ="debug"/>

<appender-ref ref="appender"/>

</root>

</log4j:configuration>

B、文本方式

  1.配置根Logger,其语法为:

  log4j.rootLogger= [ level ] , appenderName, appenderName, …

  其中,level是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指B日志信息输出到哪个地方。您可以同时指定多个输出目的地。

  2.配置日志信息输出目的地Appender,其语法为:

  log4j.appender.appenderName= fully.qualified.name.of.appender.class

  log4j.appender.appenderName.option1= value1

  …

  log4j.appender.appenderName.option= valueN

  其中,Log4j提供的appender有以下几种:

  org.apache.log4j.ConsoleAppender(控制台),

  org.apache.log4j.FileAppender(文件),

  org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件),

  org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件),

  org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

  3.配置日志信息的格式(布局),其语法为:

  log4j.appender.appenderName.layout= fully.qualified.name.of.layout.class

  log4j.appender.appenderName.layout.option1= value1

  …

  log4j.appender.appenderName.layout.option= valueN

  其中,Log4j提供的layout有以e几种:

  org.apache.log4j.HTMLLayout(以HTML表格形式布局),

  org.apache.log4j.PatternLayout(可以灵活地指定布局模式),

  org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串),

org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

  Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: %m 输出代码中指定的消息

  %p输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL

  %r输出自应用启动到输出该log信息耗费的毫秒数

  %c输出所属的类目,通常就是所在类的全名

  %t输出产生该日志事件的线程名

  %n输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”

  %d输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyyMMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921

%l输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)

示例1:

import org.apache.log4j.Logger;

publicclass Test {

static Loggerlog= Logger.getLogger(Test.class);

publicvoid log(){

log.debug("Debug info.");

log.info("Info info");

log.warn("Warn info");

log.error("Error info");

log.fatal("Fatal info");

}

publicstaticvoid main(String[] args) {

Test test =new Test();

test.log();

}

}

Log4j.properties

log4j.rootLogger=info, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

# Pattern to output the caller's file name and line number.

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n

结果

INFO [main] (Test.java:16) - Info info

WARN [main] (Test.java:17) - Warn info

ERROR [main] (Test.java:18) - Error info

FATAL [main] (Test.java:19) - Fatal info

示例2:

log4j.rootLogger=info, stdout, log, errorlog

log4j.Logger=search,Test

###Console ###

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{ABSOLUTE} [ %t ] [ %p ]:%L - %m%n

### Log ###

log4j.appender.log =org.apache.log4j.DailyRollingFileAppender

log4j.appender.log.File = log/log.log

log4j.appender.log.Append = true

log4j.appender.log.Threshold = INFO

log4j.appender.log.DatePattern='.'yyyy-MM-dd

log4j.appender.log.layout = org.apache.log4j.PatternLayout

log4j.appender.log.layout.ConversionPattern =%-d{yyyy-MM-dd HH:mm:ss} [ %t ] %m%n

### Error ###

log4j.appender.errorlog = org.apache.log4j.DailyRollingFileAppender

log4j.appender.errorlog.File = log/errorlog.log

log4j.appender.errorlog.Append = true

log4j.appender.errorlog.Threshold = ERROR

log4j.appender.errorlog.DatePattern='.'yyyy-MM-dd

log4j.appender.errorlog.layout = org.apache.log4j.PatternLayout

log4j.appender.errorlog.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss} [ %t ] %m%n

 

import org.apache.log4j.Logger;

 

public class TestLog4J {

    public static voidmain(String[] args) {

       Logger logger =Logger.getLogger(TestLog4J.class);

       logger.info("刘冬冬");

       logger.error("很好");

    }

 

}

 在代码中使用Log4j

  1.得到记录器

  使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:

  publicstatic Logger getLogger( String name)

  通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:

  staticLogger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )

  2.读取配置文件

  当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:

  BasicConfigurator.configure():自动快速地使用缺省Log4j环境。

  PropertyConfigurator.configure( String configFilename):读取使用Java的特性文件编写的配置文件。

  DOMConfigurator.configure( String filename ):读取XML形式的配置文件。

  3.插入记录信息(格式化日志信息)

  当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:

  Logger.debug( Object message ) ;

  Logger.info( Object message ) ;

  Logger.warn( Object message ) ;

  Logger.error( Object message ) ;

于log4j文字,忘了是从哪里来的,特此记录一下。

简洁易用的日志模块——log4j相关推荐

  1. java log4j logback jcl_知识总结-Java日志框架Log4j、Log4j2、logback、slf4j、简介

    功能简介 上一篇介绍了为什么打印日志.什么时候打印日志以及怎么打印日志.本篇介绍下在项目开发中常见的日志组件以及关系. 先看一张图 接口:将所有日志实现适配到了一起,用统一的接口调用. 实现:目前主流 ...

  2. python日志模块_Python之日志处理(logging模块)

    转载自:https://www.cnblogs.com/yyds/p/6901864.html 本节内容 日志相关概念 logging模块简介 使用logging提供的模块级别的函数记录日志 logg ...

  3. Mybatis源码日志模块分析

    看源码需要先下载源码,可以去Mybatis的github上的仓库进行下载,Mybatis 这次就先整理一下日志这一块的源码分析,这块相对来说比较简单而且这个模块是Mybatis的基础模块. 之前的文章 ...

  4. python日志_python 日志模块

    之前项目中用的是工具组做的日志模块,用的久了,脑袋里就懒得思考这是如何实现的.毕竟菊厂的开发,忙成狗,不是我所负责的自然只是看看会用就行了.最近开始奋发图强,自然要好好看下基础的东西. 以前做java ...

  5. python logging日志分割_python logging日志模块以及多进程日志

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 1. logging日志模块介绍 python ...

  6. python logging日志模块以及多进程日志

    本篇文章主要对 python logging 的介绍加深理解.更主要是 讨论在多进程环境下如何使用logging 来输出日志, 如何安全地切分日志文件. 原出处博客 1. logging日志模块介绍 ...

  7. log4j 打印线程号配置_日志配置log4j 打印线程号

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 # Set root logger level to WARN and a ...

  8. Life——一个简洁易用的强化学习库,基于pytorch

    简介 Life是一个基于pytorch实现的强化学习库,实现了多种强化学习算法. 项目地址:https://github.com/HanggeAi/Life 目前包含的强化学习算法 Sarsa mul ...

  9. 了解:一款造福商家的收银软件来啦!2009年至今,致力服务店主10+年,已有 10,000+ 用户共同选择;简洁易用、安全稳定、服务周到、正版软件!轻便好用,让业绩飞起来新一代收银

    了解:一款造福商家的收银软件来啦! 2009年至今,致力服务店主10+年,已有 10,000+ 用户共同选择:简洁易用.安全稳定.服务周到.正版软件! 轻便好用,让业绩飞起来 新一代收银系统 全面支持 ...

  10. 极简系列|日志模块-clog

    日志作为应用程序调试和维护的基本手段被广泛使用,像是谷歌的glog,java领域的log4j,它们都是功能强大的大型日志中间件.可是,在特殊的领域,比如是嵌入式开发领域,由于资源的限制,可能不能直接应 ...

最新文章

  1. 判断出栈顺序是否正确(栈的压入、弹出序列)
  2. 递归调用(Java)
  3. 在windows XP运行3660路由器仿真器
  4. axios  一些用法总结
  5. Java Web servletRequest
  6. 《DSP using MATLAB》示例Example7.20
  7. 【Win10 应用开发】自定义应用标题栏
  8. 主动给团队或用户安装Teams App
  9. linux系统如何用root用户登陆,Linux用root账号创建一个新的登录账号的方法
  10. 完成简单的四则运算(包含小括号)(栈)
  11. pytorch gather_GCN的简单实现(pytorch)
  12. 2016年6月 之 《设计模式》
  13. 使用fastJson把对象转字符串首字母大小写问题的解决
  14. 百度秋招笔试题 原生js按键九宫格
  15. Rose出现 “relation from A to B would cause an Invalid circular inheritance解决方法。
  16. 商业谈判在中国:西方人的见解
  17. 智力题及答案(包含梅氏砝码问题)
  18. 【2012.10.13 上周工作总结】
  19. 【CSS3】边角 border-radius
  20. 线性代数中的矩阵运算P(A,E)是什么意思?

热门文章

  1. LTE相关协议2——下行峰值速率计算
  2. 序列化(Serialization)
  3. 恭贺除夕,没什么才艺展示,就给大家画新年四格小漫画吧 >⌒<
  4. 手机重装android系统,安卓手机系统怎么重装(刷机)
  5. 北京的程序猿们,今年过年去哪玩?
  6. python 经典图书排行榜_知乎必读书单排行榜
  7. Win10彻底永久关闭自动更新的四种方法介绍
  8. Tornado @tornado.gen.coroutine 与 yield
  9. 苹果新机爆裂,德赛和欣旺达却成了关注焦点
  10. rockchip mpp编码开发