现在的位置: 首页 > 综合 > 正文

JAVA 日志介绍 篇

2018年01月29日 ⁄ 综合 ⁄ 共 7172字 ⁄ 字号 评论关闭

日志介绍

日志的由来

日志,源于log,有航海日志的意思。指记录海员记录每天的行程,生活及发生的事件。在软件开发领域,用来监控代码中变量变化,跟踪代码运行的轨迹,在开发环境中担当调试器作用,向控制台或文件输出信息。

功能划分日志

从功能上讲,这些可以分为三类,一是日志工具类,它实现了日志的记录,格式化和级别的划分,代表为logback,simplelog。二是日志系统,提供了完整的框架功能并实现了日志记录。代表为 jul(jdk提供的日志框架),log4j(apache开源项目)。三是抽象整合类,它提供了一组接口,完成日志功能,通过包装其他日志工具或系统来 工作jcl(apache开源组件),slf4j。

Log4j,历史悠久,应用广泛,被移植到多种语言及平台,功能强大,在众多的日志框架中,仍占据着主导地位。如果是web开发,宜采用log4j,因为系统已经有了很多的配置文件,不在乎多一个,而且log4j可以脱离任何组件,不像jul,和jvm紧密结合在一起。

当然有时候我们也会用到JDK自带的类集java.util.logging,通过日志系统来控制、格式化以及发布消息。日志系统功能非常强大,可以设置日志消息的优先级,可以通过过滤器来选择感兴趣的信息。并且消息可以输出到Handler对象能够处理的任意源,如控制台、窗口、数据库、本地文件等等。

因此,在这里,我们将会简单地分别介绍下Logging和Log4j。

 

Logging

一、Logging介绍

java.util.logging.Logger不是什么新鲜东西了,1.4就有了,可是因为log4j的存在,这个logger一直沉默着,其实在一些测试性的代码中,jdk自带的logger比log4j更方便。

二、创建Logger对象

staticLogger getLogger(String name)
static Logger getLogger(String name, StringresourceBundleName)

          为指定子系统查找或创建一个logger。

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

 实例:

Logger.getLogger(AccountList.class.getName()).log(Level.SEVERE, null,  ex);

三、Logging的级别

 比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

四、简单实例

publicclass TestLogger {
        public static void main(String[] args) {
                Loggerlog = Logger.getLogger("lavasoft");
                log.setLevel(Level.INFO);
                Loggerlog1 = Logger.getLogger("lavasoft");
                System.out.println(log==log1);    //true
                Loggerlog2 = Logger.getLogger("lavasoft.blog");
                log2.setLevel(Level.WARNING);

                log.info("aaa");
                log2.info("bbb");
                log2.fine("fine");
        }
}

 

true

2009-7-2820:00:30 TestLogger main
信息: aaa
Process finished with exit code 0 

当注释掉       log2.setLevel(Level.WARNING);
输出结果:

true
2009-7-28 20:02:02 TestLogger main
信息: aaa
2009-7-28 20:02:02 TestLogger main
信息: bbb
Process finished with exit code 0

 从这里可以看出,logger的名字是有层级关系的。这和log4j的控制方式完全一致。

下面是API文档的原文:

一般使用圆点分隔的层次命名空间来命名 Logger。Logger 名称可以是任意的字符串,但是它们一般应该基于被记录组件的包名或类名,如java.net 或 javax.swing。此外,可以创建“匿名”的Logger,其名称未存储在 Logger 命名空间中。

可通过调用某个getLogger 工厂方法来获得 Logger 对象。这些方法要么创建一个新Logger,要么返回一个合适的现有 Logger。

 

五、Logger的Handler

 

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

可通过执行 setLevel(Level.OFF) 来禁用Handler,并可通过执行适当级别的 setLevel 来重新启用。

Handler 类通常使用 LogManager 属性来设置Handler 的 Filter、Formatter 和Level 的默认值。

java.util.logging.Handler

java.util.logging.MemoryHandler
java.util.logging.StreamHandler 

java.util.logging.ConsoleHandler
java.util.logging.FileHandler 

java.util.logging.SocketHandler

 

例子:

publicclass TestLogger {
        public static voidmain(String[] args) throws IOException {
                Loggerlog = Logger.getLogger("lavasoft");
                log.setLevel(Level.INFO);
                Loggerlog1 = Logger.getLogger("lavasoft");
                System.out.println(log==log1);    //true
                Loggerlog2 = Logger.getLogger("lavasoft.blog");
//                log2.setLevel(Level.WARNING);

                ConsoleHandlerconsoleHandler =new ConsoleHandler();
                consoleHandler.setLevel(Level.ALL);
                log.addHandler(consoleHandler);
                FileHandlerfileHandler = new FileHandler("C:/testlog%g.log");
                fileHandler.setLevel(Level.INFO);
                log.addHandler(fileHandler);
                log.info("aaa");
                log2.info("bbb");
                log2.fine("fine");
        }
}

 

输出结果:

true
2009-7-28 20:36:14 TestLogger main
信息: aaa
2009-7-28 20:36:14 TestLogger main
信息: aaa
2009-7-28 20:36:14 TestLogger main
信息: bbb
2009-7-28 20:36:14 TestLogger main
信息: bbb

Process finished with exit code 0

 

查看C盘:

 

可见,默认的日志方式是xml格式,很烂。所以最好自定义下logger的格式。需要用Formatter来定义。

 

六、Logger的Formatter

 

Formatter为格式化 LogRecords 提供支持。
一般来说,每个日志记录 Handler 都有关联的Formatter。Formatter 接受 LogRecord,并将它转换为一个字符串。
有些 formatter(如 XMLFormatter)需要围绕一组格式化记录来包装头部和尾部字符串。可以使用getHeader 和 getTail 方法来获得这些字符串。

 

LogRecord对象用于在日志框架和单个日志 Handler 之间传递日志请求。
LogRecord(Level level, String msg)
          用给定级别和消息值构造LogRecord。

 

java.util.logging.Formatter
  java.util.logging.SimpleFormatter
  java.util.logging.XMLFormatter

 

看个例子就明白了:

publicclass TestLogger {
        public static voidmain(String[] args) throws IOException {
                Loggerlog = Logger.getLogger("lavasoft");
                log.setLevel(Level.INFO);
                Loggerlog1 = Logger.getLogger("lavasoft");
                System.out.println(log== log1);     //true
                Loggerlog2 = Logger.getLogger("lavasoft.blog");
//                log2.setLevel(Level.WARNING);

                ConsoleHandlerconsoleHandler = new ConsoleHandler();
                consoleHandler.setLevel(Level.ALL);
                log.addHandler(consoleHandler);
                FileHandlerfileHandler = new FileHandler("C:/testlog%g.log");
                fileHandler.setLevel(Level.INFO);
                fileHandler.setFormatter(newMyLogHander());
                log.addHandler(fileHandler);

                log.info("aaa");
                log2.info("bbb");
                log2.fine("fine");
        }
}

class MyLogHander extends Formatter {
        @Override
        public String format(LogRecordrecord) {
                returnrecord.getLevel() + ":" + record.getMessage()+"\n";
        }
}

 

输出:

在控制和C盘输出的文件如图

 

到此,Java自带的Logger内容就没了。

感觉格式很不爽。自带的XML格式很烂。

 

Log4j

一、Log4j介绍

Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件、甚至是套接口服务器、NT的事件记录器、UNIXSyslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

二、Log4j级别

日志记录器(Logger)是日志处理的核心组件。log4j具有5种正常级别(Level)。 日志记录器(Logger)的可用级别Level (不包括自定义级别 Level), 以下内容就是摘自log4j API (http://jakarta.apache.org/log4j/docs/api/index.html):

static Level DEBUG

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

static Level INFO

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

static Level WARN

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

static Level ERROR

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

static Level FATAL

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

另外,还有两个可用的特别的日志记录级别: (以下描述来自log4jAPI

http://jakarta.apache.org/log4j/docs/api/index.html):

static LevelALL

static LevelOFF

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

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

日志记录器(Logger)的行为是分等级的。如下表所示:

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

三、Log4j操作

1、建立Logger实例:
语法表示:public static LoggergetLogger( String name)
实际使用:static Logger logger=Logger.getLogger(ServerWithLog4j.class.getName ()) ;

2、 读取配置文件:
   获得了Logger的实例之后,接下来将配置Log4j使用环境:
   语法表示:
   BasicConfigurator.configure():自动快速地使用缺省Log4j环境。
  PropertyConfigurator.configure(String configFilename):读取使用Java的特性文件编写的配置文件。
  DOMConfigurator.configure(String filename):读取XML形式的配置文件。
   实际使用:
   PropertyConfigurator.configure("ServerWithLog4j.properties");

3、 插入日志信息
   完成了以上连个步骤以后,下面就可以按日志的不同级别插入到你要记录日志的任何地方了。
   语法表示:
   Logger.debug(Objectmessage);//调试信息
   Logger.info(Objectmessage);//一般信息
   Logger.warn(Objectmessage);//警告信息
   Logger.error(Objectmessage);//错误信息
   Logger.fatal(Objectmessage);//致命错误信息

  实际使用:logger.info("ServerSocketbefore accept: " + server);

抱歉!评论已关闭.