2017-04-10 7 views
0

私はlog4j2を使用してログに記録したいと言うメッセージをdelay=1, name=Ashと言います。 delaynameフィールドは、メッセージのフィールドであるのに対し、私はそれがjsonへのlogj4メッセージ

{"@timestamp": 1234, "delay"=1, "name"="Ash"} 

のようなJSON形式で@timestampフィールドになりたい私のログファイルのすべての行は、ロガーによって生成タイムスタンプです。

これを行う方法はありますか? JsonLayoutを使用することで、すべての出力をjson形式で出力できますが、ログメッセージを操作する方法が見つからないため、さまざまなフィールドに異なる部分を配置できるようになりました。

+0

にlog4j2.xmlパターンのレイアウトを変更。 – Fildor

+0

理想的には、私はそれを避けたいが、方法がないことを知ることも有用である。 – LetsPlayYahtzee

+0

タイムスタンプはメッセージ自体のメタ情報の一部であり、実際にはメッセージをメタデータに移動したい。あなたはMDCを試しましたか? - > PatternLayoutを使用する場合は、コンテキスト内の現在のユーザーをメッセージに再利用します。それがうまくいかない場合は、誰も解決策が出てこないので、自分のJsonLayoutを実装することをお勧めします... – slowy

答えて

0

これは、log4j2 JSONLayoutを使用して行うことができます。

  • まずあなたがjsonlayout指定する必要が

例:あなたが偽=コンパクト、JSONはprity形式のプリントになります設定した場合、ここで

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration status="WARN"> 
    <Appenders> 
     <Console name="Console" target="SYSTEM_OUT"> 
      <JSONLayout compact="true" eventEol="true" properties="true"/> 
     </Console> 
    </Appenders> 
    <Loggers> 
     <Root level="info"> 
      <AppenderRef ref="Console"/> 
     </Root> 
    </Loggers> 
</Configuration> 

  • セカンドキー値のペアとしてpu値にThreadContextを入れることができます。

例:

ここ ThreadContext
for (int i = 0; i < 5; i++) { 
    ThreadContext.clearAll(); 
    ThreadContext.put("delay", String.valueOf(i)); 
    ThreadContext.put("name", "Ash " + i); 
    LOGGER.info("Testing ", "k1", "v1", "k2", "v2"); 
} 

がはっきりするまで、すべてのキーと値のペアを保持します。

出力:

{"timeMillis":1491819918389,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"0","name":"Ash 0"},"threadId":1,"threadPriority":5} 
{"timeMillis":1491819918504,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"1","name":"Ash 1"},"threadId":1,"threadPriority":5} 
{"timeMillis":1491819918504,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"2","name":"Ash 2"},"threadId":1,"threadPriority":5} 
{"timeMillis":1491819918505,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"3","name":"Ash 3"},"threadId":1,"threadPriority":5} 
{"timeMillis":1491819918505,"thread":"main","level":"INFO","loggerName":"com.ashraful.ilpexp.LogTest","message":"Testing ","endOfBatch":false,"loggerFqcn":"org.apache.logging.log4j.spi.AbstractLogger","contextMap":{"delay":"4","name":"Ash 4"},"threadId":1,"threadPriority":5} 
0

はこれを試してみてください:

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration> 
    <Appenders> 
     <Console name="STDOUT" target="SYSTEM_OUT"> 
      <PatternLayout pattern='{"@timestamp": %d{UNIX_MILLIS}, "delay"=%X{delay}, "name"="%X{name}"}%n'/> 
     </Console> 
    </Appenders> 
    <Loggers> 
     <Root level="info"> 
      <AppenderRef ref="STDOUT"/> 
     </Root> 
    </Loggers> 
</Configuration> 

Utils.java

public class Utils { 

    private static final Logger logger = LogManager.getLogger(); 

    public static void logMsg(long delay, String name) { 
    ThreadContext.put("delay", delay + ""); 
    ThreadContext.put("name", name); 
    logger.info(""); 
    } 
} 

出力

{"@timestamp": 1491821218548, "delay"=1, "name"="hello"} 

UPDATE

は実際に、私はコードに直接ログメッセージ文字列を構築することを好みます。

public static void logMsg(long delay, String name) { 
    String s = String.format("{\"@timestamp\":%s, \"delay\"=%s, \"name\"=\"%s\"}", System.currentTimeMillis(), delay, name); 
    logger.info(s); 
} 

注:あなたが唯一のJSONフィールドとして完全なメッセージを持つことができます私の知る限り

<PatternLayout pattern='%msg%n'/> 
+0

2番目の例は最初の設定では動作しません。この場合、 'patern =% m%n'だと思います。 – LetsPlayYahtzee

+0

はい、私は答えをできるだけシンプルにしたいだけです。 – wangyuntao

関連する問題