Java standard API. Output error information as a log according to the content.
First of all, the basic usage. The main appearances are the following three.
First, create a Logger instance.
Logger logger = Logger.getLogger("logger name")
Next, create a Handler instance and register it with logger. You can register multiple Handlers. This time, create a Handler with C: \ sample \ sample.log as the output destination. If you want to output to a file, use the Handler interface implementation class FileHandler.
Handler handler = new FileHandler("C:\\sample\\sample.log");
logger.addHandler(handler);
Finally, create a Formatter instance and register it with Handler. This time, we will use SimpleFormatter to format it in a form that is easy for humans to read. SimpleFormatter is an implementation class of the Formatter interface.
Formatter formatter = new SimpleFormatter();
handler.setFormatter(formatter);
Now you are ready to go. Pass the message to logger and output the log.
Specify the log level when outputting the log. You can set the following request levels:
Logger method | Corresponding request level | Output name |
---|---|---|
-- | Level.ALL | -- |
Logger.finest() | Level.FINEST | Most detailed |
Logger.finer() | Level.FINER | Details |
Logger.fine() | Level.FINE | usually |
Logger.config() | Level.CONFIG | Constitution |
Logger.info() | Level.INFO | information |
Logger.warning() | Level.WARNING | warning |
Logger.severe() | Level.SEVERE | Serious |
For example, if Level.CONFIG is set, the log output will be "Configuration", "Information", "Warning", "Critical", and below the set level. Level.ALL, as the name implies, displays everything.
Check the actual log output by the following implementation.
Log
public class Log {
public static Logger getLog(String name) {
//Generate logger
Logger logger = Logger.getLogger(name);
try {
//Handler generation (true):writing,false:Overwrite)
Handler handler = new FileHandler("/log/sample.log", false);
//Specifying log format by SimpleFormat
handler.setFormatter(new SimpleFormatter());
//Specifying the log level/Handler settings
logger.addHandler(handler);
logger.setLevel(Level.ALL);
//Standard output settings
ConsoleHandler consoleHandler = new ConsoleHandler();
consoleHandler.setLevel(Level.CONFIG);
logger.addHandler(consoleHandler);
//Parent logger settings(true:Send to parent logger,false:Send to parent loggerしない)
logger.setUseParentHandlers(false);
//Log output
logger.finest("FNST");
logger.finer("FNR");
logger.fine("FN");
logger.config("CFG");
logger.info("INF");
logger.warning("WNG");
logger.severe("SVR");
throw new IOException();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
logger.log(Level.CONFIG, "Error occurred", e);
logger.warning("WNG:Error occurred");
}
return logger;
}
}
This class will be a class that wraps java.util.logging.Logger
Check the log behavior by calling the getLog () method with the class name as an argument
Generate a logger using the getLogger method of
java.util.logging.Logger
Specify the log level with the setLevel method
Set the log file location, format, and log level. Use FileHandler to set the first argument: file path, second argument: overwrite / append true is overwritten and false is added. This time, I want to see the behavior when it is executed once, so set it to true Set the log format for the generated handler By default, the log is output in XML format, but it is difficult to see, so set it to output in Japanese with SimpleFormatter (). You can set the log level in handler and set logger to output only messages above a certain log level. This time, by setting ALL, all log output will be described in the file.
By setting ConsoleHandler, the contents of the log can be checked on the console as well. The setting method can be done by using the addHandler () method as well as FileHandler. Set the log level for standard output as well so that logs above CONFIG are output.
False is set, but if it is set to true, standard output below the required level is displayed twice or the level does not match. What is displayed twice is that the created log is sent to the parent logger, so the log registered in the parent logger will be output.
Each log level is output for log confirmation.
I have raised an IOException and linked it to the log when the last error occurred.
Create a maiin class and call it to check its behavior.
Sample.log
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Most detailed: FNST
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Details: FNR
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
usually: FN
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Constitution: CFG
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
information: INF
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
warning: WNG
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Serious: SVR
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Constitution:Error occurred
java.io.IOException
at app.abstractDemo.log.Log.getLog(Log.java:43)
at app.abstractDemo.MainActivity.main(MainActivity.java:10)
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
warning: WNG:Error occurred
Thanks to SimpleFormatter (), I was able to confirm that the log was modified to be output in Japanese instead of XML format. All logs are output because the log level of logger is set to ALL.
Standard output
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Constitution: CFG
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
information: INF
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
warning: WNG
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Serious: SVR
java.io.IOException
at app.abstractDemo.log.Log.getLog(Log.java:43)
at app.abstractDemo.MainActivity.main(MainActivity.java:10)
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
Constitution:Error occurred
java.io.IOException
at app.abstractDemo.log.Log.getLog(Log.java:43)
at app.abstractDemo.MainActivity.main(MainActivity.java:10)
9 21, 2020 2:18:27 am app.abstractDemo.log.Log getLog
warning: WNG:Error occurred
Since the log level of consoleHandler is set in CONFIG, it was confirmed that logs higher than CONFIG are output.
I introduced how to set the log level in the logger and control it so that only messages above a certain log level are output, but if you want more detailed control, use the Filter class.
Filter filter = new Filter() {
@Override
public boolean isLoggable(LogRecord record) {
return record.getMessage().contains("Number of cases processed=");
}
};
logger.setFilter(filter);
If Filter is set as above, only logs that include "number of processes =" will be output in the message. Add the following record to the implementation and check the process
Log
//Set a filter on the logger
Filter filter1 = new Filter() {
@Override
public boolean isLoggable(LogRecord record) {
return record.getMessage().contains("Number of cases processed=");
}
};
logger.setFilter(filter1);
logger.info("Sample message"); //Not output
logger.info("Sample message,Number of cases processed=1"); //Output
//Set a filter on the handler
Filter filter2 = (record) -> record.getMessage().contains("Number of updates=");
handler.setFilter(filter2);
logger.info("Sample message"); //Not output
logger.info("Sample message,Number of cases processed=1"); //Not output
logger.info("Sample message,Number of cases processed=1,Number of updates=1"); //Output
//Set log level in handler
handler.setLevel(Level.WARNING);
logger.info("Sample message"); //Not output
logger.info("Sample message,Number of cases processed=1"); //Not output
logger.info("Sample message,Number of cases processed=1,Number of updates=1"); //Not output
logger.warning("Warning message,Number of cases processed=1,Number of updates=1"); //Output
It is assumed that only the log that is written as commented by the filter and log level will be output.
sample.log
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1,Number of updates=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
warning: warningメッセージ,Number of cases processed=1,Number of updates=1
Three logs are output as expected.
Standard output
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1,Number of updates=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
information:Sample message,Number of cases processed=1,Number of updates=1
9 21, 2020 12:14:03 afternoon app.abstractDemo.log.Log getLog
warning: warningメッセージ,Number of cases processed=1,Number of updates=1
Since no filter is set in consoleHandler, only the filter setting set in logger is applied. Therefore, the "number of processes =" set in filler1 and the log level "CONFIG" set in consoleHandler are applied and output.
The log level filter set for the logger is checked only by the directly called logger. The log level filter check set in the handler is checked by all handlers including the handler of the parent logger. Roughly speaking, the log output logic is as shown in the figure below.
The log level filter set on the logger is checked only on the first logger that receives the call, whereas it is checked. The log level filter set in the handler is checked by all handlers.
Since the logger settings are made only at the time of calling, they are not propagated to the parent logger, and the log may not be output as expected. For example, parent logger: WARNING, child logger: FINE Handler: ALL
When set in, the log set in FINE is output even though the log level is set in WARNING in the parent logger. This is because the handler settings are inherited and checked, so it looks like the parent logger is not set. The settings can be applied by changing to the following settings. Parent logger / child logger: ALL Handler: WRANING
If you write the log settings on the source, it will be complicated and difficult to read.
The method to read the configuration file from the program is as follows. This time, logging.properties located in the same classpath of the sample program is read. The configuration file should be read in java.util.Properties format.
LogManager.getLogManager().readConfiguration(SettingFileSample.class.getResourceAsStream("logging.properties"));
The sample configuration file is as follows. Please refer to {java.home} \ lib \ logging.properties for detailed explanation.
logging.properties
#Root logger handler log level setting ConsoleHandler has a standard error(System.err)Output the log to.
handlers=java.util.logging.ConsoleHandler
.level=INFO
#Logger used in the sample program"sample.SettingFileSample"settings of
sample.SettingFileSample.level=FINE
sample.SettingFileSample.handlers=java.util.logging.FileHandler
#ConsoleHandler settings
java.util.logging.ConsoleHandler.level=INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
#FileHandler settings
java.util.logging.FileHandler.pattern=C:/sample/sample.log
java.util.logging.FileHandler.limit=1000
java.util.logging.FileHandler.count=1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
The sample program using the above configuration file is described below.
SettingFileSample
public class SettingFileSample {
public static void main(String[] arg) throws SecurityException, IOException {
LogManager.getLogManager().readConfiguration(SettingFileSample.class.getResourceAsStream("logging.properties"));
Logger logger = Logger.getLogger("sample.SettingFileSample");
logger.finer("FINER message");
logger.fine("FINE message");
logger.info("INFO message");
}
}
It's neat because there are no logger or handler settings.
Recommended Posts