Log4j的使用
来源:互联网 发布:股票交易算法 编辑:程序博客网 时间:2024/06/11 00:07
OK,现在我们开始研究Log4j。Log4j是目前应用最广泛的日志空间,它分如下几个日志级别,日志级别依次升高。级别高的level会屏蔽级别低的信息。
TRACE→DEBUG→INFO→WARNING→ERROR→FATAL→OFF。
比如设置INFO级别,TRACE,DEBUG就不会输出,如果设置WARNING级别,则TRACE,DEBUG,INFO都不会输出。
- Log4j初体验
现在我们编码尝试下Log4j。代码如下:
- package org.linkinpark.commons.logtest;
- import org.apache.log4j.Logger;
- public class Log4jTest
- {
- public static Logger log = Logger.getLogger(Log4jTest.class);
- /*
- @创建时间: 2016年2月22日
- @相关参数:
- @功能描述: 定义一个输出日志的方法
- <p>
- trace→debug→info→warn→error→fatal→off
- 级别依次升高,级别高的level会屏蔽级别低的level。
- </p>
- */
- public static void logTest()
- {
- log.trace(”trace级别的日志输出”);
- log.info(”info级别的日志输出”);
- log.debug(”debug级别的日志输出”);
- log.warn(”warn级别的日志输出”);
- log.error(”error级别的日志输出”);
- log.fatal(”fatal级别的日志输出”);
- try
- {
- System.out.println(9 / 0);
- }
- catch (RuntimeException e)
- {
- log.error(e.getMessage());
- }
- }
- public static void main(String[] args)
- {
- logTest();
- }
- }
package org.linkinpark.commons.logtest;
import org.apache.log4j.Logger;
public class Log4jTest
{
public static Logger log = Logger.getLogger(Log4jTest.class);/** * @创建时间: 2016年2月22日 * @相关参数: * @功能描述: 定义一个输出日志的方法 * <p> * trace→debug→info→warn→error→fatal→off * 级别依次升高,级别高的level会屏蔽级别低的level。 * </p> */public static void logTest(){ log.trace("trace级别的日志输出"); log.info("info级别的日志输出"); log.debug("debug级别的日志输出"); log.warn("warn级别的日志输出"); log.error("error级别的日志输出"); log.fatal("fatal级别的日志输出"); try { System.out.println(9 / 0); } catch (RuntimeException e) { log.error(e.getMessage()); }}public static void main(String[] args){ logTest();}
}
这里我们用maven来管理我们该测试项目,需要添加log4j的pom依赖。
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.17</version>
- </dependency>
<dependency>日志的配置例如输出级别,输出到哪里,输出什么附加信息,输出格式等,一般都要写在配置文件log4j.properties中。
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
- # 可设置级别:TRACE→DEBUG→INFO→WARNING→ERROR→FATAL→OFF
- # 高级别level会屏蔽低级别level。
- # debug:显示debug、info、error
- # info:显示info、error
- #log4j.rootLogger=DEBUG,console,file
- log4j.rootLogger=INFO,console
- #输出到控制台
- log4j.appender.console=org.apache.log4j.ConsoleAppender
- #设置输出样式
- log4j.appender.console.layout=org.apache.log4j.PatternLayout
- #日志输出信息格式为
- log4j.appender.console.layout.ConversionPattern=[%-d{yyyy-MM-dd HH:mm:ss}]-[%t-%5p]-[%C-%M(%L)]: %m%n
- #输出到文件(这里默认为追加方式)
- #log4j.appender.file=org.apache.log4j.FileAppender
- #log4j.appender.file.File=F:/LinkinPark/logs/Log4J.log
- #样式为TTCCLayout
- #log4j.appender.file.layout=org.apache.log4j.TTCCLayout
- #自定义样式
- #%c 输出所属的类目,通常就是所在类的全名
- #%C 输出Logger所在类的名称,通常就是所在类的全名
- #%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},%d{ABSOLUTE},%d{DATE}
- #%F 输出所在类的类名称,只有类名。
- #%l 输出语句所在的行数,包括类名+方法名+文件名+行数
- #%L 输出语句所在的行数,只输出数字
- #%m 输出代码中指定的讯息,如log(message)中的message
- #%M 输出方法名
- #%p 输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL
- #%r 输出自应用启动到输出该log信息耗费的毫秒数
- #%t 输出产生该日志事件的线程名
- #%n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
- #%% 用来输出百分号“%”
- #log4j.appender.Linkin.layout.ConversionPattern=%n[%l%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m
- #log4j.appender.Linkin.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}[%C]-[%p] %m%n
- #log4j.appender.Linkin.layout.ConversionPattern = %d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
# 可设置级别:TRACE→DEBUG→INFO→WARNING→ERROR→FATAL→OFF# 高级别level会屏蔽低级别level。# debug:显示debug、info、error # info:显示info、error #log4j.rootLogger=DEBUG,console,filelog4j.rootLogger=INFO,console#输出到控制台 log4j.appender.console=org.apache.log4j.ConsoleAppender #设置输出样式 log4j.appender.console.layout=org.apache.log4j.PatternLayout #日志输出信息格式为log4j.appender.console.layout.ConversionPattern=[%-d{yyyy-MM-dd HH:mm:ss}]-[%t-%5p]-[%C-%M(%L)]: %m%n #输出到文件(这里默认为追加方式) #log4j.appender.file=org.apache.log4j.FileAppender #log4j.appender.file.File=F:/LinkinPark/logs/Log4J.log #样式为TTCCLayout #log4j.appender.file.layout=org.apache.log4j.TTCCLayout #自定义样式 #%c 输出所属的类目,通常就是所在类的全名 #%C 输出Logger所在类的名称,通常就是所在类的全名 #%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss , SSS},%d{ABSOLUTE},%d{DATE}#%F 输出所在类的类名称,只有类名。#%l 输出语句所在的行数,包括类名+方法名+文件名+行数#%L 输出语句所在的行数,只输出数字#%m 输出代码中指定的讯息,如log(message)中的message#%M 输出方法名#%p 输出日志级别,即DEBUG,INFO,WARN,ERROR,FATAL#%r 输出自应用启动到输出该log信息耗费的毫秒数#%t 输出产生该日志事件的线程名#%n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”#%% 用来输出百分号“%”#log4j.appender.Linkin.layout.ConversionPattern=%n[%l%d{yy/MM/dd HH:mm:ss:SSS}][%C-%M] %m #log4j.appender.Linkin.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss}[%C]-[%p] %m%n #log4j.appender.Linkin.layout.ConversionPattern = %d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
OK,现在让我们来看看控制台输出的日志情况。
- [2016-02-22 22:33:35]-[main- INFO]-[org.linkinpark.commons.logtest.Log4jTest-logTest(22)]: info级别的日志输出
- [2016-02-22 22:33:35]-[main- WARN]-[org.linkinpark.commons.logtest.Log4jTest-logTest(24)]: warn级别的日志输出
- [2016-02-22 22:33:35]-[main-ERROR]-[org.linkinpark.commons.logtest.Log4jTest-logTest(25)]: error级别的日志输出
- [2016-02-22 22:33:35]-[main-FATAL]-[org.linkinpark.commons.logtest.Log4jTest-logTest(26)]: fatal级别的日志输出
- [2016-02-22 22:33:35]-[main-ERROR]-[org.linkinpark.commons.logtest.Log4jTest-logTest(33)]: / by zero
[2016-02-22 22:33:35]-[main- INFO]-[org.linkinpark.commons.logtest.Log4jTest-logTest(22)]: info级别的日志输出 [2016-02-22 22:33:35]-[main- WARN]-[org.linkinpark.commons.logtest.Log4jTest-logTest(24)]: warn级别的日志输出 [2016-02-22 22:33:35]-[main-ERROR]-[org.linkinpark.commons.logtest.Log4jTest-logTest(25)]: error级别的日志输出 [2016-02-22 22:33:35]-[main-FATAL]-[org.linkinpark.commons.logtest.Log4jTest-logTest(26)]: fatal级别的日志输出 [2016-02-22 22:33:35]-[main-ERROR]-[org.linkinpark.commons.logtest.Log4jTest-logTest(33)]: / by zero
- Log4J的应用
- 1,Log4j的执行效率
- log.debug(“debug级别的日志输出”);
- log.info(”info级别的日志输出”);
log.debug("debug级别的日志输出");log.info("info级别的日志输出");这两句日志可能被记录到日志文件中,但是写的过程不同于常规的打开文件,写文件,关闭文件等流程,频繁的打开文件,关闭文件需要消耗大量的资源。Log4j只在初始化的时候打开文件,并保持对文件的写控制,知道在系统结束的时候才会关闭文件。这样就使I/O次数达到最小,提高了运行效率。
当输出级别设置为ERROR时,debug,info等低级别方法会因为输出级别小于error而直接返回,所以不会消耗太多的资源。这里我们来看下debug()方法内部的实现代码:
- public void debug(Object message)
- {
- if (repository.isDisabled(Level.DEBUG_INT))
- return;
- if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel()))
- {
- forcedLog(FQCN, Level.DEBUG, message, null);
- }
- }
public void debug(Object message) { if (repository.isDisabled(Level.DEBUG_INT)) return; if (Level.DEBUG.isGreaterOrEqual(this.getEffectiveLevel())) { forcedLog(FQCN, Level.DEBUG, message, null); } }
- 2,优化日志代码
虽然设为ERROR时debug()会直接返回,但是下面的代码仍然会消耗额外的时间,原因是在执行debug()前,需要先将字符串进行连接。
- log.debug(“debug级别的日志输出”+i+“*”+j); // 有字符串拼接
log.debug("debug级别的日志输出"+i+"*"+j); // 有字符串拼接
如果想要避免这种消耗,最好使用isDebugEnabled()或者isEnabledFor()判断一下,比如下面代码:
- if (log.isDebugEnabled())
- {
- log.debug(”debug级别的日志输出”);
- }
- if (log.isEnabledFor(Level.DEBUG))
- {
- log.debug(”debug级别的日志输出”);
- }
if (log.isDebugEnabled()) { log.debug("debug级别的日志输出"); } if (log.isEnabledFor(Level.DEBUG)) { log.debug("debug级别的日志输出"); }
- 3,log4j配置文件
Log4j默认的配置文件为log4j.properties。启动时,会加载classpath下的log4j.properties初始化Log4j。如果文件不存在,Log4j会在控制台打印如下信息,提示说没有找到Log4j配置。比如我们现在只保留Java代码,然后删除掉log4j.properties配置文件,看控制台报错。
OK,现在重新将log4j.properties配置文件加入到我们的项目classpath中,然后控制台输出日志正常。这里一定要注意要加载项目的Classpath中,在这里我们随便写写测试类,所以直接丢项目src下面就好了,编译过后配置文件自动就放到了class的根目录下了。
- log4j:WARN No appenders could be found for logger (org.linkinpark.commons.logtest.Log4jTest).
- log4j:WARN Please initialize the log4j system properly.
- log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
log4j:WARN No appenders could be found for logger (org.linkinpark.commons.logtest.Log4jTest).log4j:WARN Please initialize the log4j system properly.log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
OK,现在重新将log4j.properties配置文件加入到我们的项目classpath中,然后控制台输出日志正常。这里一定要注意要加载项目的Classpath中,在这里我们随便写写测试类,所以直接丢项目src下面就好了,编译过后配置文件自动就放到了class的根目录下了。
当然我们也可以使用其他的方式,只不过不推荐罢了。如果不使用默认的文件名log4j.properties,可以用PropertyConfigurator指定配置文件的路径。比如下面的代码,经过测试可行。当然还可以使用log4j.xml,只不过要在xml里面加入log4j的secma,不推荐。这里贴出使用Java类加载指定配置文件的代码:
- public static void logTest()
- {
- PropertyConfigurator.configure(”/Users/LinkinPark/WorkSpace/linkin-log-test/src/main/java/org/linkinpark/commons/logtest/log4j.properties”);
- if (log.isDebugEnabled())
- {
- log.debug(”debug级别的日志输出”);
- }
- }
public static void logTest() { PropertyConfigurator.configure("/Users/LinkinPark/WorkSpace/linkin-log-test/src/main/java/org/linkinpark/commons/logtest/log4j.properties"); if (log.isDebugEnabled()) { log.debug("debug级别的日志输出"); } }
这里也贴出PropertyConfigurator类configure()方法源码:
- static public void configure(String configFilename)
- {
- new PropertyConfigurator().doConfigure(configFilename, LogManager.getLoggerRepository());
- }
- public void doConfigure(String configFileName, LoggerRepository hierarchy)
- {
- Properties props = new Properties();
- FileInputStream istream = null;
- try
- {
- istream = new FileInputStream(configFileName);
- props.load(istream);
- istream.close();
- }
- catch (Exception e)
- {
- if (e instanceof InterruptedIOException || e instanceof InterruptedException)
- {
- Thread.currentThread().interrupt();
- }
- LogLog.error(”Could not read configuration file [“ + configFileName + “].”, e);
- LogLog.error(”Ignoring configuration file [“ + configFileName + “].”);
- return;
- }
- finally
- {
- if (istream != null)
- {
- try
- {
- istream.close();
- }
- catch (InterruptedIOException ignore)
- {
- Thread.currentThread().interrupt();
- }
- catch (Throwable ignore)
- {
- }
- }
- }
- // If we reach here, then the config file is alright。嫁入到log4j中去了。
- doConfigure(props, hierarchy);
- }
static public void configure(String configFilename) { new PropertyConfigurator().doConfigure(configFilename, LogManager.getLoggerRepository()); } public void doConfigure(String configFileName, LoggerRepository hierarchy) { Properties props = new Properties(); FileInputStream istream = null; try { istream = new FileInputStream(configFileName); props.load(istream); istream.close(); } catch (Exception e) { if (e instanceof InterruptedIOException || e instanceof InterruptedException) { Thread.currentThread().interrupt(); } LogLog.error("Could not read configuration file [" + configFileName + "].", e); LogLog.error("Ignoring configuration file [" + configFileName + "]."); return; } finally { if (istream != null) { try { istream.close(); } catch (InterruptedIOException ignore) { Thread.currentThread().interrupt(); } catch (Throwable ignore) { } } } // If we reach here, then the config file is alright。嫁入到log4j中去了。 doConfigure(props, hierarchy); }
OK,log4j的配置文件内容还是比较多的,我们下一篇来详细的整理。这篇先这样。
阅读全文
0 0
- Log4j的使用!
- Log4j的使用
- Log4j的使用
- log4j的第一步使用
- Log4j的使用
- log4j的使用
- Log4j的简单使用
- Log4j的使用
- Log4j的使用
- log4j/log4e的使用
- log4j/log4e的使用
- Log4j 的灵活使用
- log4j/log4e的使用
- log4j的使用
- log4j的使用
- Log4j的使用
- LOG4J的使用- -
- Log4j的使用
- 前端常用JS库
- ASIC/SoC设计
- 北大 AI 公开课第10讲 胡郁:人工智能+,共创新时代
- leetcode 149. Max Points on a Line 计算斜率的问题
- 【剑指offer】面试题25:从上往下打印二叉树
- Log4j的使用
- http协议详解
- 等待事件整体印象
- C++内存检测
- windows10配置jdk和Tomcat
- PAT考试已结束,撒花
- 【Python3.6】将个人微信改造成机器人自动对话
- Java基本数据类型の浮点型
- 涉及MySQL工具本身的几个常用命令行操作