当前位置: 首页 > 知识库问答 >
问题:

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

子车鸿才
2023-03-14
    null
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);
  }

}

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

<?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>
  • 日志文档
  • SLF4J文档
  • SLF4J手册
  • 合并Logback和SLF4J
  • 日志和SLF4J-structuredarguments
  • 使用日志记录的JSON日志
  • 将日志折叠-多行合并为一行
  • Apache Log4j布局
  • 因此:重写日志1
  • 因此:重写日志2
  • 因此:使Logback输出为JSON
  • 格式SLF4J
  • 使用Logback或log4j2将多行日志折叠为一个
  • Baeldung Log4j2 JSON日志
  • Java日志指南

共有1个答案

堵德曜
2023-03-14

我将LogerRror方法更改为:

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文件依赖项:

  <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文件:

<?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>
 类似资料:
  • 我希望记录对web服务的请求和响应。我将slf4j与底层log4j2实现一起使用。我的日志记录语句如下所示。 记录器。信息(“{}”,新的CustomObject(请求、响应、参数1、参数2)); 我已经在所有必要的对象和CustomObject类中实现了toString方法,以记录该对象的所有属性。 我看到CustomObject的toString方法在将日志消息传递给Asynch记录器之前被调

  • 问题内容: PHP中是否可以通过MySQL记录集传递函数或类,并获得返回的JSON字符串,可以在Ajax请求中将其传递回JavaScript函数? 像这样的东西: 问题答案: 这应该工作: 如果需要处理结果集,则可以使用以下更复杂的版本,该版本可让您添加将在每条记录上调用的回调函数,并且必须返回已处理的记录: 像这样使用它:

  • 问题内容: 我想得到一个表示像这样的json的字符串: {“投票”:{“ option_A”:“ 3”}} 并在其中包含一个“计数”键, 这样结束: {“投票”:{“ option_A”:“ 3”},“ count”:“ 1”} 这就是为什么我计划将其转换为json以便可以添加计数然后再次将其设置为字符串的原因。 问题是我不知道该json的结构 ,所以我无法使用,因为该结构有所不同。我怎样才能做到

  • 我有一个JSON字符串,其中包含如下结构,基本上我有一个VO链,每个VO都有VO列表和VO地图。 我想打印键值对中的每个属性名称及其值。我不想打印 VO 名称,而只想打印结束属性(叶级属性) type=new id=10 add_record=true dob_required=false dept_name=purchase main_group=“main group”sub_group=“s

  • 问题内容: 我们将Spring与slf4j和hibernate结合使用,我试图找到一种自动记录异常和错误的方法(即,无需在每个类中启动调试器的实例),以便它可以捕获抛出的任何错误或异常,并且在日志中获取类和方法的名称, 我读了一篇关于为此使用方面和拦截器的简短说明,因此您能否为我提供一些实现此目的的详细方法, 问候, 问题答案: 异常方面可能看起来像这样: spring会议: 编辑: 如果您希望记

  • 声纳可能重复,抱怨记录和重新触发异常。 这是我在类中的代码: 和我的日志类: 声纳指向捕获(最终异常e)并表示记录或重新抛出此异常。你觉得怎么样?