Java Logging API 中的 SimpleFormatter
日志记录对于任何软件应用程序都非常有用,它有助于在多个场景中找出项目的执行情况。在Java, Java.util 包具有日志记录实用程序,并且以下导入对于日志记录非常必要。
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;
通过属性文件显示日志消息的规范:
在一个项目中,我们可以指定一个属性文件,它们会跟踪维护日志功能。其中,“Java.util.logging.ConsoleHandler.formatter”指定了要使用的Formatter类的名称,默认设置为Java.util.logging.SimpleFormatter ,它只是以纯文本形式显示日志条目。
Java
// Specification of SimpleFormatter in .properties file
java.util.logging.ConsoleHandler.formatter
= java.util.logging.SimpleFormatter
// Following are the different set of formats
// that are possible to give in the file We
// need to specify the format in a single line
// either like
java.util.logging.SimpleFormatter.format
= [ % 1 $tF % 1 $tT ][% 4 $ - 7s] % 5 $s
% n
// or
java.util.logging.SimpleFormatter.format
= "%1$tc %2$s%n%4$s: %5$s%6$s%n"
Java
/*
* Configuration: By default each ConsoleHandler
* is initialized using the following LogManager
* configuration properties. If properties are not
* defined (or have invalid values) then the specified
* default values are used.
* #"java.util.logging.ConsoleHandler.formatter"
* specifies the name of a Formatter class to use
* and the default setting is java.util.logging.SimpleFormatter,
* which is nothing but displaying log entries in the plain
* text.java.util.logging.ConsoleHandler.formatter
* = java.util.logging.SimpleFormatter
* java.util.logging.SimpleFormatter.format
* =[%1$tF %1$tT] [%4$-7s] %5$s %n
* #java.util.logging.SimpleFormatter.format
* ="%1$tc %2$s%n%4$s: %5$s%6$s%n"
* #java.util.logging.ConsoleHandler.level
* specifies the default level for the Handler
* (defaults to Level.INFO).
* #java.util.logging.ConsoleHandler.filter
* specifies the name of a Filter class to use
* (defaults to no Filter).
* #java.util.logging.ConsoleHandler.encoding
* the name of the character set encoding to use
* (defaults to the default platform encoding).
* #handlers= java.util.logging.ConsoleHandler
* #.level= FINE
* # default file output is in user's home directory.
* #Below specified are the other set of information for logging
*/
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
java.util.logging.ConsoleHandler.level = INFO
Java
// SimpleFormatter in Java Logging API
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 SimpleFormatterLoggingExample {
// create static logger object
static Logger loggerInformation = Logger.getLogger(
SimpleFormatterLoggingExample.class.getName());
public static void main(String[] args)
{
try {
// In mylogging.properties, necessary
// logging messages settings are given.
// First it has to be read
LogManager.getLogManager().readConfiguration(
new FileInputStream(
"mylogging.properties"));
}
catch (SecurityException | IOException e1) {
System.out.println(
"SecurityException message ,, "
+ e1.getMessage());
}
// There are different levels of setting
// loggerInformation default level is INFO if the
// value is not specified, for our example we have
// kept as INFO other available levels are ALL -
// 1,FINEST - 2,FINER - 3,FINE - 4,CONFIG - 5,INFO -
// 6,WARNING - 7,SEVERE - 8,OFF - 9
loggerInformation.setLevel(Level.FINE);
loggerInformation.addHandler(new ConsoleHandler());
// adding custom handler
loggerInformation.addHandler(new MyHandler());
try {
// FileHandler file name with max size and
// number of log files limit
Handler fileHandler
= new FileHandler("logger.log", 2000, 3);
fileHandler.setFormatter(new MyFormatter());
// setting custom filter for FileHandler
fileHandler.setFilter(new MyFilter());
loggerInformation.addHandler(fileHandler);
for (int i = 0; i < 5; i++) {
// logging messages
loggerInformation.log(
Level.INFO,
"Printing logger information " + i);
}
loggerInformation.log(Level.CONFIG,
"Config data is set");
}
catch (SecurityException | IOException e) {
System.out.println(
"SecurityException message ,, "
+ e.getMessage());
}
}
}
Java
// SimpleFormatter in Java Logging API
import java.util.logging.Logger;
public class SimpleFormatterUsingSystemProperty {
// Create static logger object with Null
private static Logger LOGGER = null;
// Static block
static
{
System.setProperty(
"java.util.logging.SimpleFormatter.format",
"[%1$tF %1$tT] [%4$-7s] %5$s %n");
// Logger to get logs
LOGGER = Logger.getLogger(
SimpleFormatterUsingSystemProperty
.class.getName());
}
// Driver code
public static void main(String[] args)
{
// Log information
LOGGER.info(
"Inside main method of SimpleFormatterUsingSystemProperty");
// Log warning
LOGGER.warning(
"a general warning message for the security");
}
}
Java
// SimpleFormatter in Java Logging API
import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class SimpleFormatterUsingProgramaticway {
// create static logger object with null value
private static Logger LOGGERINFORMATION = null;
// static block
static
{
Logger mainLogger
= Logger.getLogger("com.journaldev");
mainLogger.setUseParentHandlers(false);
ConsoleHandler handler = new ConsoleHandler();
// setting the required format to
// the ConsoleHandler object
handler.setFormatter(new SimpleFormatter() {
private static final String format
= "[%1$tF %1$tT] [%2$-7s] %3$s %n";
// Override format method
@Override
public synchronized String format(
LogRecord logRecord)
{
return String.format(
format, new Date(logRecord.getMillis()),
logRecord.getLevel().getLocalizedName(),
logRecord.getMessage());
}
});
// addHandler method with handler
// passed as parameter
mainLogger.addHandler(handler);
LOGGERINFORMATION = Logger.getLogger(
SimpleFormatterUsingProgramaticway
.class.getName());
}
public static void main(String[] args)
{
// log information
LOGGERINFORMATION.info(
"in SimpleFormatterUsingProgramaticway");
// Log warnings
LOGGERINFORMATION.warning("a general warning");
}
}
SimpleFormatter 的特点:
- SimpleFormatter 仅通过纯文本消息显示日志消息
- 从Java 7 开始,可以使用系统属性配置 SimpleFormatters。
- 由于是纯文本显示,任何人都可以轻松理解。显示基本信息。
- ConsoleHandler 使用此格式化程序类,并在控制台中打印日志消息。
执行:
示例 1:示例 mylogging.properties
Java
/*
* Configuration: By default each ConsoleHandler
* is initialized using the following LogManager
* configuration properties. If properties are not
* defined (or have invalid values) then the specified
* default values are used.
* #"java.util.logging.ConsoleHandler.formatter"
* specifies the name of a Formatter class to use
* and the default setting is java.util.logging.SimpleFormatter,
* which is nothing but displaying log entries in the plain
* text.java.util.logging.ConsoleHandler.formatter
* = java.util.logging.SimpleFormatter
* java.util.logging.SimpleFormatter.format
* =[%1$tF %1$tT] [%4$-7s] %5$s %n
* #java.util.logging.SimpleFormatter.format
* ="%1$tc %2$s%n%4$s: %5$s%6$s%n"
* #java.util.logging.ConsoleHandler.level
* specifies the default level for the Handler
* (defaults to Level.INFO).
* #java.util.logging.ConsoleHandler.filter
* specifies the name of a Filter class to use
* (defaults to no Filter).
* #java.util.logging.ConsoleHandler.encoding
* the name of the character set encoding to use
* (defaults to the default platform encoding).
* #handlers= java.util.logging.ConsoleHandler
* #.level= FINE
* # default file output is in user's home directory.
* #Below specified are the other set of information for logging
*/
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
java.util.logging.ConsoleHandler.level = INFO
示例 2:使用 mylogging.properties 的示例Java文件依次以纯文本形式显示日志消息
Java
// SimpleFormatter in Java Logging API
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 SimpleFormatterLoggingExample {
// create static logger object
static Logger loggerInformation = Logger.getLogger(
SimpleFormatterLoggingExample.class.getName());
public static void main(String[] args)
{
try {
// In mylogging.properties, necessary
// logging messages settings are given.
// First it has to be read
LogManager.getLogManager().readConfiguration(
new FileInputStream(
"mylogging.properties"));
}
catch (SecurityException | IOException e1) {
System.out.println(
"SecurityException message ,, "
+ e1.getMessage());
}
// There are different levels of setting
// loggerInformation default level is INFO if the
// value is not specified, for our example we have
// kept as INFO other available levels are ALL -
// 1,FINEST - 2,FINER - 3,FINE - 4,CONFIG - 5,INFO -
// 6,WARNING - 7,SEVERE - 8,OFF - 9
loggerInformation.setLevel(Level.FINE);
loggerInformation.addHandler(new ConsoleHandler());
// adding custom handler
loggerInformation.addHandler(new MyHandler());
try {
// FileHandler file name with max size and
// number of log files limit
Handler fileHandler
= new FileHandler("logger.log", 2000, 3);
fileHandler.setFormatter(new MyFormatter());
// setting custom filter for FileHandler
fileHandler.setFilter(new MyFilter());
loggerInformation.addHandler(fileHandler);
for (int i = 0; i < 5; i++) {
// logging messages
loggerInformation.log(
Level.INFO,
"Printing logger information " + i);
}
loggerInformation.log(Level.CONFIG,
"Config data is set");
}
catch (SecurityException | IOException e) {
System.out.println(
"SecurityException message ,, "
+ e.getMessage());
}
}
}
由于Java.util.logging.SimpleFormatter.format=[%1$tF %1$tT] [%4$-7s] %5$s %n 在“mylogging.properties”文件中设置,
输出:
同时, Java.util.logging.SimpleFormatter.format="%1$tc %2$s%n%4$s: %5$s%6$s%n"
输出可以是:
其他示例格式:
1. Java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"。在方括号中显示一行,其中包含日志级别 (4$)、日志消息 (5$) 和时间戳 (1$)。
例子:
WARNING: A general warning message in terms of security [Thu Jan 28 13:11:31 IST 2021]
2. Java.util.logging.SimpleFormatter.format="%1$tc %2$s%n%4$s: %5$s%6$s%n"。显示 2 行,第一行包括时间戳 (1$) 和来源 (2$),而第二行包括日志级别 (4$) 和日志消息 (5$),后跟 throwable 及其回溯(6$),以防万一。
例子:
Thu Jan 28 13:11:31 IST 2021 fatal
SEVERE: Exception raised and hence several messages are thrown with an exception
java.lang.IllegalArgumentException: invalid argument
3. Java.util.logging.SimpleFormatter.format=”%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n %4$s:%5$s%n”。显示 2 行类似于上面看到的示例,但显示不同的日期/时间格式。一个重要的区别是它不显示 throwable 及其回溯。
例子:
Thu Jan 28 13:11:31 IST 2021 fatal
SEVERE: Exception raised and hence several messages are thrown with an exception
通过在子类中覆盖。该方法可以被覆盖。通过 Formatter.formatMessage(Java.util.logging.LogRecord),可以对消息字段进行本地化和格式化。
也使用系统属性,我们可以进行格式化
Java
// SimpleFormatter in Java Logging API
import java.util.logging.Logger;
public class SimpleFormatterUsingSystemProperty {
// Create static logger object with Null
private static Logger LOGGER = null;
// Static block
static
{
System.setProperty(
"java.util.logging.SimpleFormatter.format",
"[%1$tF %1$tT] [%4$-7s] %5$s %n");
// Logger to get logs
LOGGER = Logger.getLogger(
SimpleFormatterUsingSystemProperty
.class.getName());
}
// Driver code
public static void main(String[] args)
{
// Log information
LOGGER.info(
"Inside main method of SimpleFormatterUsingSystemProperty");
// Log warning
LOGGER.warning(
"a general warning message for the security");
}
}
输出 :
设置格式的编程方式:
Java
// SimpleFormatter in Java Logging API
import java.util.Date;
import java.util.logging.ConsoleHandler;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;
public class SimpleFormatterUsingProgramaticway {
// create static logger object with null value
private static Logger LOGGERINFORMATION = null;
// static block
static
{
Logger mainLogger
= Logger.getLogger("com.journaldev");
mainLogger.setUseParentHandlers(false);
ConsoleHandler handler = new ConsoleHandler();
// setting the required format to
// the ConsoleHandler object
handler.setFormatter(new SimpleFormatter() {
private static final String format
= "[%1$tF %1$tT] [%2$-7s] %3$s %n";
// Override format method
@Override
public synchronized String format(
LogRecord logRecord)
{
return String.format(
format, new Date(logRecord.getMillis()),
logRecord.getLevel().getLocalizedName(),
logRecord.getMessage());
}
});
// addHandler method with handler
// passed as parameter
mainLogger.addHandler(handler);
LOGGERINFORMATION = Logger.getLogger(
SimpleFormatterUsingProgramaticway
.class.getName());
}
public static void main(String[] args)
{
// log information
LOGGERINFORMATION.info(
"in SimpleFormatterUsingProgramaticway");
// Log warnings
LOGGERINFORMATION.warning("a general warning");
}
}
输出 :
结论:
SimpleFormatter 是一种以人类可读的方式理解日志消息的更简单方法,包括时间戳、日志消息级别(如 INFO、WARNING 等)以及日志消息。还会显示引发异常的消息,以便更轻松地跟踪项目的整个流程。另一种格式,即 XMLFormatter 也可用,但它以 XML 方式显示消息。因此,SimpleFormatter 甚至对新手用户和普通用户也非常有用。