zoukankan      html  css  js  c++  java
  • Java日志(一):log4j与.properties配置文件

      日志是应用软件中不可缺少的部分,Apache的开源项目log4j是一个功能强大的日志组件,提供方便的日志记录,在Apache网站jakarta.apache.org/log4j可以免费下载到Log4j最新版本的软件包。

      Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、 INFO、DEBUG,分别用来指定日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;日志信息的输出格式指定输出的内容。


    案例篇

    Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(.properties文件,键=值),本文案例使用Java特性文件

    第一节 初识log4j

    案例一

    新建Java project(项目名为HelloWord-log4j),新建目录lib,添加jar文件,建包com.test,建类Test1,内容如下: 

    package com.test;
    
    import org.apache.log4j.Logger;
    
    public class Test1 {
    
      // 得到记录器
      private static Logger log = Logger.getLogger(Test1.class.getName());
    
      public static void main(String[] args) {
    
        // 插入记录信息
        log.info("Test log4j");
    
      }
    }

    然后在src目录下新建一个配置文件,命名为log4j.properties,其内容如下:

    log4j.rootLogger=INFO,appender1
    log4j.appender.appender1=org.apache.log4j.ConsoleAppender
    log4j.appender.appender1.layout=org.apache.log4j.SimpleLayout

    运行,控制台输出如下内容:

    INFO - Test log4j

     案例二

    将案例一的配置文件log4j.properties移到com.test包下(或者将其移到项目根目录下),其内容不变,运行,控制台输出如下内容:

    log4j:WARN No appenders could be found for logger (com.test.Test1).
    log4j:WARN Please initialize the log4j system properly.

    案例三

    将案例一的配置文件log4j.properties重命名为test.properties,依然位于src目录下,其内容不变,运行,控制台输出如下内容:

    log4j:WARN No appenders could be found for logger (com.test.Test1).
    log4j:WARN Please initialize the log4j system properly.

    这三个案例说明:只要log4j的配置文件名为log4j.properties且该配置文件在类根路径下,则程序可自动加载该配置文件,不用写任何代码,log4j就会初试化


    第二节 PropertyConfigurator.configure

    案例四

    在案例三的基础上(也就是说现在配置文件位于src目录下,其名称为test.properties),修改代码如下:

    package com.test;
    
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    
    public class Test1 {
    
      // 得到记录器
      private static Logger log = Logger.getLogger(Test1.class.getName());
    
      public static void main(String[] args) {
    
        PropertyConfigurator.configure ("src\test.properties");
    
        // 插入记录信息
        log.info("Test log4j");
    
      }
    }

    运行,控制台输出如下:

    INFO - Test log4j

    案例五

    将案例四中的配置文件移到com.test包下

    将代码中的PropertyConfigurator.configure ("src\test.properties")修改为PropertyConfigurator.configure ("src\com\test\test.properties")

    运行,控制台输出如下:

    INFO - Test log4j

    案例六

    将案例四中的配置文件移到项目根目录下

    将代码中的PropertyConfigurator.configure ("src\test.properties")修改为PropertyConfigurator.configure ("test.properties")

    运行,控制台输出如下:

    INFO - Test log4j

    案例七

    在案例四的基础上,在项目中新建目录conf,将配置文件移到该目录下

    将代码中的PropertyConfigurator.configure ("src\test.properties")修改为PropertyConfigurator.configure ("conf\test.properties")

    运行,控制台输出如下:

    INFO - Test log4j

    案例三、四、五、六、七说明:可以通过PropertyConfigurator.configure("");语句来加载自定义命名的配置文件(包括log4j.properties),但是得明确指定配置文件的放置目录


    第三节 Properties

    案例八

    利用Properties类,配合new FileInputStream("")来加载配置文件,在案例七的基础上(此时配置文件位于conf目录下,其名称为test.properties),修改代码如下:

    package com.test;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;
    
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    
    public class Test1 {
    
      // 得到记录器
      private static Logger log = Logger.getLogger(Test1.class.getName());
    
      public static void main(String[] args) {
    
        Properties props = new Properties();
        try {
          props.load(new FileInputStream("conf\test.properties"));
        } catch (IOException e) {
          e.printStackTrace();
        }
        PropertyConfigurator.configure(props);
    
        // 插入记录信息
        log.info("Test log4j");
    
      }
    }

    运行,控制台输出如下:

    INFO - Test log4j

    案例九

    将案例八中的配置文件移到其它目录下时(如:项目根目录或src目录或com.test包),需要相应改变代码中new FileInputStream("conf\test.properties")中配置文件的路径,如:当配置文件位于com.test包下时,修改该语句为new FileInputStream("src\com\test\test.properties")

    案例八、九说明:利用Properties类,配合new FileInputStream("")读取配置文件时仍然需要使用PropertyConfigurator.configure("")语句,与直接使用PropertyConfigurator.configure("")语句没有什么太大区别;那么为什么要使用案例八/九中更为繁琐的方式呢,这样做有什么好处吗???

    答案:利用Properties类可以不使用配置文件,可以直接在代码中通过使用Properties类对象来设定Log4j环境,如下代码所示:

    private static void initLog4j() {
      Properties prop = new Properties();
    
      prop.setProperty("log4j.rootLogger", "DEBUG, CONSOLE");
      prop.setProperty("log4j.appender.CONSOLE", "org.apache.log4j.ConsoleAppender");
      prop.setProperty("log4j.appender.CONSOLE.layout", "org.apache.log4j.PatternLayout");
      prop.setProperty("log4j.appender.CONSOLE.layout.ConversionPattern", "%d{HH:mm:ss,SSS} [%t] %-5p %C{1} : %m%n");
    
      PropertyConfigurator.configure(prop);
    }

    第四节 ClassLoader

    案例十

    利用Properties类,配合ClassLoader来加载配置文件,在案例八的基础上,将配置文件移到src目录下,修改代码如下:

    package com.test;
    
    import java.io.IOException;
    import java.util.Properties;
    
    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    
    public class Test1 {
    
    // 得到记录器
    private static Logger log = Logger.getLogger(Test1.class.getName());
    
      public static void main(String[] args) {
    
        ClassLoader loader = Test1.class.getClassLoader();
    
        Properties props = new Properties();
        try {
          System.out.println(loader.getResource(""));
          props.load(loader.getResourceAsStream("test.properties"));
        } catch (IOException e) {
          e.printStackTrace();
        }
        PropertyConfigurator.configure(props);
    
        // 插入记录信息
        log.info("Test log4j");
    
      }
    
    }

    运行,控制台输出如下:

    INFO - Test log4j

    解说:可以发现,上述代码中没有src的身影,如果将路径改为src\test.properties,然后运行程序,程序报错;

    将配置文件移到项目根目录下,然后运行程序,程序报错;

    将配置文件移到com.test包下,也只需将路径修改为com\test\test.properties,程序即可正常运行

    此处的原因在于,loader.getResource("")读取的路径是bin目录(ClassPath目录)


    小结:

    代码中需要配置这些路径的原因之一在于IDE暗中帮我们做了一些事情,当你在src目录下新建文件时,它会自动将其发布到ClassPath目录(默认为bin目录)下,那代码中为什么写成src而不是bin呢


    番外篇

    日志信息的格式

    说明:本文参考资料(2)中有一些示例指定了日志信息的输出格式,此处截图为证,O(∩_∩)O哈哈~

    解说:Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下:

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

      %f 输出所属的类名,包括扩展名

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

      %n 输出一个回车换行符,Windows平台为“rn”,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)

      %m 输出代码中指定的消息,如log.info(message)中的message

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


    参考资料: 

    (1)http://www.codeceo.com/article/log4j-usage.html

    (2)http://blog.sina.com.cn/s/blog_541caaee010121gy.html


    一篇好文:Java日志性能那些事http://www.infoq.com/cn/articles/things-of-java-log-performance

  • 相关阅读:
    Python3 WebDriver操作cookie的方法
    Windows创建定时任务执行Python脚本
    Python3 自定义请求头消息headers
    为什么SQL用UPDATE语句更新时更新行数会多3行有触发器有触发器有触发器有触发器有触发器有触发器
    【C#】C#获取文件夹下的所有文件
    jQuery.ajax()调用asp.net后台方法(非常重要)
    Asp.Net+JQuery.Ajax之$.post
    c# post 接收传来的文件
    C#使用GET、POST请求获取结果,这里以一个简单的用户登陆为例。
    javascript中let和var的区别
  • 原文地址:https://www.cnblogs.com/studyLog-share/p/4567133.html
Copyright © 2011-2022 走看看