最新のJava 11.でプロジェクトを実行しようとしました。特定のファイルロガーを除くすべてが機能します。ロギングは以前のJavaバージョン-10、9、8では正常に機能しますが、Java 11では正常に機能しません。
サーバーの実行中に警告が1つだけ表示されます。
警告:Sun.reflect.Reflection.getCallerClassはサポートされていません。これはパフォーマンスに影響します。
私の設定は次のとおりです。
<Configuration>
<Appenders>
<RollingFile name="postgresDBLog" fileName="${sys:logs.folder}/postgres.log"
filePattern="${sys:logs.folder}/archive/postgres.log.%d{yyyy-MM-dd}">
<PatternLayout>
<pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<RollingFile name="workersLog" fileName="${sys:logs.folder}/worker.log"
filePattern="${sys:logs.folder}/archive/worker.log.%d{yyyy-MM-dd}">
<PatternLayout>
<pattern>%d{HH:mm:ss.SSS} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<RollingFile name="statsLog" fileName="${sys:logs.folder}/stats.log"
filePattern="${sys:logs.folder}/archive/stats.log.%d{yyyy-MM-dd}">
<PatternLayout>
<pattern>%msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
<RollingFile name="userLog" fileName="${sys:logs.folder}/blynk.log"
filePattern="${sys:logs.folder}/archive/blynk.log.%d{yyyy-MM-dd}">
<PatternLayout>
<pattern>%d{HH:mm:ss.SSS} %-5level- %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="cc.blynk.server.workers" level="debug" additivity="false">
<appender-ref ref="workersLog"/>
</Logger>
<Logger name="cc.blynk.server.workers.StatsWorker" level="debug" additivity="false">
<appender-ref ref="statsLog"/>
</Logger>
<Logger name="cc.blynk.server.db" level="debug" additivity="false">
<appender-ref ref="postgresDBLog"/>
</Logger>
<Logger name="com.zaxxer.hikari" level="OFF" additivity="false">
</Logger>
<Logger name="org.asynchttpclient.netty.channel" level="OFF" additivity="false" />
<!-- turn off netty errors in debug mode for native library loading
https://github.com/blynkkk/blynk-server/issues/751 -->
<Logger name="io.netty" level="INFO" additivity="false" />
<Root>
<AppenderRef ref="userLog"/>
</Root>
</Loggers>
</Configuration>
userLog
を除くすべてのロガーは正常に動作します。ただし、userLog
は空です。
log4j2 version 2.11.1
Ubuntu 16.04.5 LTS
Java version "11.0.1" 2018-10-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.1+13-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.1+13-LTS, mixed mode)
更新:
level="info"
をルートレベルに追加すると、問題が修正されます。
<Root level="info">
<AppenderRef ref="userLog"/>
</Root>
しかし、私のプロジェクトでは、プロパティファイルに基づいてログレベルを設定するコードを使用していました。コードは次のとおりです。
private static void changeLogLevel(String level) {
Level newLevel = Level.valueOf(level);
LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
Configuration conf = ctx.getConfiguration();
conf.getLoggerConfig(LogManager.ROOT_LOGGER_NAME).setLevel(newLevel);
ctx.updateLoggers(conf);
}
この部分はJava 11では動作しないようです。
誰かがMavenを使用していて、フラットjarを組み立てているときに同じ問題が発生している場合、同じ問題を修正するために私がしたことは次のとおりです。
<plugin>
<groupId>org.Apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.Apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>foo.bar.Generate</mainClass>
<manifestEntries>
<Multi-Release>true</Multi-Release>
</manifestEntries>
</transformer>
<transformer implementation="org.Apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
重要な部分は<Multi-Release>true</Multi-Release>
。
ロガーレベルを変更するために今使用しているJavaコードは次のとおりです。
Configurator.setAllLevels("foo.bar", Level.DEBUG);
このメッセージが表示される場合、アプリケーションはマルチリリースjarを使用するように設定されていません。 Log4jは、META-INF/versions/9にあるStackLocatorのバージョンでStackwalkerを使用することにより、Java 9+をサポートします。アプリケーションの動作に応じて、jarマニフェストでMulti-Releaseをtrueに設定する必要がある場合があります。これは、Spring Boot jarにも当てはまります。複数リリースのサポートがなければ、Reflection.getCallerClass()を使用しようとするStackLocatorのJava 9より前のバージョンを使用します。そのクラスはJava 9で削除されました。Log4jはスタックの場所を計算するためのより遅い方法にフォールバックしますが、それでも動作します。したがって、警告。
Log4J2はもちろん互換性があり、 JDKマルチリリース機能 または 詳細 を使用します。
しかし...
1)最初に、-私のように-slf4jインターフェースを使用している場合、別のMavenアーティファクトを使用する必要があります。 http://logging.Apache.org/log4j/2.x/log4j-slf4j-を参照してくださいimpl/index.html
<dependency>
<groupId>org.Apache.logging.log4j</groupId>
<artifactId>log4j-slf4j18-impl</artifactId>
<version>2.12.1</version>
</dependency>
'mvndependency:tree'が示すように、すべての依存関係を追加します。
\- org.Apache.logging.log4j:log4j-slf4j18-impl:jar:2.12.1:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.8.0-alpha2:compile
[INFO] +- org.Apache.logging.log4j:log4j-api:jar:2.12.1:compile
[INFO] \- org.Apache.logging.log4j:log4j-core:jar:2.12.1:runtime
2)次に、私と同じように、すべての依存関係を含む1つのJARを作成する場合、マルチリリースマニフェストエントリも追加する必要があります。 https://issues.Apache.org/ jira/browse/LOG4J2-2537 または私のプロジェクトの pom.xml で検索
<Multi-Release>true</Multi-Release>
この部分は、Java 11。
JDK 8からJDK 11にアップグレードした後、LoggerContextを使用してLogLevel設定をプログラムで更新すると、同じ問題が発生しました。LogManager.getContext(boolean)
がLoggerContextを見つけられない場合オブジェクトは効果がありません。 Log4jのLogManagerクラスのクラスローダーを指定すると、この場合の問題が修正されました。
LoggerContext ctx = (LoggerContext) LogManager.getContext(LogManager.class.getClassLoader(), false);