最近,項目提出需求,日誌需要固定輸出為 格式,以便後端 程式解析. 項目背景 項目為簡單的 項目,日誌由 採集,因此不需要配置輸出至 . 下麵為 文件中配置的依賴,此處使用 完成日誌格式轉換操作. Logback配置 上述即為 文件中的配置內容,需要註意日誌中的 從配置文件 中獲取,而 屬性則同 字 ...
最近,項目提出需求,日誌需要固定輸出為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
請求,並記錄相應日誌.
需要註意,MDC
是ThreadLocal
實現,因此在多線程環境下使用需要註意.
最終日誌
最終日誌如下圖所示:
{"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"}