从JDK1.4开始即引入与日志相关的类java.util.logging.Logger,但由于Log4J的存在,一直未能广泛使用。综合网上各类说法,大致认为:
(1)Logger:适用于小型系统,当日志量过大时性能有待提升。好处在于JDK集成了此类,无需引入新包。且性能也在逐步改善当中,我认为一般而言,使用Logger即可。
(2)Log4J:并发性较好,性能较强,适用于大型系统。
本文介绍java.util.logging.Logger的详细用法。
1、基本概念
Logger中有2个比较重要的概念,分别是记录器(Logger)与处理器(Handler),二者分别完成以下功能:
(1)Logger:记录日志,设置日志级别等。
(2)Handler:确定输出位置等。
2、Logger相关
(1)一般通过getLogger来获取对象,而不能通过构造函数直接构造。
static Logger getLogger(String name)
static Logger getLogger(String name, String resourceBundleName)
Logger objects may be obtained by calls on one of the getLogger factory methods. These will either create a new Logger or return a suitable existing Logger.由于是通过工作获取到的对象,因此,若所传参数相同,则会返回同一个Logger对象。
(2)关于Logger的命名
Logger names can be arbitrary strings, but they should normally be based on the package name or class name of the logged component, such as java.net or javax.swing.
Logger原则上可以任意命名,但实际上一般是与Logger所在包或者所有类的名称相同。
(3)Logger的级别
- SEVERE(最高值)
- WARNING
- INFO
- CONFIG
- FINE
- FINER
- FINEST(最低值)
logger默认的级别是INFO,比INFO更低的日志将不显示。通过此属性,可以简单的修改Logger的级别,以达到开关日志的目的。
(4)Logger是具有层级关系的,比如org.abc.def会继承org.abc的一些属性。
3、Handler相关
(1)Handler 对象从 Logger 中获取日志信息,并将这些信息导出。例如,它可将这些信息写入控制台或文件中,也可以将这些信息发送到网络日志服务中,或将其转发到操作系统日志中。
(2)可通过执行 setLevel(Level.OFF) 来禁用 Handler,并可通过执行适当级别的 setLevel 来重新启用。
(3)默认情况下,使用ConsoleHandler,即将日志输出至控制台。可通过FileHandler,SocketHandler等,将日志导向其它地方。
4、基本示例
public static void main(String[] args) {
final Logger logger = Logger.getLogger("org.jediael.crawl.MyCrawler");
logger.info("Begin Crawling, Good Luck!");
//为每一个种子url,启动一个线程
Thread t = new Thread(new Runnable() {
@Override
public void run() {
logger.info(Thread.currentThread()+" start!!");
控制台输出如下:
六月 18, 2014 2:49:35 下午 org.jediael.crawl.MyCrawler main
信息: Begin Crawling, Good Luck!
六月 18, 2014 2:49:35 下午 org.jediael.crawl.MyCrawler$2 run
信息: Thread[Thread-1,5,main] start!!
六月 18, 2014 2:49:35 下午 org.jediael.crawl.MyCrawler$2 run
信息: Thread[Thread-4,5,main] start!!
六月 18, 2014 2:49:35 下午 org.jediael.crawl.MyCrawler$2 run
信息: Thread[Thread-3,5,main] start!!
六月 18, 2014 2:49:35 下午 org.jediael.crawl.MyCrawler$2 run
信息: Thread[Thread-2,5,main] start!!
(2)改变logger的级别
默认情况下,logger的级别为Info,它会处理info及其以上级别的日志;若将其提高至waring,则示例1中的日志将不再显示。
public static void main(String[] args) {
final Logger logger = Logger.getLogger("org.jediael.crawl.MyCrawler");
logger.setLevel(Level.WARNING);
logger.info("Begin Crawling, Good Luck!");
此时控制台无输出
(3)将日志输出至文件
final Logger logger = Logger.getLogger("org.jediael.crawl.MyCrawler");
logger.setLevel(Level.INFO);
FileHandler fileHandler = new FileHandler("d:\\1.log");
fileHandler.setLevel(Level.INFO);
logger.addHandler(fileHandler);
logger.info("Begin Crawling, Good Luck!");
此时日志同时输出至控制台及文件中。注意,未指定文件格式的情况下,日志输出格式为XML。
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE log SYSTEM "logger.dtd">
<log>
<record>
<date>2014-06-18T15:04:44</date>
<millis>1403075084407</millis>
<sequence>0</sequence>
<logger>org.jediael.crawl.MyCrawler</logger>
<level>INFO</level>
<class>org.jediael.crawl.MyCrawler</class>
<method>main</method>
<thread>1</thread>
<message>Begin Crawling, Good Luck!</message>
</record>
<record>
<date>2014-06-18T15:04:44</date>
<millis>1403075084471</millis>
<sequence>1</sequence>
若需要改变日志的输出格式,则需要使用Formatter。
如何才能只将日志输出到文件,而不输出至Console?
加上以下语句即可移除console中的输出。
logger.setUseParentHandlers(false);