This is the 12th day of my participation in the August Text Challenge.More challenges in August

@TOC

Log implementation JUL, logback, log4j, log4j2

  • Loggers: Called Loggers, applications publish logs by taking Logger objects and calling their APIS. Logger is usually the entry program for applications to access the logging system.
  • Appenders: Also called Handlers, each Logger is associated with a set of Handlers, and the Logger hands the logs to the Handlers, who take care of the logging. Handlers are an abstraction whose concrete implementation determines the location of logging, whether in a console, a file, other logging services on the network, or operating system logs.
  • Also known as Formatters, Layouts transform and format data in log events. Layouts determine the final form of data in a log record.
  • Level: Each log message has an associated log Level. This Level gives a rough guide to the importance and urgency of log messages, and I can associate Level with Loggers and Appenders so that we can filter messages.
  • Filters: Filters that customize what information is recorded and what information is left out as needed.

JUL log Level java.util.logging.level

The levels are listed in descending order as follows:

  • SEVERE (Maximum) : SEVERE indicates the message level indicating a critical failure
  • WARNING: WARNING is the message level indicating a potential problem
  • INFO: INFO is the message level for reporting messages
  • CONFIG: CONFIG is the message level for statically configuring messages
  • FINE: FINE is the message level that provides trace information
  • FINER: FINEST indicates the most detailed trace message
  • FINEST (lowest value) : FINEST indicates the most detailed trace message

Special level

  • OFF: Can be used to disable logging.
  • ALL: Enables the logging of ALL messages.

Example explanation function

Create a Maven project because juL is a log provided by Java’s JDK, so there is no need to add jar packages. Use it directly.

JULTest Test method Different log output methods

Get the logger and print the log using a different method.

/** * Java native log jul test */
public class JULTest {
    @Test
    public void  test(a){
        // Get the logger object
        Logger logger = Logger.getLogger("cn.ling.logs.JULTest");
        // Log output
        logger.info("Hello JUL");
        // General method for logging
        logger.log(Level.INFO, "JUL log");
        // Output variable values as placeholders
        logger.log(Level.INFO,User information: {0},{1}.new Object[]{"Little beauty".18}); }}Copy the code

Output result:

March17.2021 2:13:02PM cn.ling.logs.JULTest Test information: Hello JUL March17.2021 2:13:02PM cn.ling.logs.JULTest Test information: JUL log March17.2021 2:13:02Afternoon cn.ling.logs.JULTest Test information: User information: Xiaomei,18
Copy the code

TestLogConsoleConfig method console output test

The following is only the test method code, put in the above test class can be:

Execute code using the default log level Info:

@Test
    public void testLogConsoleConfig(a){
        // Get the logger object
        Logger logger = Logger.getLogger("cn.ling.logs.JULTest");
        logger.severe("severe");
        logger.warning("warning");
        logger.info("info");
        logger.config("config");
        logger.fine("fine");
        logger.finer("finer");
        logger.finest("finest");
    }
Copy the code

Output result: Logs whose log level is lower than INFO are not output:

March17.2021 2:17:52Afternoon cn.ling.logs.JULTest testLogConsoleConfig Severe: Severe March17.2021 2:17:52PM cn.ling.logs.JULTest testLogConsolfig Warning: Warning March17.2021 2:17:52Afternoon cn.ling.logs.JULTest testLogConsoleConfig Information: infoCopy the code

Close the default log level: the logger. SetUseParentHandlers (false)

@Test
    public void testLogConsoleConfig(a){
        // Get the logger object
        Logger logger = Logger.getLogger("cn.ling.logs.JULTest");
        // Turn off the default log level
        logger.setUseParentHandlers(false);

        // Output to the console
        ConsoleHandler consoleHandler = new ConsoleHandler();

        // Output format
        SimpleFormatter simpleFormatter = new SimpleFormatter();
        consoleHandler.setFormatter(simpleFormatter);
        // Outputs the log level of the console
        consoleHandler.setLevel(Level.ALL);

        logger.addHandler(consoleHandler);
        // Log output level
        logger.setLevel(Level.CONFIG);

        logger.severe("severe");
        logger.warning("warning");
        logger.info("info");
        logger.config("config");
        logger.fine("fine");
        logger.finer("finer");
        logger.finest("finest");
    }
Copy the code

Consolehandler. setLevel(level.all); Output all; logger.setLevel(Level.CONFIG); Output the config level. The output standard is the one with the smallest range, that is, the highest log level

March17.2021 2:23:15Afternoon cn.ling.logs.JULTest testLogConsoleConfig Severe: Severe March17.2021 2:23:15PM cn.ling.logs.JULTest testLogConsolfig Warning: Warning March17.2021 2:23:15PM cn.ling.logs.JULTest testLogConsoleConfig Information: info March17.2021 2:23:15Afternoon cn.ling.logs.JULTest testLogConsoleConfig Configuration: configCopy the code

If the logger setUseParentHandlers (false) is not set to false, will repeat above info output log. The following

March17.2021 2:26:30Afternoon cn.ling.logs.JULTest testLogConsoleConfig Severe: Severe March17.2021 2:26:30Afternoon cn.ling.logs.JULTest testLogConsoleConfig Severe: Severe March17.2021 2:26:30PM cn.ling.logs.JULTest testLogConsolfig Warning: Warning March17.2021 2:26:30PM cn.ling.logs.JULTest testLogConsolfig Warning: Warning March17.2021 2:26:30PM cn.ling.logs.JULTest testLogConsoleConfig Information: info March17.2021 2:26:30PM cn.ling.logs.JULTest testLogConsoleConfig Information: info March17.2021 2:26:30Afternoon cn.ling.logs.JULTest testLogConsoleConfig Configuration: configCopy the code

TestLogFileConfig method output file test

@Test
    public void testLogFileConfig(a) throws IOException {
        // Get the logger object
        Logger logger = Logger.getLogger("cn.ling.logs.JULTest");
        // Turn off the default log level
        logger.setUseParentHandlers(false);

        // Output to the console
        ConsoleHandler consoleHandler = new ConsoleHandler();

        // Output format
        SimpleFormatter simpleFormatter = new SimpleFormatter();
        consoleHandler.setFormatter(simpleFormatter);
        // Outputs the log level of the console
        consoleHandler.setLevel(Level.ALL);

        FileHandler fileHandler = new FileHandler("D:/logs/jul.log");
        fileHandler.setFormatter(simpleFormatter);
        logger.addHandler(fileHandler);

        // Log output level
        logger.setLevel(Level.CONFIG);

        logger.severe("severe");
        logger.warning("warning");
        logger.info("info");
        logger.config("config");
        logger.fine("fine");
        logger.finer("finer");
        logger.finest("finest");
    }
Copy the code

Output result:

java.nio.file.NoSuchFileException: D:\logs\jul.log.lck

	at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79)
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97)
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102)
	at sun.nio.fs.WindowsFileSystemProvider.newFileChannel(WindowsFileSystemProvider.java:115)
	at java.nio.channels.FileChannel.open(FileChannel.java:287)
	at java.nio.channels.FileChannel.open(FileChannel.java:335)
	at java.util.logging.FileHandler.openFiles(FileHandler.java:459)
	at java.util.logging.FileHandler.<init>(FileHandler.java:292)
	at cn.ling.logs.JULTest.testLogFileConfig(JULTest.java:73)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
	at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
	at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Copy the code

The output directory does not exist and needs to be added

Parent relationship of log objects

The description in the above code is more detailed, the following code, if the description is not detailed enough, I hope to try to try, here just put the code out.

@Test
    public void testLogParent(a){
        Logger loggerF = Logger.getLogger("cn.ling.logs");
        Logger loggerS = Logger.getLogger("cn.ling.logs.JULTest");
        System.out.println("LoggerF ==loggerS result:"+(loggerF==loggerS.getParent()));//true

        // Disable the default configuration. If changed to true, child and parent log objects print logs
        loggerF.setUseParentHandlers(false);
        ConsoleHandler consoleHandler = new ConsoleHandler();
        SimpleFormatter simpleFormatter = new SimpleFormatter();
        consoleHandler.setFormatter(simpleFormatter);
        loggerF.addHandler(consoleHandler);
        loggerF.setLevel(Level.ALL);
        consoleHandler.setLevel(Level.ALL);
        // Log level
        loggerS.severe("severe");
        loggerS.warning("warning");
        loggerS.info("info");
        loggerS.config("config");
        loggerS.fine("fine");
        loggerS.finer("finer");
        loggerS.finest("finest");
    }
Copy the code

** Output result: ** why more logs than the above output, because the log level is different.

LoggerF == loggerF result: true March 17, 2021 2:34:52 PM cn.ling.logs.JULTest testLogParent Serious: Severe March 17, 2021 2:34:52 PM cn.ling.logs.JULTest testLogParent Warning: Warning March 17, 2021 2:34:52 PM cn.ling.logs.JULTest testLogParent Info March 17, 2021 2:34:52 PM cn.ling.logs.JULTest testLogParent config: Config March 17, 2021 2:34:52 PM cn.ling.logs.JULTest testLogParent Fine March 17, 2021 2:34:52 PM cn.ling.logs.JULTest testLogParent Finer March 17, 2021 2:34:52 PM CN.ling.logs.JULTest testLogParent finer March 17, 2021 2:34:52 PM finer March 17, 2021 2:34:52 PM CN.ling.logsCopy the code

TestLogProperties Configuration file

Create the configuration file logging.properties

#Handler used by #RootLogger (set when fetched) : top-level parent element
handlers=java.util.logging.ConsoleHandler,java.util.logging.FileHandler
#RootLogger Log level
.level=INFO

## Customize Logger
#cn.ling.handlers=java.util.logging.FileHandler
#Customize Logger log levels
#cn.ling.level=INFO
#Ignore the parent logging Settings
#cn.ling.useParentHandlers=false


## Console processor
#Output Log Level
java.util.logging.ConsoleHandler.level=INFO
#Specifies the character set of the handler object
java.util.logging.ConsoleHandler.encoding=UTF-8
#Output Log format
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter

## File handler
#Output Log Level
java.util.logging.FileHandler.level=INFO
#Specify handler object Log message format object SimpleFormatter or XMLFormatter
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
#Path of the output log file
java.util.logging.FileHandler.pattern=D:/logs/jul.log
#Output log file size limit (50000 bytes)
java.util.logging.FileHandler.limit=50000
#Limit the number of output log files
java.util.logging.FileHandler.count=10
#Whether the output log file is appended (does not overwrite the preceding log)
java.util.logging.FileHandler.append=true

#Specifies the log message format
java.util.logging.SimpleFormatter.format = %4$s: %5$s [%1$tc]%n
Copy the code

Test code:

	@Test
    public void testLogProperties(a) throws IOException {
        InputStream resourceAsStream = JULTest.class.getClassLoader().getResourceAsStream("logging.properties");
        Logger logger = Logger.getLogger("cn.ling.logs.JULTest");
        LogManager manager = LogManager.getLogManager();
        manager.readConfiguration(resourceAsStream);
        logger.severe("severe");
        logger.warning("warning");
        logger.info("info");
        logger.config("config");
        logger.fine("fine");
        logger.finer("finer");
        logger.finest("finest");
    }
Copy the code

The console output is as follows:

[Wednesday March17 14:39:00 CST 2021[Wednesday March17 14:39:00 CST 2021Info: info [Wednesday march17 14:39:00 CST 2021]
Copy the code

The ** log file is as follows: ** repeated because I executed twice.

Log Principle Analysis

  1. Initialize LogManager LogManager load logging.properties configuration add Logger to LogManager
  2. Get the Logger from the singleton LogManager
  3. Set the Level Level and specify LogRecord
  4. Filters provide more fine-grained control beyond the log level
  5. Handler is used to handle the log output location
  6. The Formatter is used to format the LogRecord