log 4 j 2の移行X


セキュリティ欠陥に対処するために、1週間でLog 4 Jの3つのバージョンがありました.
すべての同じルックアップ機能のために.
この機能はlog 4 j 2に多少ユニークです.X
それで、多分、それは、うまくいけばより安全で、代替のロガーに賛成してlog 4 jを掘るのが悪い考えでありません?
プロジェクトに依存して、ロガーを変更する簡単なpeasyからマルチ週のタスクに範囲があります.
私は、多くでそれを賭ける準備ができていますケース、それは実際には非常に簡単です.
それで、どのようにそれをするかを調べましょうLogback ターゲットとして
(実際には多くの選択肢がありません).

必要条件


まず第一に、それは比較的簡単に移動することですか?
あなたがあなたに依存する状況にいるならばAPIs exposed by log4j-api
(簡単に言えば:LogManager , Logger , Level , そしてThreadContext //Marker ),
または使用Slf4j 代わりにlog4j-slf4j-impl ),
あなたは良い条件にあるが、それは十分ではない.
ログコード自体に加えて考慮すべき別のこと
ユーザーにログ設定を公開するかどうか
(と設定ファイルは?
log 4 jから離れると、ログの設定方法が明らかに変わります.
そして最後に、拡張可能なフレームワークをログ出力します.
使用しているそのような拡張子を見てください.
と他のロガーの代替案があるかどうか.
例えば、あなたが使っているならsentry-log4j2 ,
同等であることを知っているsentry-logback を返します.
私は非常にシンプルだが、完全に現実的なセットアップを仮定します
(それは私が過去数年にわたって書いたほとんどのアプリで使用されているものだから現実的です).

依存関係の変更


しばらくの間、脇に置きなさい.
プロジェクト依存関係で何を変更する必要があるかを見てみましょう.
あなたのログAPIとしてSLF 4 Jを使用しているならば
それから、あなたは変わりますlog4j-slf4j-impl to logback-classic .
log 4 j APIを直接使っているなら、
最後に設定する必要がありますlog4j-api , log4j-to-slf4j , and logback-classic .
他のアダプタやブリッジがあれば、それに応じて置き換えてください.
から
Tolog4j-jcl jcl-over-slf4j log4j-1.2-api log4j-over-slf4j log4j-jul jul-to-slf4j log4j-jplいいえ、しかし、コピーすることができますthe one from Slf4j 2
この時点で、あなたはもはや持っている必要がありますlog4j-core 依存関係では
直接的または一時的に.

依存性管理に関する一考察


ランタイム依存関係に1つのロガーしか持たないことが重要です.
そして、アダプタ/ブリッジの間の衝突を持っていないことを確認します.
ルイ・ジェイコメットgreat blog post over at Gradle's blog on the subject.
あなたがMavenを使っているならばmvn dependency:tree あなたが持っている依存関係を理解し、どこから来るのか
その後使用dependency exclusions 不要な推移依存関係を削除するために必要な場合
適切なアダプター、ブリッジまたは実装に置き換えます.
あなたがGradleを使っているならば、私はルイスJacomet logging-capabilities plugin 十分!
あなたが既にそれを使用している場合は、から切り替えることを忘れないでください
loggingCapabilities {
    enforceLog4J2()
}
to
loggingCapabilities {
    enforceLogback()
}

設定ファイルの移行


次のステップは構成ファイルの移行です
したがって、等価動作を得ることができます.
私はいくつかの簡単な例を、再び実際のアプリケーションから撮影します.

コンソールへのログイン


Dockerコンテナで実行しているアプリケーション、あるいはシステムを経由しています.
これは、コンソールに直接アプリケーションのログを持っているのは便利です.
このlog 4 j 2の設定
<Configuration>
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{ISO8601_OFFSET_DATE_TIME_HHCMM}{Europe/Paris} %p %c{1.} [%t] %m%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>
はlogbackになります.
<configuration>
  <shutdownHook/>
  <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{"yyyy-MM-dd'T'HH:mm:ss,SSSXXX", Europe/Paris} [%thread] %p %c{1} [%t] %m%n</pattern>
    </encoder>
  </appender>

  <root level="info">
    <appender-ref ref="Console" />
  </root>
</configuration>

ファイルへのログ記録


ローリング戦略を使用したファイルへのログ記録を好むアプリケーション
(ここでは非同期ロガーを使用します).
このログ4 j 2設定ファイル
<Configuration>
  <Appenders>
    <Async name="AsyncLogFile">
      <AppenderRef ref="LogFile" />
    </Async>
    <RollingFile name="LogFile"
      fileName="/var/log/myapp/myapp.log"
      filePattern="/var/log/myapp/myapp-%d{yyyy-MM-dd}.log.gz">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
      <Policies>
        <TimeBasedTriggeringPolicy />
      </Policies>
    </RollingFile>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="AsyncLogFile" />
    </Root>
  </Loggers>
</Configuration>
はlogbackになります.
<configuration>
  <shutdownHook/>
  <appender name="AsyncLogFile" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="LogFile" />
  </appender>
  <appender name="LogFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>/var/log/myapp/myapp.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>/var/log/myapp/myapp-%d{yyy-MM-dd}.log.gz</fileNamePattern>
      <maxHistory>7</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%d %p %c{1} [%t] %m%n</pattern>
    </encoder>
  </appender>
  <root level="info">
    <appender-ref ref="AsyncLogFile" />
  </root>
</configuration>

ログを送信する


sentryを使う最も簡単な方法は、ログアペンダとして設定することです.
一般的に上記のようにいくつかの他のappenderに加えて.
以下のlog 4 j 2設定ファイルの断片
<Configuration>
  <Appenders>
    <!-- … -->
    <Sentry name="Sentry"
            minimumEventLevel="WARN"
            minimumBreadcrumbLevel="DEBUG"
    />
  </Appenders>
  <Loggers>
    <Root level="info">
      <!-- … -->
      <AppenderRef ref="Sentry" level="warn" />
    </Root>
  </Loggers>
</Configuration>
はlogbackになります.
<configuration>
  <!-- … -->
  <appender name="Sentry" class="io.sentry.logback.SentryAppender">
    <minimumEventLevel>WARN</minimumEventLevel>
    <minimumBreadcrumbLevel>DEBUG</minimumBreadcrumbLevel>
  </appender>
  <root level="info">
    <!-- … -->
    <appender-ref ref="Sentry" />
  </root>
</configuration>

その他注意事項


あなたが使っているならばlog4j2.component.properties ファイル
明示的に置き換える必要がありますSystem.setProperty() できるだけ早くコードで
( logbackが初期化される前)
または他の同等の方法で同じことを達成する.
このファイルでは、私が書いたアプリで、
使用しているlog4j2.isWebapp=falseand log4j.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelectorすべてのappenderを非同期にする.
相当にないlog4j2.isWebapp ,
logbackはクラスパス内のサーブレットクラスの存在によって動作を変更しません.
に関してはAsyncLoggerContextSelector , あなたは明示的に使用する必要がありますAsyncAppender 設定ファイルの
(ログバック/ジョーンを設定する方法があります.AsyncAppender しかし、明示的にしましょう.

リンク


最後にすることは、アプリケーションが設定ファイルを使用していることを確認することです.
設定ファイルのlog 4 j 2とlogbackの検索方法は全く似ています.
まずシステムのプロパティ
次に、クラスパス内のファイルを返します.
そして最後にコンソールに戻ります.
システムプロパティを使用している場合は
から変更log4j2.configurationFile to logback.configurationFileすべてのDockerエントリポイント、systemdサービスユニット、シェルスクリプトなどで.
クラスパスにファイルを使用している場合は、
名前を付けなければならないlogback.xml むしろlog4j2.xml(or logback-test.xml むしろlog4j2-test.xml ).

結論


3つのステップ(依存関係、設定ファイル、設定ファイルの検索)
多くではなく、多くの場合、アプリケーション
log 4 j 2からの移行に.
私は、これが良いことであり、あなたがそれをすべきだと言っていません.
しかし、もしLog 4 J 2の欠陥のこのカスケードの光の中で.
あなたは、離れて、彼らが続くステップであることを想像しました.