2016-11-09 6 views
3

私は子()のコンテキストをSpringBootで動的に作成しており、各コンテキストを分離したファイルに記録したいと思います。これは可能ですか?Springブートの子()コンテキストによるログバック分離

これは、さまざまなアダプタに動的なスプリング統合設定があるためです。これは、同じアダプター構成で異なる接続で作業する場合には非常に便利ですが、1つのログファイルについて多くの情報があります。

私はJNDIコンテキスト分離でもスレッド分離を見ましたが、これを実行する最良の方法は何か分かりません。これはlogback.xmlファイルを設定するだけですか?

更新:

たぶんオプションがMDCであると私は概念を理解していないです。異なると@Componentにも適用することができ

@MessageEndpoint 
public class TestComponents { 

private static final Logger LOGGER = LoggerFactory.getLogger(Test.class); 

@Router(inputChannel = "inputRouter") 
public MessageChannel router(Message<String> demo) { 
.. 
LOGGER.trace(“TEST”); 
… 
LOGGER.error(“TEST”); 
… 
} 

@ServiceActivator(inputChannel="inputService") 
public void service(Message<String> demo) { 
.. 
LOGGER.trace(“TEST”); 
.. 
} 

@Transformer(inputChannel="inputTransformer", outputChannel="outputTransformer") 
public byte[] transformerToByte(Message<String> demo) { 
.. 
LOGGER.debug(“TEST”); 
.. 
} 
} 

例:たとえば、あなたは、次のような@Transformer@ServiceActivator@Routerなど、複数のSpring統合要素と春@MessageEndpoint要素のMDCを適用する方法を説明できますメソッド。私は

が原因ドキュメントに記述paragraphにパフォーマンスを心配:

MDC logback-古典は 値が中程度の頻度でMDCに配置されていることを前提としてによって実装されることに注意してください

答えて

0

これは簡単にはできないと思います。私はLogbackに関する多くの経験はありませんが、私はLog4J、Spring、Tomcat、そしてクラスローディングについてよく知っています。

Log4Jのように、log4Jは静的ファクトリメソッドを使用してシングルトンロガーを生成します。これは、静的状態がクラスローダーに格納されていることを意味します。 春には、どのクラスロードをコンテキストのロードに使用するかを指定できますが、クラスローダーは親クラスローダによってロードできないクラスまたはリソースのみをロードします(URLClassLoader.getResourceをオーバーライドするとこれが見つかります) 。これは、Springブートが開始されると、ロギングが初期化され、 'root'クラスローダーによってロードされるため、問題です。

これを防ぐには、クラスパスからログバックjarを削除し、ルートのSpringコンテキストと別のクラスのロードをロードするための新しいURLクラスローダー(ログバックjarと構成のみを含む)を作成します子コンテキストをロードします(別の構成と同じjar)。ログバックjarはシステムクラスパスの一部ではないので、スタティックはクラスローダーによってスコープが決まるため、2つの別個のログバック構成を持つことができます。私は原因LoggingSystemクラスが初期化されている方法に、logback-コアとlogback-古典的なjarファイルをロードするクラスローダを持つだけでは十分ではないことに気づい少し深く

EDIT

ダイビング(ログシステムライン126、バージョン1.4.1)、バネ・ブート・ジャーナル(とその他すべてのもの)は、同じクラス・ローダーによってロードされる必要があります。つまり、通常はスプリングブートアプリケーションを実行するために使用されるjarバンドルを使用することはできません。

+0

ありがとうクラウス。私たちのカスタム設定はSpringブート設定を無効にしますが、Springブートはまだchild()コンテキストが作成される前後でログバックを使用しているので、この方法を使用することはできません。私はSpringの拡張機能を使ってプログラムで設定をカスタマイズしています – crm86

0

logbackMDC (Mapped Diagnostic Context)SiftingAppenderと組み合わせて使用​​できます。

私はそれがどのように動作するかを説明します以下:

  1. MDCは、あなたがその値に基づいてログファイルを分離するために使用することができる弁別を持つことができます。この段階では、子コンテキストからトップスタックメソッドを実行する前にMDC.put('child-context-key', 'childContextId')を実行し、実行後にMDC.remove('child-context-key')を実行する必要があります。
  2. その後、ch.qos.logback.classic.sift.SiftingAppenderを設定して、値をディスクリミネータとして使用してログファイルを区切ります。 例:

    <appender name="CHILD-CONTEXT-SIFT-APPENDER" class="ch.qos.logback.classic.sift.SiftingAppender"> 
    <discriminator class="ch.qos.logback.classic.sift.MDCBasedDiscriminator"> 
        <key>child-context-key</key> 
        <defaultValue>defaultChildContextId</defaultValue> 
    </discriminator> 
    <sift> 
        <appender name="CHILD-CONTEXT-SIFT-FILE-APPENDER" 
         class="ch.qos.logback.core.rolling.RollingFileAppender"> 
         <file>/path/to/your/log/file/${child-context-key}.log 
         </file> 
    </sift> 
    </appender> 
    

また、あなたは、JNDI弁別に基づくWebアプリケーション・モジュールのための個別のログファイルを設定する方法を示しthis exampleフォームlogbackに従うことができます。

+0

彼はそれぞれの子コンテキストが自分自身のファイルにログインすることを望んでいると思うので、XのShiftAppenders、child-1、child-2、childを定義する必要があります-3 ... child-X。彼がプログラムでログアウトするためにShiftAppenderを追加できない限り。 Springコンテキストをロードする前にMDCを設定する必要がありますが、コンテキストでエグゼキュータを使用する場合は、Springロード・スレッドからMDC(MDC.getCopyOfContextMap())を保存して、executorスレッドに設定する必要がありますつまり、ThreadFactoryを定義するか、各実行可能なrunメソッドでMDC.setContextMap(saved-MDC)を呼び出す必要があります。 –

+0

@Klaus Groenbaek、申し訳ありませんが、あなたはいくつかの 'SiftAppenders'について間違っています。 –

+0

Sergeyありがとうございました。私はドキュメントを読んでいましたが、MDCとJNDIは有効なオプションではありません。なぜなら私はアプリケーションサーバーを持っておらず、MDCは実際にはパフォーマンスが悪いからです。さらに、私は動的なコンテキストで動的に構成可能なものを探しているので、MDCのソリューションは有効ではありません。 MDCは、メッセージやスレッドの分離が少ない場合でも、数十のLOGトレースで子コンテキストがかなり大きい場合に適しています。 – crm86

関連する問題