java - Spring Boot自定义滚动日志文件

标签 java json spring spring-boot logging

我们有一个 Spring Boot 应用程序,并使用 logback 和滚动文件来创建 json 和标准日志文件。

我们使用filebeat抓取log.json文件并推送到elk服务器

我想在日志目录中添加一个 op.json 自定义 json 滚动日志文件。这是为了收集有关名为 perf info 的操作的信息。

基本上,我只想使用一个管理滚动文件的类。在类中,将有一个 logOp 函数,它接受一个 java 对象,并将其序列化,向 json 输出添加一些标准日志字段。

问题: 1){不是链接的,但会很好} logback 中是否有功能允许我创建一个命名记录器,它将一个字符串(在我的例子中是序列化的 JSON)附加到 op.json 日志文件的末尾,并实现滚动记录器功能

2)如果这不能通过 logback 获得(我能理解)。是否有一个 java 包可以管理将字符串附加到滚动文件?我可以创建这个“Appender”的实例并向其添加字符串。这就像 logback 中的独立滚动文件附加器

我的目标是创建一个简单的 JSON 文件,可以直接查看和/或使用 filebeat 抓取该文件并将其发送到 Logstash 以创建操作性能仪表板。

-------------------- spring-boot-logger.log 和 spring-boot-logger.json 文件的配置 {for log.debug("my log消息},包括侦探 ----------

<include resource="org/springframework/boot/logging/logback/defaults.xml"/>

<springProperty scope="context" name="site" source="ci2.application"/>
<springProperty scope="context" name="app" source="spring.application.name"/>


<property name="LOGS" value="./logs" />


<!-- You can override this to have a custom pattern -->
<property name="CONSOLE_LOG_PATTERN"
          value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>

<!-- Appender to log to console -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <!-- Minimum logging level to be presented in the console logs-->
    </filter>
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
</appender>



<appender name="RollingFile"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOGS}/spring-boot-logger.log</file>
    <encoder>
        <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        <charset>utf8</charset>
    </encoder>
    <rollingPolicy
        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily and when the file reaches 10 MegaBytes -->
        <fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
</appender>


<appender name="Json"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOGS}/spring-boot-logger.json</file>
    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <timestamp>
                <timeZone>UTC</timeZone>
            </timestamp>
            <pattern>
                <pattern>
                    {
                    "severity": "%level",
                    "service": "${app:-}",
                    "trace": "%X{X-B3-TraceId:-}",
                    "span": "%X{X-B3-SpanId:-}",
                    "parent": "%X{X-B3-ParentSpanId:-}",
                    "exportable": "%X{X-Span-Export:-}",
                    "pid": "${PID:-}",
                    "thread": "%thread",
                    "class": "%logger{40}",
                    "rest": "%message",
                    "schema":"ci2",
                    "group":"devops",
                    "site": "${site}"

                    }
                </pattern>
            </pattern>
        </providers>
    </encoder>  
    <rollingPolicy
        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily and when the file reaches 10 MegaBytes -->
        <fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.json
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

</appender>

<!-- LOG everything at INFO level -->
<root level="warn">
    <appender-ref ref="RollingFile" />
    <appender-ref ref="Console" />
    <appender-ref ref="Json" />
</root>

<!-- LOG everything at INFO level -->
<root name="org.springframework" level="info">
    <appender-ref ref="RollingFile" />
    <appender-ref ref="Console" />
    <appender-ref ref="Json" />
</root>


<!-- LOG "com.siemens.pl*" at INFO level -->
<logger name="com.siemens.pl" level="info" additivity="false">
    <appender-ref ref="RollingFile" />
    <appender-ref ref="Console" />
    <appender-ref ref="Json" />
</logger>

-----------------结束logback配置---------------------------------------- ------

我正在尝试向 json 日志动态添加值。

类似于

1) 最高级别支持,将 map 中的值添加为生成的 json 中的 JSON 条目

 something like



    Map myValues = new HashMap<String,String> ();
    myValues.put("startTime",startTime);
    myValues.put("endTime",endTime);
    myValues.put("op",operation);
    myValues.put("user",user);
    // ideal usage format, would add map as "key":"value"  to json output
    log.debug(myValues);

2)如果将用户生成的字符串附加到日志文件(没有通过日志记录添加任何内容),我可以生成日志字符串(json myKeys + Stander 日志记录),然后附加

    Map myValues = new HashMap<String,String> ();
    myValues.put("startTime",startTime);
    myValues.put("endTime",endTime);
    myValues.put("op",operation);
    myValues.put("user",user);

    #Generate JSON String that includes standard logging fields and dynamic
    # user fileds passed in myValues map
    String myLogStringToAppendToLogFile = generateLogString(myValues);


    #Ideal op would accept string and append user provide string to end of
    #logfile with no modification
    log.debug("RawString", myLogStringToAppendToLogFile );
    log.debug(myValues);
<小时/>

上面是最简单的,我不确定记录器上是否有 API 可以接受 map 并添加到日志

记录器的另一个选项是向 json 文件添加一组固定的属性,并且属性值可以在用户日志行中传递。

例如,来自上面的 logback def -------------------

<appender name="Json"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOGS}/spring-boot-logger.json</file>
    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <timestamp>
                <timeZone>UTC</timeZone>
            </timestamp>
            <pattern>
                <pattern>
                    {
                    "severity": "%level",
                    "service": "${app:-}",
                    "trace": "%X{X-B3-TraceId:-}",
                    "span": "%X{X-B3-SpanId:-}",
                    "parent": "%X{X-B3-ParentSpanId:-}",
                    "exportable": "%X{X-Span-Export:-}",
                    "pid": "${PID:-}",
                    "thread": "%thread",
                    "class": "%logger{40}",
                    "rest": "%message",
                    "schema":"ci2",
                    "group":"devops",
                    "site": "${site}"

                    }
                </pattern>
            </pattern>
        </providers>
    </encoder>  
    <rollingPolicy
        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- rollover daily and when the file reaches 10 MegaBytes -->
        <fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.json
        </fileNamePattern>
        <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
            <maxFileSize>10MB</maxFileSize>
        </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>

</appender>
-----------------------

In this appender def, the <pattern> is used to add values to the json def for sleuth.    

How can I define entries in this pattern and pass in the dynamic value to the logger.  It looks possible and sleuth may do it with  

                     "trace": "%X{X-B3-TraceId:-}",
                    "span": "%X{X-B3-SpanId:-}",
                    "parent": "%X{X-B3-ParentSpanId:-}",
                    "exportable": "%X{X-Span-Export:-}",

另一个可行的 API 是记录器接受一个字符串并将用户提供的字符串附加到日志文件的末尾

最佳答案

总而言之: 您不需要创建记录器,您需要检查附加程序。 幸运的是,Logback 已经支持具有 JSON 布局的 Console Appender 的 json 序列化。

logback.xml/logback-spring.xml中配置控制台附加程序:

<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
        <jsonFormatter
            class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
            <prettyPrint>true</prettyPrint>
        </jsonFormatter>
        <timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
    </layout>
</appender>

并在 POM 中添加一些依赖项。

参见here完整教程

关于java - Spring Boot自定义滚动日志文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59653776/

相关文章:

java - 如何使用值而不是键从哈希表中删除元素?

java - 如何在不破坏 CoordinatorLayout.LayoutParams 的情况下重写 CoordinatorLayout.Behavior

java - 简单的网络服务示例 tomEE 不工作

java - 如何使用递归方法打印 a 到 z

php - 当我单击登录按钮时发生 fatal error 调用成员函数execute()

java - JAXB 和 Jersey 列表解析?

ios - 为什么 NSURLSession.dataTaskWithURL() 不调用我的完成处理程序?

json - 在 PySpark 中有效地清理复杂 JSON 文件中的 HTML 实体

java - 如何等待主线程直到异步方法完成?

java - Spring aop 破坏了原始代码?启用方面时, Autowiring bean 的字段变为空