首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SLF4J记录异常为JSON或单行字符串

SLF4J记录异常为JSON或单行字符串
EN

Stack Overflow用户
提问于 2020-07-01 15:00:19
回答 1查看 3.1K关注 0票数 2

我需要能够将异常记录为日志中的单个记录,这将使在Kibana / Elasticsearch中调查问题变得更加容易。从slf4j的文档中可以看出,Logger接口要求消息为Strings。是在将异常消息传递给Logger之前从异常消息中删除换行符的唯一选项吗?

就上下文而言,我使用以下内容:

  • .m2/repository/org/slf4j/slf4j-api/1.7.28/slf4j-api-1.7.28.jar
  • Java 11
  • Sprint Boot版本2.1.8

这是我的自定义异常处理程序的精简版本:

代码语言:javascript
运行
复制
import my.error.Error; // custom Error class
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler {

  private final Logger logger = LoggerFactory.getLogger(this.getClass());
  private void logError(Error error, Exception ex){
    logger.error(String.format("id: %s, message: %s", error.getId(), ex.getMessage()), ex);
  }

}

最初,我试图通过更改我的logback.xml文件,在src/main/java/resources中更改日志记录行为。不幸的是,这似乎没有任何作用,所以我现在的假设是,我正在创建的CustomExceptionHandler正在推翻logback.xml文件中设置的规范。具体来说,在其他研究的基础上,改变了<pattern> of <encoder>。它试图替换所有换行符。

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" debug="true">
    <include resource="org/springframework/boot/logging/logback/base.xml" />

    <appender name="FILE-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/gateway.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/archived/gateway/gateway.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern>
            <!-- each archived file, size max 5MB -->
            <maxFileSize>5MB</maxFileSize>
            <!-- total size of all archive files, if total size > 10GB, it will delete old archived file -->
            <totalSizeCap>10GB</totalSizeCap>
            <!-- 30 days to keep -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d %p %c{1.} [%t] %m MULTIEXCEPTION %replace(%xException){'\n','\u2028'}%nopex%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="FILE-ROLLING" level="DEBUG" additivity="false"/>
    </root>

    <springProfile name="local">
        <logger name="my.gateway" level="TRACE" additivity="false">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="FILE-ROLLING" />
        </logger>
        <logger name="com.netflix" level="DEBUG" additivity="false">
            <appender-ref ref="CONSOLE" />
        </logger>
        <logger name="org.springframework" level="DEBUG" additivity="false">
            <appender-ref ref="CONSOLE" />
        </logger>
        <logger name="com" level="INFO" additivity="false">
            <appender-ref ref="CONSOLE" />
        </logger>
        <logger name="gov" level="INFO" additivity="false">
            <appender-ref ref="CONSOLE" />
        </logger>
        <logger name="org" level="INFO" additivity="false">
            <appender-ref ref="CONSOLE" />
        </logger>
    </springProfile>
</configuration>

链接

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-24 16:07:43

我将我的logError方法更改为:

代码语言:javascript
运行
复制
import org.slf4j.MDC; // new import to add property
// ... other imports from before

  private void logError(Error error, Exception exception){
    MDC.put("error id", error.getId().toString()); // add a new property to the thread context
    LOGGER.error(exception.getMessage(), exception);
    MDC.clear(); // remove all new properties after logging the error
  }

我的新pom.xml文件依赖项:

代码语言:javascript
运行
复制
  <dependencies>
    <!-- logging -->
    <dependency>
      <groupId>net.logstash.logback</groupId>
      <artifactId>logstash-logback-encoder</artifactId>
      <version>5.2</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback.contrib</groupId>
      <artifactId>logback-jackson</artifactId>
      <version>0.1.5</version>
    </dependency>
    <!-- ch.qos.logback.contrib.json.classic.JsonLayout -->
    <dependency>
      <groupId>ch.qos.logback.contrib</groupId>
      <artifactId>logback-json-classic</artifactId>
      <version>0.1.5</version>
    </dependency>
    <!-- Other dependencies -->
    <!-- ... -->
    <!-- ... -->
  </dependencies>

新的logback.xml文件:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender class="ch.qos.logback.core.rolling.RollingFileAppender" name="FILE-ROLLING">
    <!-- Old encoder is removed: 
    <encoder>
      <pattern>%d %p %c{1.} [%t] %m%n</pattern>
    </encoder>
    -->
    <file>${LOG_PATH}/data.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>${LOG_PATH}/archived/data/data.%d{yyyy-MM-dd}.%i.log.gz
      </fileNamePattern>
      <!-- each archived file, size max 10MB -->
      <maxFileSize>10MB</maxFileSize>
      <!-- total size of all archive files, if total size > 20GB, it will delete old archived file -->
      <maxHistory>60</maxHistory>
      <!-- 60 days to keep -->
      <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <!-- TODO : configure a pretty printer -->
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <provider class="net.logstash.logback.composite.loggingevent.ArgumentsJsonProvider"/>
    </encoder>
  </appender>

  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <!-- TODO : configure a pretty printer -->
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
      <provider class="net.logstash.logback.composite.loggingevent.ArgumentsJsonProvider"/>
    </encoder>
  </appender>
  <!-- The base logback configuration is removed, but note that this will also remove the default Spring start-up messages, so those need to be added back into the <root> 
  <include resource="org/springframework/boot/logging/logback/base.xml"/>
  -->
  <root level="INFO">
    <appender-ref ref="FILE-ROLLING"/>
    <appender-ref ref="CONSOLE"/> <!-- This adds Spring start-up messages back into the logs -->
  </root>
  <springProfile name="local">
    <logger additivity="false" level="TRACE" name="org.springframework.web">
      <appender-ref ref="CONSOLE"/>
    </logger>
  </springProfile>
  <springProfile name="dev">
    <logger additivity="false" level="DEBUG" name="org.springframework">
      <appender-ref ref="FILE-ROLLING"/>
    </logger>
  </springProfile>
  <springProfile name="prod">
    <logger additivity="false" level="DEBUG" name="my.app.path">
      <appender-ref ref="FILE-ROLLING"/>
    </logger>
    <logger additivity="false" level="DEBUG" name="org.jooq">
      <appender-ref ref="FILE-ROLLING"/>
    </logger>
    <logger additivity="false" level="DEBUG" name="org.springframework">
      <appender-ref ref="FILE-ROLLING"/>
    </logger>
  </springProfile>
</configuration>

SLF4J文档-映射诊断上下文

Baeldung示例- MDC + Log4J2

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62679726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档