log4j

简介

  • 是什么?

    Apache的一个开源的、轻量级的、用于日志管理的框架
  • 有什么?

    Log4j由三个重要的组件构成:日志信息的输出格式,日志信息的优先

    级,日志信息的输出目的地。

    1,日志信息的优先级用来指定这条日志信息的重要程度;

    2,日志信息的输出目的地指定了日志将打印到控制台还是文件中(或其它组件中);

    3,输出格式则控制了日志信息的显示内容 。
  • 能干什么?

    主要用来进行日志记录的管理,包括对日志输出的目的地,输出的信息级别和输出的格式等。

    日志级别

OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,可以控制到应用程序中相应级别的日志信息的开关。

几个重要规则

1:级别的控制,就是只要大于等于指定的控制级别,就可以输出

2:如果有多个logger,都可以匹配输出,则每个logger都产生输出,其中根logger匹配所有的输出;而级别控制来源于路径最详细的logger。

输出源

Log4j允许日志请求被输出到多个输出源。用Log4j的话说,一个输出源被称做一个Appender 。一个logger可以设置超过一个的appender。

常见Appender

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

org.apache.log4j.FileAppender(文件)

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

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

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

org.apache.log4j.jdbc.JDBCAppender(把日志用JDBC记录到数据库中)

布局

布局就是指输出信息的格式。在Log4j中称作Layout

常见Layout

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

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

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

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

常用的PatternLayout

%m 输出代码中指定的消息

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

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

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

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

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

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

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

配置示例

配置

Log4j有两种配置方式,一种是xml格式,一种是properties格式。都是放置到classpath下面。默认名称分别是:log4j.xml和log4j.properties

1,properties配置方式

# non-root loggers
# log4j.rootLogger = debug,ydc.File,ydc.Console
# 这是一个输出目的地,目的地是按天卷动的文件
# key都是可以用.分开的
# 【log4j都是给log4j用的】.【appneder【目的地】/logger【控制单元】本质】
# appender【变量名】.【给这个变量的setter】
# Appender javass.File = new org.apache.log4j.DailyRollingFileAppender();
log4j.appender.javass.File=org.apache.log4j.DailyRollingFileAppender
# javass.File.setFile("palmpay.log")
log4j.appender.javass.File.file=javass.log
# javass.File.setDatePattern(".yyyy-MM-dd")
log4j.appender.javass.File.DatePattern=.yyyy-MM-dd
# Layout layout = new org.apache.log4j.PatternLayout();
# javass.File.setLayout(layout);
log4j.appender.javass.File.layout=org.apache.log4j.PatternLayout
# layout.setConversionPattern("%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n");
log4j.appender.javass.File.layout.ConversionPattern=%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n
#输出的目的地,输出到哪儿,Daily【按天】Rolling【滚动】File【文件】Appender【目的地】
#今天的日志打印到palmpay.log
#以前天的日志,各自打印到对应的天数的文件里
#日志输出的信息,【%m%n代表信息本身】【%d{HH:mm:ss,SSS} %5p (%C{1}:%M) -附加在信息之前的其他东西】%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n
#【%d{HH:mm:ss,SSS}【时间】 %5p【级别】 (%C{1}:%M)【类、方法】】
log4j.appender.javass.Console=org.apache.log4j.ConsoleAppender
log4j.appender.javass.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.javass.Console.layout.ConversionPattern=%d{HH:mm:ss,SSS} %5p (%C:%M) - %m%n
#目的地和格式之间的关系了,每个目的地各自制定各自的格式 #logger,是控制日志输出的最小单元
# key的剩余部分,是个包名,管理它和它的子包下的所有类
# value的部分 = 一个级别和对多个目的地的引用【拿,分开】 #log4j.rootLogger = debug,javass.File,javass.Console
log4j.logger.cn.javass=warn,javass.Console,javass.File
#log4j.logger.cn.javass.dao=info,javass.File,javass.Console
#log4j.logger.org.apache.struts2=error,javass.File,javass.Console
#log4j.logger.com.opensymphony.xwork2=error,javass.File,javass.Console
#log4j.logger.org.springframework=ERROR,ydc.File,ydc.Console
#log4j.logger.org.hibernate=ERROR,ydc.File,ydc.Console

2,xml配置方式

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<!-- in java cmd add -Dlog4j.configuration=logging.xml -->
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="log.console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n" />
</layout>
</appender> <appender name="log.file" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="javass.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %5p (%C{1}:%M) - %m%n" />
</layout>
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="info" />
<param name="levelMax" value="info" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender> <logger name="cn.javass" additivity="false">
<level value="debug" />
<appender-ref ref="log.console" />
<appender-ref ref="log.file" />
</logger> <logger name="cn.javass.dao" additivity="false">
<level value="info" />
<appender-ref ref="log.console" />
<appender-ref ref="log.file" />
</logger> <!--
<root>
<level value="debug" />
<appender-ref ref="log.console" />
<appender-ref ref="log.file" />
</root>
--> </log4j:configuration>

3,java使用示例

/**
* 1、如何取logger
* 这个logger可以被几个log4j.logger管理
* 2、用什么样的级别打印
* @author Administrator
*
*/
public class Test1 { //用类对象来取得logger,就相当于是用全类名
private static final Logger logger = Logger.getLogger(Test1.class); public static void main(String[] args) { logger.debug("debug");
logger.info("info");
logger.warn("warn");
logger.error("error"); } }
public class Test2 {
/**
* Logger for this class
*/
private static final Logger logger = Logger.getLogger(Test2.class); private static void test1(int x){
if (logger.isDebugEnabled()) {
logger.debug("test1(int) - start");
} String xx = "y";
if (logger.isInfoEnabled()) {
logger.info("test1(int) - String xx=" + xx);
} if (logger.isDebugEnabled()) {
logger.debug("test1(int) - end");
}
} /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub } }

4,自己项目中使用的方式

log4j.properties

#
log4j.rootLogger=INFO, console log4j.category.com.means=all #
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Encoding=UTF-8
log4j.appender.stdout.ImmediateFlush=true
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%d{yyyy-MM-dd HH/:mm/:ss}]%-5p %c(line/:%L) %x-%m%n #
log4j.appender.f =org.apache.log4j.FileAppender
log4j.appender.f.File=/HYAQ_APP_LOG.log
log4j.appender.f.Append=true
log4j.appender.f.layout=org.apache.log4j.PatternLayout
log4j.appender.f.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss,SSS}[%C]-[%p] %m%n log4j.appender.rolling_file=org.apache.log4j.RollingFileAppender
log4j.appender.rolling_file.File=log/hyaq_rolling.log
log4j.appender.rolling_file.Append=true
log4j.appender.rolling_file.MaxFileSize=1000KB
log4j.appender.rolling_file.MaxBackupIndex=100
log4j.appender.rolling_file.layout=org.apache.log4j.PatternLayout
log4j.appender.rolling_file.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss,SSS}[%C]-[%p] %m%n # config about ibatis
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG #log4j
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{ISO8601} - %p - %m%n
public class TxxDAOImpl extends SqlMapClientDaoSupport implements TxxDAO {
static Logger log = Logger.getLogger(TxxDAOImpl.class);
public TxxDAOImpl() {
super();
}
public boolean insert(Txx record) { boolean bFlag = false;
try{
getSqlMapClientTemplate().insert("XX_XXY.insert", record);
bFlag = true;
}catch(Exception e) {
log.error("TPermitDAOImpl新增***增发申请信息方法异常");
log.error("异常信息:" + e.getMessage());
}
return bFlag;
}
}

Appender、Layout、Logger三者之间的关系

每个Appender都要引用自己的Layout。

每个Logger都可以指定一个级别,同时引用多个Appender;而一个Appender也同时可以被多个Logger引用。

xml vs properties

首先要注意,log4j.xml优先于log4j.properties,如果同时存在log4j.xml和log4j.properites,以log4j.xml为准。

在log4j.properties里,控制级别的时候,只能打印出大于指定级别的所有信息;但是在log4j.xml中可以通过filter来完成过滤:典型的引用是只打印出某种级别的信息。

<appender name="log.file"
class="org.apache.log4j.DailyRollingFileAppender">
<filter class="org.apache.log4j.varia.LevelRangeFilter">
<param name="levelMin" value="info" />
<param name="levelMax" value="info" />
<param name="AcceptOnMatch" value="true" />
</filter>
</appender>
\

可以通过logger的additivity=“false”属性,来设置多个logger是否重复输出同一条信息

<logger name="cn.javass1" additivity="false">
<level value="debug" />
<appender-ref ref="log.console" />
<appender-ref ref="log.file" />
</logger>

看似奇怪的重复级别判断:我们在看一些成熟框架的源代码中,经常看到如下代码:

if (logger.isDebugEnabled()){
logger.debug(“debug:“+name);
}

为什么不是直接logger.debug(“debug:“+name);呢?

在配置文件中虽然可以使用控制级别为比debug级别更高的级别,而不输出debug信息;但是,这里的字符串连接操作仍然会影响运行效率;如果先判断当前logger的级别,如果级别不合适的话,连这句字符串连接都可以不做了。

在java中使用log4j时,我们可以使用它的eclipse插件log4e。它的官方网址是:http://log4e.jayefem.de/,分为商业版本和免费版本。我们只需要使用其免费版本,就可以极大的帮我们提高开发效率。比如:在一个类中声明一个logger;帮我们写麻烦的logger.isDebugEnabled();在一个方法开始的时候打印所有的参数;输出一个变量等等。

使用classpath下的logging.properties

如果想使用自定义的logging.properties,只需要保证这段代码运行在getLogger之前即可:

ClassLoader classLoader =
Thread.currentThread().getContextClassLoader();
InputStream inputStream =
classLoader.getResourceAsStream("logging.properties");
if (inputStream != null) {
try {
LogManager.getLogManager().readConfiguration(inputStream);
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

最新文章

  1. centos6.5和centos7如何搭建php环境
  2. 理清Java中的编码解码转换
  3. MyEclipse 10, 2013, 2014 破解、注册码
  4. tomcat结合nginx使用小结
  5. tkinter 的两个例子
  6. c++ bind1st 和 bind2nd的用法
  7. Asp.Net MVC Control向View传值
  8. 2016 ACM/ICPC Asia Regional Qingdao Online HDU5889
  9. php safe mode bypass all &lt;转&gt;
  10. bootstrap适配移动端
  11. 文件上传利器JQuery上传插件Uploadify
  12. 【JMeter】JMeter使用plugins插件进行服务器性能监控
  13. c - 给分数分级别
  14. ubuntu12.04下同步cm10源码(个人记录,当作笔记)
  15. java-7继承
  16. alter 和 update的区别?
  17. sublime安装AngularJS插件
  18. ASP.NET CORE 3 安装遇到的问题
  19. python非官方模块下载大全
  20. Fuck me 忘记改REDO 造成复制用户超级慢

热门文章

  1. Eclipse工具修理集
  2. 洛谷 P1327 数列排序
  3. 洛谷 P1104 生日
  4. A题之拼音转数字
  5. Windows下编译OpenSSL(使用VS2013)
  6. (转)如何启动或关闭数据库的归档(ARCHIVELOG)模式
  7. 如何使用 PyCharm 将代码上传到GitHub上(详细图解)
  8. NSDate时间
  9. 关于android的2.2与4.4的文件读取的一点发现
  10. java韩顺平老师视频有需要可以留言