2017-08-29 3 views
0

私のJavaアプリケーションをドッカーに入れるつもりです。しかし、私たちの会社のロギング施設に基づいて、私はfluentdを使ってコンテナのログを収集しなければなりません。それで私はJavaスタックトレースを1行のログに入れなければなりません。ドックのlogbackによる1行でのprint java例外の問題

私は以下のことをしましたが、状況によっては動作しますが、お互いに失敗します。

package com.alex; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 

import java.util.zip.DataFormatException; 

public class Main { 
    private static final Logger logger = LoggerFactory.getLogger(Main.class); 

    public static void alexExc() throws Exception { 
     throw new Exception("hello"); 
    } 

    public static void main(String[] args) throws Exception { 
     try { 
      alexExc(); 
     } catch (Throwable t) { 
      logger.error("oops", t); 
     } 

     throw new DataFormatException("invalid data format"); 
    } 
} 

次は私の指定された一つの "#012"

package com.alex; 

import ch.qos.logback.classic.pattern.ThrowableProxyConverter; 
import ch.qos.logback.classic.spi.IThrowableProxy; 
import ch.qos.logback.core.CoreConstants; 

public class OneLineStackTraceConverter extends ThrowableProxyConverter { 
    protected String throwableProxyToString(IThrowableProxy tp) { 
     String originalStackTrace = super.throwableProxyToString(tp); 

     return originalStackTrace.replace(CoreConstants.LINE_SEPARATOR, " #012"); 
    } 
} 

で区切りを置き換えるために、私のコンバータである。そして、私のlogback設定です:あなたが見ることができるように

<?xml version="1.0" encoding="UTF-8" ?> 
<configuration scan="true" scanPeriod="30 seconds"> 
    <conversionRule conversionWord="ex" 
      converterClass="com.alex.OneLineStackTraceConverter" /> 

    <appender name="INFO_FILE" 
       class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>/logs/loggingmdc/info.log</file> 
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 
      <fileNamePattern>/logs/loggingmdc/info.log.%i</fileNamePattern> 
      <minIndex>1</minIndex> 
      <maxIndex>5</maxIndex> 
     </rollingPolicy> 
     <triggeringPolicy 
       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 
      <maxFileSize>1GB</maxFileSize> 
     </triggeringPolicy> 
     <encoder> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %le %logger{0}: ## %msg\n</pattern> 
     </encoder> 
     <filter class="ch.qos.logback.classic.filter.LevelFilter"> 
      <level>INFO</level> 
      <onMatch>ACCEPT</onMatch> 
      <onMismatch>DENY</onMismatch> 
     </filter> 
    </appender> 
    <appender name="DEBUG_FILE" 
       class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>/logs/loggingmdc/debug.log</file> 
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 
      <fileNamePattern>/logs/loggingmdc/debug.log.%i</fileNamePattern> 
      <minIndex>1</minIndex> 
      <maxIndex>5</maxIndex> 
     </rollingPolicy> 
     <triggeringPolicy 
       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 
      <maxFileSize>1GB</maxFileSize> 
     </triggeringPolicy> 
     <encoder> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %le %logger{0}: ## %msg %ex\n</pattern> 
     </encoder> 
     <filter class="ch.qos.logback.classic.filter.LevelFilter"> 
      <level>DEBUG</level> 
      <onMatch>ACCEPT</onMatch> 
      <onMismatch>DENY</onMismatch> 
     </filter> 
    </appender> 
    <appender name="ERROR_FILE" 
       class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>/logs/loggingmdc/error.log</file> 
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 
      <fileNamePattern>/logs/loggingmdc/error.log.%i</fileNamePattern> 
      <minIndex>1</minIndex> 
      <maxIndex>5</maxIndex> 
     </rollingPolicy> 
     <triggeringPolicy 
       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 
      <maxFileSize>1GB</maxFileSize> 
     </triggeringPolicy> 
     <encoder> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %le %logger{0}: ## %msg %ex\n</pattern> 
     </encoder> 
     <filter class="ch.qos.logback.classic.filter.LevelFilter"> 
      <level>ERROR</level> 
      <onMatch>ACCEPT</onMatch> 
      <onMismatch>DENY</onMismatch> 
     </filter> 
    </appender> 
    <appender name="THIRD_PARTY_FILE" 
       class="ch.qos.logback.core.rolling.RollingFileAppender"> 
     <file>/logs/loggingmdc/thirdparty.log</file> 
     <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> 
      <fileNamePattern>/logs/loggingmdc/thirdparty.log.%i</fileNamePattern> 
      <minIndex>1</minIndex> 
      <maxIndex>5</maxIndex> 
     </rollingPolicy> 
     <triggeringPolicy 
       class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> 
      <maxFileSize>1GB</maxFileSize> 
     </triggeringPolicy> 
     <encoder> 
      <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %le %logger{0}: ## %msg %ex\n</pattern> 
     </encoder> 
    </appender> 

    <root level="INFO"> 
     <appender-ref ref="THIRD_PARTY_FILE"/> 
    </root> 
    <logger name="com.alex" level="DEBUG" additivity="false"> 
     <appender-ref ref="INFO_FILE"/> 
     <appender-ref ref="DEBUG_FILE"/> 
     <appender-ref ref="ERROR_FILE"/> 
    </logger> 
</configuration> 

私のログバック設定では、私はconversionRuleを追加して、イベントログ中の例外が私のOneLineStackTraceConverterを使用することを指定します。

  1. それは私が私のエンコーダ
  2. ため、各パターンに%exが含まれている場合、私はパターンで%exを含めるDONOT場合、それは動作しません動作します。どうして?ユーザーがパターンに%exを含めることを忘れた場合、その例外に使用する他のconversionWordがありますか?
  3. 最後のDataFormatExceptionはログファイルには載っていませんが、コンソールに出力されます。コンソールにもログファイルがあります。どうすればそれをすることができますか?

ありがとうございます。

答えて

1

DONOTにパターン%%が含まれていると動作しません。どうして?

変換語= exを宣言したため、あなたがそれを使わなければ、Logbackはあなたの心に何があるのか​​分からないので、何もしません。これをコード内の変数を宣言し、それを使用しないと比較すると、理解できるはずです。

それは限り、あなたのコードが行くように記録されていないので、最後のDataFormatExceptionは、ログファイルに

を行っておりません。コードに例外を投げた場合、Logback(またはあなたの場合はSLF4J)は自動的にキャッチしてログに記録しません。

+0

ご返信ありがとうございます。最初のものについては、あなたが説明したことを正確に理解しています。しかし、パターンに '%ex'を使用すると、スタックトレースは1行にフォーマットされていることが期待されます。パターンで '%ex'を削除すると、スタックトレースもログファイルにありますが、指定されたコンバータを使用していない元の複数行のスタックトレースです。もう1つは、ログファイルにも例外を指示する方法がありますか? – Alex

+0

@Alex 1)ログバックは、ログステートメントとパターンを一致させます。ログ文にカスタムパーサを指定しないと、メッセージの一部としてアペンダにダンプされます。これは、正規表現のマッチングに似ています - 指定した部分だけがマッチします。 2)コンソールアペンダーを宣言し、fluentdを使ってDockerログをポンピングすることもできます。 –