首页 > 解决方案 > JSON 日志中的 message 属性有反斜杠

问题描述

我在一个项目中使用spring boot,目前正在探索日志记录行为。为此,我正在使用 zipkin 服务。

logback.xml的如下:

    <appender name="STASH"
    class="net.logstash.logback.appender.LogstashTcpSocketAppender">
    <destination>192.168.0.83:5000</destination>
      <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"
        <providers>
            <mdc /> <!-- MDC variables on the Thread will be written as JSON fields -->
            <context /> <!--Outputs entries from logback's context -->
            <version /> <!-- Logstash json format version, the @version field in the output -->
            <logLevel />
            <loggerName />
            <pattern>
                <pattern>
                    {
                    "serviceName": "zipkin-demo"
                    }           
                </pattern>
            </pattern>
            <threadName />
            <message />
            <logstashMarkers />
            <arguments />
            <stackTrace />
        </providers>
    </encoder>
</appender>

<root level="info">
    <appender-ref ref="STASH" />
</root> 

现在据我了解,要登录 json,您需要一个自定义记录器实现,我已完成如下操作:

public class CustomLogger {

public static void info(Logger logger, Message message, String msg) {
    log(logger.info(), message, msg).log();
}

private static JsonLogger log(JsonLogger logger, Message message, String msg) {
    try {
        if (message == null) {
            return logger.field("Message", "Empty message").field("LogTime", new Date() );
        }
        logger
        .field("message", message.getMessage())            
        .field("id", message.getId());

        StackTraceElement ste = (new Exception()).getStackTrace()[2];
        logger.field(
                "Caller",
                ste.getClassName() + "." + ste.getMethodName() + ":" + ste.getLineNumber());
        return logger;
    } catch (Exception e) {
        return logger.exception("Error while logging", e).stack();
    }
}

我的消息类是:

public class Message {

private int id;
private String message;

..constructor & setters and getters
}

现在在我的控制器类中,我将自定义记录器用作:

static  com.savoirtech.logging.slf4j.json.logger.Logger log = com.savoirtech.logging.slf4j.json.LoggerFactory.getLogger(Controller.class.getClass());
Message msg = new Message(1, "hello");
CustomLogger customLogger = new CustomLogger();
customLogger.info(log, msg, "message");

我的日志最终在 kibana 中为:

 "message": "{\"message\":\"hello\",\"id\":1,\"Caller\":\"<class_name>:65\",\"level\":\"INFO\",\"thread_name\":\"http-nio-3333-exec-2\",\"class\":\"<custom_logger_class>\",\"logger_name\":\"java.lang.Class\",\"@timestamp\":\"2018-07-20 19:02:14.090+0530\",\"mdc\":{\"X-B3-TraceId\":\"554c43b0275c3430\",\"X-Span-Export\":\"true\",\"X-B3-SpanId\":\"368702fffa40d2cd\"}}",

现在,我希望我message的部分日志作为json条目而不是这个。我哪里错了?我尝试过广泛搜索方法,但无济于事。甚至可能吗?

标签: javaspring-bootloggingslf4jzipkin

解决方案


我终于让它工作了。我刚刚更改了 logstash 配置文件并添加了:

input
{  
   tcp   
   {  
      port => 5000 
      type => "java" 
      codec => "json"
   }
}
filter
{  
   if [type]== "java"   
   {  
      json
      {  
         source => "message"
      }
   }
}

过滤器部分早先丢失了。


推荐阅读