今天我们将研究Java中的Logger。Java Logger提供了java编程的日志记录。
目录[ 隐藏 ]
Java Logging API在1.4中引入,您可以使用java logging API来记录应用程序消息。在这个java日志教程中,我们将学习Java Logger的基本功能。我们还将研究不同日志记录级别的Java Logger示例,日志处理程序,格式化程序,过滤器,日志管理器和日志记录配置。
java.util.logging.Logger
是用于在java logging API中记录应用程序消息的类。
我们可以使用非常简单的一行代码创建java Logger;
Logger logger = Logger.getLogger(MyClass.class.getName());
java.util.logging.Level
定义了不同级别的java日志记录。java中有七个级别的日志记录。
还有另外两个日志记录级别,OFF将关闭所有日志记录,ALL将记录所有消息。
我们可以使用以下代码设置记录器级别:
logger.setLevel(Level.FINE);
将为所有等于或大于记录器级别的级别生成日志。例如,如果将记录器级别设置为INFO,则将为INFO,WARNING和SEVERE日志记录消息生成日志。
我们可以向java记录器添加多个处理程序,每当我们记录任何消息时,每个处理程序都会相应地处理它。Java Logging API提供了两个默认处理程序。
我们也可以创建自己的自定义处理程序来执行特定任务。要创建我们自己的Handler类,我们需要扩展java.util.logging.Handler类或其任何子类,如StreamHandler,SocketHandler等。
以下是自定义Java日志记录处理程序的示例:
package com.journaldev.log;
import java.util.logging.LogRecord;
import java.util.logging.StreamHandler;
public class MyHandler extends StreamHandler {
@Override
public void publish(LogRecord record) {
//add own logic to publish
super.publish(record);
}
@Override
public void flush() {
super.flush();
}
@Override
public void close() throws SecurityException {
super.close();
}
}
格式化程序用于格式化日志消息。java logging API中有两个可用的格式化程序。
我们可以通过扩展java.util.logging.Formatter
类并将其附加到任何处理程序来创建我们自己的自定义Formatter类。以下是一个简单的自定义格式化程序类的示例。
package com.journaldev.log;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
public class MyFormatter extends Formatter {
@Override
public String format(LogRecord record) {
return record.getThreadID()+"::"+record.getSourceClassName()+"::"
+record.getSourceMethodName()+"::"
+new Date(record.getMillis())+"::"
+record.getMessage()+"\n";
}
}
java.util.logging.LogManager
是读取日志记录配置,创建和维护记录器实例的类。我们可以使用此类来设置我们自己的应用程序特定配置。
LogManager.getLogManager().readConfiguration(new FileInputStream("mylogging.properties"));
以下是Java Logging API配置文件的示例。如果我们不指定任何配置,则从JRE Home lib/logging.properties
文件中读取。
mylogging.properties
handlers= java.util.logging.ConsoleHandler
.level= FINE
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# 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
com.journaldev.files = SEVERE
这是一个简单的java程序,显示了Java中Logger的用法。
package com.journaldev.log;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
public class LoggingExample {
static Logger logger = Logger.getLogger(LoggingExample.class.getName());
public static void main(String[] args) {
try {
LogManager.getLogManager().readConfiguration(new FileInputStream("mylogging.properties"));
} catch (SecurityException | IOException e1) {
e1.printStackTrace();
}
logger.setLevel(Level.FINE);
logger.addHandler(new ConsoleHandler());
//adding custom handler
logger.addHandler(new MyHandler());
try {
//FileHandler file name with max size and number of log files limit
Handler fileHandler = new FileHandler("/Users/pankaj/tmp/logger.log", 2000, 5);
fileHandler.setFormatter(new MyFormatter());
//setting custom filter for FileHandler
fileHandler.setFilter(new MyFilter());
logger.addHandler(fileHandler);
for(int i=0; i<1000; i++){
//logging messages
logger.log(Level.INFO, "Msg"+i);
}
logger.log(Level.CONFIG, "Config data");
} catch (SecurityException | IOException e) {
e.printStackTrace();
}
}
}
当您运行上面的java logger示例程序时,您会注意到CONFIG日志未在文件中打印,这是因为MyFilter类。
package com.journaldev.log;
import java.util.logging.Filter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class MyFilter implements Filter {
@Override
public boolean isLoggable(LogRecord log) {
//don't log CONFIG logs in file
if(log.getLevel() == Level.CONFIG) return false;
return true;
}
}
输出格式也与MyFormatter类定义的相同。
1::com.journaldev.log.LoggingExample::main::Sat Dec 15 01:42:43 PST 2012::Msg977
1::com.journaldev.log.LoggingExample::main::Sat Dec 15 01:42:43 PST 2012::Msg978
1::com.journaldev.log.LoggingExample::main::Sat Dec 15 01:42:43 PST 2012::Msg979
1::com.journaldev.log.LoggingExample::main::Sat Dec 15 01:42:43 PST 2012::Msg980
如果我们不将自己的Formatter类添加到FileHandler,则会像这样打印日志消息。
<record>
<date>2012-12-14T17:03:13date>
<millis>1355533393319millis>
<sequence>996sequence>
<logger>com.journaldev.log.LoggingExamplelogger>
<level>INFOlevel>
<class>com.journaldev.log.LoggingExampleclass>
<method>mainmethod>
<thread>1thread>
<message>Msg996message>
record>
控制台日志消息的格式如下:
Dec 15, 2012 1:42:43 AM com.journaldev.log.LoggingExample main
INFO: Msg997
Dec 15, 2012 1:42:43 AM com.journaldev.log.LoggingExample main
INFO: Msg998
Dec 15, 2012 1:42:43 AM com.journaldev.log.LoggingExample main
INFO: Msg998
下图显示了最终的Java Logger示例项目。