当前位置:网站首页>Alternative to log4j

Alternative to log4j

2022-06-25 00:14:00 MicroStone

last year 12 month , With log4j Expose high-risk vulnerabilities , about Java Not good news for developers , about Ops Even more so . The former must be fixed Log4J Version repackaging their application , The latter must be redeployed . But for the program log Come on , It's not just . Today let's take a look at java System native log Mechanism

In short ,System.Logger It is a part of the log engine API. Instead of using SFL4J Of API And what you want to achieve , Better use System.Logger.Java 9 Start java It's already open System.Logger, But I only recently learned about it , This is really regrettable .

System.Logger API

The API With other logging API It's a little different : It avoids different logging methods , for example debug(), Support the transfer of logging parameters info() One way .log()``Level

1.png
If you don't provide any corresponding implementation on the classpath , be System.Logger The default is JUL.

public class LoggerExample {

  private static final System.Logger LOGGER = System.getLogger("c.f.b.DefaultLogger"); // 1

  public static void main(String[] args) {
      LOGGER.log(DEBUG, "A debug message");
      LOGGER.log(INFO, "Hello world!");
  }
}
  1. Get recorder .

Running the above code snippet will output the following :

Dec 24, 2021 10:38:15 AM c.f.b.DefaultLogger main
INFO: Hello world!

Widely compatible with other logging systems

Most applications currently use Log4J2 or SLF4J. Both provide compatible System.Logger Realization .

about Log4J, We need to add two dependencies :

<dependencies>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>            <!-- 1 -->
        <version>2.17.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>    <!-- 2 -->
        <artifactId>log4j-jpl</artifactId>
        <version>2.17.0</version>
    </dependency>
</dependencies>
  1. Log4J Realization System.Logger
  2. System.Logger From to Log4J Support for .

The same logging fragment as above now outputs the following :

11:00:07.373 [main] INFO  c.f.b.DefaultLogger - Hello world!

To use instead SLF4J, You need to add the following dependencies :

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-simple</artifactId>               <!-- 1 -->
        <version>2.0.0-alpha5</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk-platform-logging</artifactId> <!-- 2 -->
        <version>2.0.0-alpha5</version>
    </dependency>
</dependencies>
  1. Basic SLF4J Realization . Any other implementation can , for example Logback.
  2. System.Logger From to SLF4J Support for .
[main] INFO c.f.b.DefaultLogger - Hello world!

Your own System.Logger Realization

System.Logger Depend on Java Of ServiceLoader Mechanism . both log4j-jpl contain slf4j-jdk-platform-logging One META-INF/services/java.lang.System$LoggerFinder Point to LoggerFinder Implementation files .

2.png
We can base it on System.out Purpose to create our own log system .\
The first step is to implement the log itself .

public class ConsoleLogger implements System.Logger {

    private final String name;

    public ConsoleLogger(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean isLoggable(Level level) {
        return level.getSeverity() >= Level.INFO.getSeverity();
    }

    @Override
    public void log(Level level, ResourceBundle bundle, String msg, Throwable thrown) {
        if (isLoggable(level)) {
            System.out.println(msg);
            thrown.printStackTrace();
        }
    }

    @Override
    public void log(Level level, ResourceBundle bundle, String format, Object... params) {
        if (isLoggable(level)) {
            System.out.println(MessageFormat.format(format, params));
        }
    }
}

then , We need to write code System.LoggerFinder:

public class ConsoleLoggerFinder extends System.LoggerFinder {

    private static final Map<String, ConsoleLogger> LOGGERS = new HashMap<>(); // 1

    @Override
    public System.Logger getLogger(String name, Module module) {
        return LOGGERS.computeIfAbsent(name, ConsoleLogger::new);              // 2
    }
}

Keep the path of all existing logs :

  1. If it doesn't exist , Then create a recorder and store it .

Last , We create a service file :

ch.frankel.blog.ConsoleLoggerFinder

Now? , Run the same code snippet output :

Hello world!

Conclusion

although API Compared with other more mature logging systems API More limited , But this System.Logger It's a good choice . It provides as JDK Part of api. therefore , It avoids other third parties api Vulnerability risk , for example SLF4J To Log4J2.

For this reason , Later can be based on System.Logger Realize the system log function .

原网站

版权声明
本文为[MicroStone]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202210955008323.html