Maven項目配置Logback輸出JSON格式日志


最近,項目提出需求,日志需要固定輸出為JSON格式,以便后端Flink程序解析.

項目背景

項目為簡單的Maven項目,日志由Filebeat采集,因此不需要配置輸出至Logstash.
下面為pom.xml文件中配置的依賴,此處使用logstash-logback-encoder完成日志格式轉換操作.

       <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.28</version>
        </dependency>
        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>6.1</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.2.3</version>
        </dependency>

Logback配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>probe</contextName>

   <!-- 配置文件存儲地址  -->
    <property name="LOG_PATH" value="./logs"/>

    <!-- 讀取應用程序配置文件中內容,獲取下文所需要的region屬性 --->
    <property resource="application.properties"/>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers class="net.logstash.logback.composite.loggingevent.LoggingEventJsonProviders">
                <pattern>
                    <pattern>
                        {
                        "date":"%d{yyyy-MM-dd HH:mm:ss.SSS}",
                        "level":"%level",
                        <!-- system屬性由程序動態確定,通過Slf4j提供的MDC進行具體設置 -->
                        "system":"%X{system} ",
                        <!-- 讀取配置文件中的屬性,並設置至日志中  -->
                        "region":"${application.region}",
                        "filepath":"%class:%line",
                        "msg":"%msg"
                        }
                    </pattern>
                </pattern>
            </providers>
            <charset>UTF-8</charset>
        </encoder>
        <append>true</append>

        <!--  配置日志文件滾動存儲策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/probe.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <MaxHistory>10</MaxHistory>
            <maxFileSize>10MB</maxFileSize>
            <totalSizeCap>300MB</totalSizeCap>
        </rollingPolicy>
    </appender>

    <root level="FILE">
        <appender-ref ref="console"/>
    </root>
</configuration>

上述即為logback.xml文件中的配置內容,需要注意日志中的region從配置文件application.properties中獲取,而system屬性則同msg字段一樣由程序動態設置.

MDC設置system屬性

    /**
     * 衡量單次http請求的時延
     *
     * @param url 請求地址
     */
    private static void measureHttpTimeDelay(String url, Platform platform) {
        // MDC中設置system屬性
        MDC.put("system", platform.toString());
        OkHttpClient client = new OkHttpClient();
        client.newBuilder().connectTimeout(5, TimeUnit.SECONDS)
                .readTimeout(5, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder().url(url).build();
        Instant before = Instant.now();
        try (Response response = client.newCall(request).execute()) {
            Instant after = Instant.now();
            if (response.isSuccessful()) {
                long duration = Duration.between(before, after).toMillis();
                log.info("請求成功!" + response.message() + "時延 = " + duration + "ms");
            } else {
                log.info("請求失敗!" + response.message());
            }
        } catch (IOException e) {
            log.error("get http response failed, url: {}, ex: {}", url, e.getMessage());
        }
        // MDC中清除system屬性設置
        MDC.remove("system");
    }

上述程序,模擬一個簡單的http請求,並記錄相應日志.
需要注意,MDCThreadLocal實現,因此在多線程環境下使用需要注意.

最終日志

最終日志如下圖所示:

{"date":"2019-09-05 21:16:44.643","level":"INFO","system":"ALI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"請求成功!OK時延 = 439ms"}
{"date":"2019-09-05 21:16:45.326","level":"INFO","system":"HUAWEI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"請求成功!OK時延 = 165ms"}
{"date":"2019-09-05 21:16:46.513","level":"INFO","system":"ALI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"請求成功!OK時延 = 485ms"}
{"date":"2019-09-05 21:16:56.130","level":"INFO","system":"HUAWEI_YUN ","region":"HUABEI","filepath":"com.test.Application:38","msg":"請求成功!OK時延 = 419ms"}

PS:
如果您覺得我的文章對您有幫助,請關注我的微信公眾號,謝謝!
程序員打怪之路


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM