• java.util.logging.Logger 使用详解


    概述:

    第1部分 创建Logger对象

    第2部分 日志级别

    第3部分 Handler

    第4部分 Formatter

    第5部分 自定义

    第6部分 Logger的层次关系

    参考 

    第1部分 创建Logger对象

    要使用J2SE的日志功能,首先要取得java.util.logging.Logger实例,这可以通过Logger类的两个静态getLogger()方法来取得:

    static Logger getLogger(String name) 
             查找或创建一个logger。
    static Logger getLogger(String name, String resourceBundleName) 
             为指定子系统查找或创建一个logger。

    注意:name是Logger的名称,当名称相同时候,同一个名称的Logger只创建一个。

    下面是简单范例:

     1 public class LoggingDemo {
     2     public static void main(String[] args){
     3         Logger logger = Logger.getLogger("LoggingDemo");
     4         
     5         try{
     6             System.out.println(args[0]);
     7         }catch(ArrayIndexOutOfBoundsException e){
     8             logger.warning("没有提供执行时的自变量!");
     9         }        
    10     }    
    11 }

    执行结果:

    第2部分 日志级别

    在进行信息的记录时,依信息程序的不同,会设定不同等级的信息输出。Java log比log4j的级别详细,全部定义在java.util.logging.Level里面。

    各级别按降序排列如下:

    • SEVERE(最高值)
    • WARNING
    • INFO
    • CONFIG
    • FINE
    • FINER
    • FINEST(最低值)

    此外,还有一个级别OFF,可用来关闭日志记录,使用级别ALL启用所有消息的日志记录。

    logger默认的级别是INFO,比INFO更低的日志将不显示。

    Logger的默认级别定义是在jre安装目录的lib下面。

    # Limit the message that are printed on the console to INFO and above. 
    java.util.logging.ConsoleHandler.level = INFO

    可以通过操作Logger上的几个方法来得到不同等级的信息输出。如下列范例:

     1 public class LoggingDemo {
     2     public static void main(String[] args){
     3         Logger logger = Logger.getLogger("LoggingDemo");
     4         
     5         logger.severe("严重信息");
     6 
     7         logger.warning("警示信息");
     8 
     9         logger.info("一般信息");
    10 
    11         logger.config("设定方面的信息");
    12 
    13         logger.fine("细微的信息");
    14 
    15         logger.finer("更细微的信息");
    16 
    17         logger.finest("最细微的信息");
    18     }
    19     
    20 }

    执行结果:

    此示例中config()方法及以下的信息并没有显示出来,这是因为Logger的默认等级是INFO,比这个等级更低的信息,Logger并不会将信息输出。

    Logger的默认等级是定义在执行环境的属性文件logging.properties中,这个文件位于JRE安装目录的lib目录下。部分内容如下:

    # Limit the message that are printed on the console to INFO and above.
    java.util.logging.ConsoleHandler.level = INFO
    java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter

    Logger默认的输出媒介控制器(Handler)是java.util.logging.ConsolerHandler,也就是将信息输出至控制台。一个Logger可以拥有多个handler,每个handler可以有自己的日志级别,在通过Logger的级别限制后,实际上还要再经过handler的级别限制。所以在上面的范例中如果想要看到所有的信息,则必须同时设定Logger与!ConsoleHandler的级别。下面的范例示范了如何设定:

     1 public class LoggingDemo {
     2     public static void main(String[] args){
     3         Logger logger = Logger.getLogger("LoggingDemo");
     4         
     5         //显示所有等级的信息
     6         logger.setLevel(Level.ALL);
     7         ConsoleHandler consoleHandler = new ConsoleHandler();
     8         //显示所有等级的信息
     9         consoleHandler.setLevel(Level.ALL);
    10         //设定Handler为!ConsoleHandler
    11         logger.addHandler(consoleHandler);        
    12         logger.severe("严重信息");
    13         logger.warning("警示信息");
    14         logger.info("一般信息");
    15         logger.config("设定方面的信息");
    16         logger.fine("细微的信息");
    17         logger.finer("更细微的信息");
    18         logger.finest("最细微的信息");
    19     }
    20     
    21 }

    执行结果:

    Level.ALL表示显示所有的信息,所有这一次的执行结果可显示所有等级的信息。如果要关闭所有的信息,可以设定为Level.OFF。

    Logger的Severe(),warning(),info()等方法,实际上是个便捷的方法。也可以直接使用log()方法并指定等级来执行相同的作用,如:

    public class LoggingDemo {
        public static void main(String[] args){
            Logger logger = Logger.getLogger("LoggingDemo");
            logger.log(Level.SEVERE, "严重信息test");        
        }    
    }

    结果:

    第3部分 Handler

    Handler对象从Logger中获取日志信息,并将这些信息导出。例如,它可将这些信息写入控制台或文件中,也可以将这些信息发送到网络日志服务中,或将其转发到操作系统日志中。

    Logger默认的输出处理者是ConsoleHandler。!ConsoleHandler的输出是使用System.err对象,而信息的默认等级是INFO,这可以在JRE安装目录下lib目录的logging.properties中看到:

    # Limit the message that are printed on the console to INFO and above.
    java.util.logging.ConsoleHandler.level = INFO

    Java SE实现了5个Handler:

    (1) java.util.logging.ConsoleHandler 以System.err输出日志。

    (2) java.util.logging.FileHandler 将信息输出到文件。

    (3) java.util.logging.!StreamHandler以指定的!OutputStream实例输出日志。

    (4) java.util.logging.!SocketHandler将信息通过Socket传送至远程主机。

    (5) java.util.logging.!MemoryHandler将信息暂存在内存中。

    以下代码将信息输出至文件中:

     1 public class LoggingDemo {
     2     public static void main(String[] args){
     3         Logger logger = Logger.getLogger("LoggingDemo");
     4 
     5         try {
     6             FileHandler fileHandler = new FileHandler("D:\test/3.txt");
     7             logger.addHandler(fileHandler);
     8             logger.info("测试信息");
     9         } catch (SecurityException e) {
    10             e.printStackTrace();
    11         } catch (IOException e) {
    12             e.printStackTrace();
    13         }
    14     }
    15     
    16 }

    执行结果:

    D: est3.text内容如下:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE log SYSTEM "logger.dtd">
    <log>
    <record>
      <date>2014-11-25T10:53:49</date>
      <millis>1416884029723</millis>
      <sequence>0</sequence>
      <logger>LoggingDemo</logger>
      <level>INFO</level>
      <class>com.ConcurrentContainer.LoggingDemo</class>
      <method>main</method>
      <thread>1</thread>
      <message>测试信息</message>
    </record>
    </log>

    fileHandler默认的输出格式是XML格式。输出格式由java.util.logging.Formatter来控制,下一节详细介绍Formatter。

    第4部分 Formatter

    Formatter为格式化LogRecords提供支持。
    一般来说,每个Handler都有关联的Formatter。Formatter接受LogRecord,并将它转换为一个字符串。

    默认提供了两种Formatter:
    1.java.util.logging.SimpleFormatter:标准日志格式,就是我们通常在启动一些诸如 Tomcat JBoss之类的服务器的时候经常能在控制台下看到的那种形式,就像这样:

    2004-12-20 23:08:52 org.apache.coyote.http11.Http11Protocol init
    信息: Initializing Coyote HTTP/1.1 on http-8080

    2.java.util.logging.XMLFormatter:XML形式的日志格式,如果为Logger添加了一个new XMLFormatter(),那么就会以XML形式输出,不过更常用的是使用上面介绍的FileHandler输出到XML文件中。

    从上一节的例子可知,FileHandler的默认格式是java.util.logging.XMLFormatter,而ConsolerHandler的默认格式是java.util.logging.SimpleFormatter,可以使用Handler实例的setFormatter()方法来设定信息的输出格式。例如:

    fileHandler.setFormatter(new SimpleFormatter());

    FileHandler的Formatter设定为SimpleFormatter,则输出的日志文件内容就是简单的文字信息,打开文件后会发现与命令行模式下看到的信息内容相同。

    第5部分 自定义

    1、Handler

    用户可以定制自己输出媒介控制器,继承Handler即可,通常只需要实现Handler中三个未定义的抽象方法:

     publish:主要方法,把日志记录写入你需要的媒介。

     flush:清除缓冲区并保存数据。

     close:关闭控制器。

    通过重写以上三个方法可以很容易实现一个新的输出媒介控制器。

    2、Formatter

    除了XMLFormatter与!SimpleFormatter之外,也可以自定义日志的输出格式,只要继承抽象类Formatter,并重新定义其format()方法即可。format()方法会传入一个java.util.logging.LogRecord对象作为参数,可以使用它来取得一些与程序执行有关的信息。'

    3、日志级别

    Java的一个日志级别对应一个整数值,Level有9个内置的级别,分别是:

    类型          对应的整数
     OFF         最大整数( Integer. MAX_VALUE
     SEVERE     1000
     WARNING   900
     INFO         800
     CONFIG      700
     FINE          500
     FINER        400
     FINEST      300
     ALL           最小整数(Integer. MIN_VALUE

    你也可以定义自己的日志级别,通过继承Level的方式,譬如:

     1 /**
     2  * 自定义日志级别
     3  * @ClassName: AlertLevel
     4  * TODO
     5  * @author xingle
     6  * @date 2014-11-25 上午9:54:23
     7  */
     8 public class AlertLevel extends Level{
     9 
    10     /**
    11      * @param name
    12      * @param value
    13      */
    14     protected AlertLevel(String name, int value) {
    15         super(name,value);
    16     }
    17     
    18     public static void main(String[] args){
    19         Logger logger = Logger.getAnonymousLogger();
    20         //低于INFO(800),显示不出来,因为默认的配置 java.util.logging.ConsoleHandler.level = INFO
    21         logger.log(new AlertLevel("ALERT",950), "自定义 lever!");
    22     }
    23 }

    执行结果:

    第6部分 Logger的层次关系

     在使用Logger的静态getLogger()方法取得Logger实例时,给getLogger()方法的名称是有意义的。如果给定a,实际上将从根(Root)logger继承一些特性,像日志级别(Level)以及根logger的输出媒介控制器。如果再取得一个Logger实例,并给定名称a.b,则这次取得的Logger将继承pku这个Logger上的特性。从以下范例可以看出Logger在名称上的继承关系:

     1 /**
     2  * Logger的层次关系
     3  * @ClassName: LoggerHierarchyDemo
     4  * TODO
     5  * @author xingle
     6  * @date 2014-11-25 上午10:04:54
     7  */
     8 public class LoggerHierarchyDemo {
     9     public static void main(String[] args){
    10         Logger onlyfunLogger = Logger.getLogger("a");
    11         Logger caterpillarLogger = Logger.getLogger("a.b");
    12         System.out.println("root logger:"+onlyfunLogger.getParent());
    13         System.out.println("onlyfun logger:" + caterpillarLogger.getParent().getName());
    14         System.out.println("caterpillar Logger:" + caterpillarLogger.getName() + "
    ");
    15         onlyfunLogger.setLevel(Level.WARNING);
    16         caterpillarLogger.info("caterpillar ' info");
    17         caterpillarLogger.setLevel(Level.INFO);
    18         caterpillarLogger.info("caterpillar ' info");
    19     }
    20 }

    执行结果:

    getParent()方法可以取得Logger上的上层父Logger,根Logger并没有名称,所以直接调用它的toString()以取得字符串描述。当Logger没有设定等级时,则使用父Logger的等级设定,所以在上面的范例中,onlyfunLogger设定等级为WARNING时,caterpillarLogger调用info()方法时并不会有信息显示(因为WARNING等级比INFO高)。


    参考 :

     1.主题:log4j详解与实战

  • 相关阅读:
    java线程管理
    java进程间通信
    Possible multiple enumeration of IEnumerable
    Adding Search
    Working with SQL Server LocalDB
    ASP.NET Razor
    ASP.NET Razor
    modelstate.isvalid false
    Razor Intro
    open Command window here
  • 原文地址:https://www.cnblogs.com/xingele0917/p/4120320.html
Copyright © 2020-2023  润新知