Diese neuen Funktionen nach Java 8 (3): Java System Logger

Eine Schwachstelle im log4j-Logging-Framework im Dezember letzten Jahres hatte sehr große Auswirkungen auf die gesamte Java-Industrie. Dieser Vorfall brachte auch das log4j-Logging-Framework in den Vordergrund der Kontroverse.

In der Java-Welt ist log4j wahrscheinlich relativ beliebt. Neben log4j kennen oder hören Java-Programmierer möglicherweise auch einige Protokollierungs-Frameworks wie jul, slf4j und logback.

Aber es gibt tatsächlich noch eine andere, die wahrscheinlich nicht wenige Programmierer kennen:

Java 9 führt die Protokollierungsstandardschnittstelle System Logger ein

Dieser Artikel ist der dritte einer Reihe von Neuerungen nach Java 8 . Weitere Artikel dieser Reihe sind:

  1. Diese neuen Funktionen nach Java 8 (1): lokale Variable var
  2. Diese neuen Funktionen nach Java 8 (2): Textblöcke

JULI

Tatsächlich hat Java zusätzlich zu den populären Logging-Frameworks log4j und slf4j die java.util.logging-Log-Implementierung in Version 1.4 eingeführt.

Aber das Protokoll, das mit Java geliefert wird, ist nicht wirklich populär geworden, es gibt heute weit weniger Leute, die davon wissen, als diejenigen, die von den populären Protokollierungs-Frameworks wie log4j wissen.

Wenn Sie in Code sprechen, lautet das java.util.logging-Beispiel wie folgt:

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.logging.Level;
import java.util.logging.Logger;

public class TestJavaUtilLogging {

    private static Logger logger = Logger.getLogger(TestJavaUtilLogging.class.getName());

    @Test
    void testLogger(){
        logger.log(Level.INFO,"这是一个java.util.logging.Logger日志");
    }
}
复制代码

Der Grund, warum diese Logging-Tool-Klasse nicht beliebt ist, ist, dass sie viele Probleme hat, das größte ist, dass ihre Leistung weit unter der von log4j liegt.

log4j, der De-facto-Mainstream

Zumindest in der Java-Welt, in der Java 8 der Mainstream ist, hat Java selbst lange Zeit keine Standards für die Protokollierung, und java.util.logging ist eine Implementierung, kein Standard, und fast eine weniger bekannte Implementierung.

Als Referenz gibt es in der Java-Welt zwei Standards, mit denen wir Programmierer sehr vertraut sind.

Einer ist der JPA-Standard, Hibernate oder Eclipselink implementieren alle den JPA-Standard. Und das Spring Data Jpa, das jeder viel verwendet, ist eigentlich eine Kapselungsschicht, die auf dem Ruhezustand basiert.

另一个就是javax.annotation。类似Spring Bean IOC框架,Guice依赖注入框架,它们同样都支持了javax.annotaion。

而在Java日志系统这个领域,很长一段时间,本身并未有标准。

用的最多的log4j,成为了事实上的主流。

slf4j,试图定义一个标准

我认为有相当一部分人对slf4jj这个认知可能并不是很正确,把它当成和log4j一样的日志框架去理解。

但其实并不是。slf4j理论上并不能和log4j,logback放在一起说,它们是不同级别的东西。

slf4j的全称是:The Simple Logging Facade for Java,用中文来描述就是,Java简单日志门面

slf4j并不是一个日志实现,它是接口与抽象,它的角色非常类似于JPA以及javax.annotation这样的东西。 虽然slf4j自身提供了一个默认的空实现,但那其实什么意义都没有。

你必须将slf4j + log4j或者slf4j + logback这样的搭配起来用才行。slf4j是接口,而log4j与logback是实现。

是不是和JPA很相似?是的,slf4j的目的就是希望给Java带来一个日志标准。

其实,它确实成为了Java当前业界事实上的标准了,主流的第三方日志框架都实现了slf4j中的接口。那些就算使用了log4j做为实现的,也大多会与slf4j结合使用。

所以,你在Java的第三方类库中,可能见到的大部分Logger类,大多是org.slf4j.Logger,而org.slf4j.Logger其实是一个接口。同样,在使用slf4j的时候,你一定会见到log4j或logback等日志实现搭配一起来用。

Java System Logger

不过,slf4j毕竟不是JDK的东西,也不属于javaEE,是属于apache的开源框架。

Java仍然希望建立自己JDK级别的日志标准,这样会有以下几个好处:

  1. 结束当前Java生态中日志混乱不统一的现状
  2. 提供SDK级别的日志接口,有利于生态中的所有类库后续都只依赖SDK日志接口,这样可以做到任意切换日志实现。

当然,这个想法确实很不错,而且Java确实也这么做了。

终于,在Java 9的时候,Java 9添加了System Logger特性。这个日志接口的完整类名是: java.lang.System.Logger

System.Logger同样是一个接口,不是实现。这意味着你需要一个实现。

如果你没有添加另外的实现,则默认使用的是java.util.logger.Logger做为实现。

当然,你也可以使用log4j来做实现,log4j也添加了对Java System Logger的实现.

添加log4j及log4j-jpl依赖 (以Gradle为例)

    dependencies {
        testImplementation("org.apache.logging.log4j:log4j-core:${rootProject.extra["log4j-version"]}")
        testImplementation("org.apache.logging.log4j:log4j-jpl:${rootProject.extra["log4j-version"]}")
    }
复制代码

同样,添加log4j.properties日志配置文件

log4j.rootLogger=INFO,stdout
log4j.logger.org.myddd=DEBUG

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%p\t%d{ISO8601}\t%r\t%c\t[%t]\t%m%n
复制代码

使用System.Logger做日志

public class TestSystemLogger {

    private final static System.Logger logger = System.getLogger(TestSystemLogger.class.getName());

    @Test
    void testLogger(){
        logger.log(System.Logger.Level.DEBUG,"这是Java System Logger的Debug日志");
    }
}
复制代码

甚至,你可以自己实现一个日志实现也行。

问题

Java 9引进这个JDK级别的Logger,从想法上来说是好的,也是值得称赞的。但如果再认真分析下,我认为它仍然有它的问题

其一:其实现不够简洁优雅

来,我们对比下

// Java System Logger的写法
logger.log(Level.DEBUG,"这是Java System Logger的Debug日志");

//log4j及其它日志框架的写法
logger.debug("这是log4j的Debug日志");
复制代码

一眼就可以看到,从简洁性上来说,log4j这种更简洁。

在简洁代码之道中也专门说到这个,与其通过多一个参数,还不如多几个方法,减少一个参数这样更简洁与优雅,方法的表意更简洁纯粹。

其二:存在感不强,短期内难以改变日志现状

Java 9这个System Logger,存在感我认为并不强,可能相当一部分Java程序员并不知道这个点。

那我们可以很容易推测,基于Java的第三方类库也好,生态也好,在日志上可能仍然会选择slf4j这个抽象或干脆直接使用log4j或logback这一类的实现,而不是Java System Logger。

这意味着,Java System Logger试图统一Java生态的日志,短期内难以实现。

Obwohl slf4j eine Abstraktion ist, muss es log4j geben, das eine beträchtliche Anzahl von Frameworks direkt verwenden kann, anstatt slf4j + log4j.

Das bedeutet, dass in Ihrem Java-Projekt, wenn Sie sich auf viele Frameworks von Drittanbietern verlassen, einige Frameworks von Drittanbietern möglicherweise slf4j verwenden, einige möglicherweise log4j und einige möglicherweise andere Protokolle verwenden.

Diese chaotische Situation ist kurzfristig nicht zu ändern.

Beenden

Das sogenannte „it’s not too late to flick the past“ ist zwar kurzfristig nicht zu ändern, aber diese Art von Fortschritt Javas ist dennoch ermutigend.

Für mich ist die zukünftige Verwendung von System Logger mit log4j als Implementierung der beste Weg und die beste Maßnahme, um Java zu respektieren.

Was würdest du tun?

Nun, diese Woche habe ich über Protokolle gesprochen, und nächste Woche werde ich mit Ihnen weiter über die neuen Funktionen nach Java 8 sprechen.

Supongo que te gusta

Origin juejin.im/post/7088496311946706975
Recomendado
Clasificación