About the log level of java.util.logging.Logger

What is java.util.logging.Logger?

Java standard API. Output error information as a log according to the content.

how to use

First of all, the basic usage. The main appearances are the following three.

  1. Logger-An object that outputs logs.
  2. Handler --An object that controls the output destination of the log.
  3. Formatter-An object that controls the format of the log.

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.

Log level

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.

Confirmation by implementation

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

  1. Use getLogger () to generate a logger and set the log level

Generate a logger using the getLogger method of java.util.logging.Logger Specify the log level with the setLevel method

  1. Setting to output as a file (FileHandler)

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.

  1. Set standard output (ConsoleHandler)

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.

  1. Parent logger settings

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.

  1. Log settings

Each log level is output for log confirmation.

  1. Check the log when an error occurs

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.

Execution result

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.

filter

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.

Execution result

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.

Log output control

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.

image.png

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

Read property file

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.

Reference article

How to use java.util.logging

Recommended Posts

About the log level of java.util.logging.Logger
About the handling of Null
About the behavior of ruby Hash # ==
About the basics of Android development
About the role of the initialize method
Think about the 7 rules of Optional
Summary about the introduction of Device
About the version of Docker's Node.js image
What is testing? ・ About the importance of testing
About the operation of next () and nextLine ()
About the error message Invalid redeclaration of'***'
About the treatment of BigDecimal (with reflection)
About the number of threads of Completable Future
About the mechanism of the Web and HTTP
Log Level Memorandum
About the method
About the package
Think about the combination of Servlet and Ajax
About the official start guide of Spring Framework
About the description order of Java system properties
About the idea of anonymous classes in Java
Log4j 2 Understanding the underlying concepts of the log system
About next () and nextLine () of the Scanner class
About Java log output
Output about the method # 2
Format of the log output by Tomcat itself in Tomcat 8
About the StringBuilder class
The world of clara-rules (2)
Commentary: About the interface
About disconnect () of HttpURLConnection
About the asset pipeline
About the function double-java
[Grails] About the setting area and the setting items of application.yml
Talking about the merits of database bind variables ((1) Introduction)
About selection of OpenJDK
About the problem of deadlock in parallel processing in gem'sprockets' 4.0
About DI of Spring ①
About the ternary operator
Judgment of the calendar
How to set the log level to be displayed in the release version of orhanobut / logger
The world of clara-rules (1)
The world of clara-rules (3)
About the length method
Development of factor level
About the Kernel module
The idea of quicksort
About the authenticate method.
[Technical memo] About the advantages and disadvantages of Ruby
Find the approximate value of log (1 + x) in Swift
About the map method
About the ancestors method
About form. ○○ of form_with
[Output] About the database
About @Accessors of Lombok
About the [ruby] operator
About the to_s method.
The idea of jQuery
About the function of Spring Boot due to different versions
About truncation by the number of bytes of String on Android
[Ruby] Questions and verification about the number of method arguments
I want to change the log output settings of UtilLoggingJdbcLogger