1. 程式人生 > 程式設計 >使用ApiBoot Logging進行統一管理請求日誌

使用ApiBoot Logging進行統一管理請求日誌

ApiBoot Logging通過整合minbox-logging來進行管理每一次請求的日誌資訊,包含頭資訊引數主體內容路徑、發生的伺服器相關資訊等,根據介面的響應狀態還可以記錄響應的頭資訊、響應的內容以及發生異常時的堆疊資訊

minbox-projects開源組織

“org.minbox.framework” 致力於向廣大開發者提供一系列的 “開箱即用” 的框架落地實現解決方案。

自從ApiBoot框架的落地,內部整合的第三方外掛(plugin)日漸增多也同樣導致了ApiBoot的原始碼太過於冗腫,針對這個問題minbox-projects開源組織就誕生了,ApiBoot第一個加入了該組織,並且會將ApiBoot

內整合的第三方外掛進行陸續分離,將每一個外掛作為獨立的開源專案加入minbox-projects開源組織,方便各個專案的單獨維護以及更新發版。

組織首頁:gitee.com/minbox-proj…

minbox-logging日誌元件

minbox-logging日誌元件是minbox-projects開源組織內的一員,是一款分散式零侵入式、鏈路式請求日誌分析框架

提供Admin端點進行採集日誌分析日誌日誌告警通知服務效能分析等。通過Admin Ui可檢視實時鏈路日誌資訊、線上業務服務列表,致力解決request -> response整個業務請求的日誌分析以及記錄。

minbox-logging日誌元件原始碼:

gitee.com/minbox-proj…

建立示例專案

通過idea開發工具建立一個SpringBoot專案。

  • pom.xml依賴
<!--配置引數-->
<properties>
  <java.version>1.8</java.version>
  <api.boot.version>2.1.4.RELEASE</api.boot.version>
</properties>

<dependencies>
  <!--Web-->
  <dependency>
    <groupId
>
org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--ApiBoot Logging--> <dependency> <groupId>org.minbox.framework</groupId> <artifactId>api-boot-starter-logging</artifactId> </dependency> </dependencies> <dependencyManagement> <!--ApiBoot統一版本依賴--> <dependencies> <dependency> <groupId>org.minbox.framework</groupId> <artifactId>api-boot-dependencies</artifactId> <type>pom</type> <scope>import</scope> <version>${api.boot.version}</version> </dependency> </dependencies> </dependencyManagement> 複製程式碼
  • 測試控制器

新增一個用於測試的LoggingSampleController控制器,原始碼如下所示:

/**
 * 請求日誌示例
 *
 * @author 恆宇少年
 */
@RestController
@RequestMapping(value = "/test")
public class LoggingSampleController {
    /**
     * 驗證請求引數以及相應內容
     *
     * @param name
     * @return
     */
    @GetMapping
    public String hello(@RequestParam("name") String name) {
        return "你好:" + name;
    }

    /**
     * 驗證主體請求內容以及相應內容
     *
     * @param user
     * @return
     */
    @PostMapping
    public String bodyHello(@RequestBody User user) {
        return "你好:" + user.getName();
    }

    /**
     * RequestBody 示例類
     */
    @Data
    public static class User {
        private String name;
    }
}
複製程式碼
  • application.yml
spring:
  application:
    name: apiboot-unified-manage-request-logs
server:
  port: 8080
複製程式碼

由於ApiBoot Logging需要記錄日誌產生的伺服器相關資訊,所以spring.application.name以及server.port這兩個引數必須配置,要不然啟動專案時會丟擲錯誤資訊。

  • @EnableLoggingClient註解
@SpringBootApplication
@EnableLoggingClient
public class ApibootUnifiedManageRequestLogsApplication {

    public static void main(String[] args) {
        SpringApplication.run(ApibootUnifiedManageRequestLogsApplication.class,args);
    }

}
複製程式碼

使用@EnableLoggingClient註解來開啟日誌的客戶端,將該註解配置在入口類上,內部通過ImportBeanDefinitionRegistrar進行註冊minbox-logging-client所需要的Bean

ApiBoot的版本統一依賴

我們在使用SpringBoot時發現我們新增的依賴並不需要指定具體的版本號,這就是版本統一依賴起到的作用,主要還是Maven繼承關係緣故。

ApiBoot內也存在這麼一個統一維護依賴版本的模組api-boot-dependencies,這個模組原始碼僅一個pom.xml檔案,主要用來配置每一個第三方依賴或者內建的依賴的具體版本。

我們通過在專案中的pom.xml配置檔案內新增如下版本管理依賴:

<dependencyManagement>
  <!--ApiBoot統一版本依賴-->
  <dependencies>
    <dependency>
      <groupId>org.minbox.framework</groupId>
      <artifactId>api-boot-dependencies</artifactId>
      <type>pom</type>
      <scope>import</scope>
      <version>${api.boot.version}</version>
    </dependency>
  </dependencies>
</dependencyManagement>
複製程式碼

就可以不指定版本號使用ApiBoot所提供的全部依賴。

測試請求

專案準備完成,我們先來把專案通過SpringBoot Application方式進行啟動,通過如下curl命令訪問我們的測試介面:

curl http://localhost:8080/test\?name\=hengboy
複製程式碼

訪問完成後,請求成功,但是控制檯並沒有列印任何請求日誌資訊,倒是有一個警告的日誌:

Not set 【LoggingAdminDiscovery】in LoggingFactoryBean,don't invoke report request logs.
複製程式碼

這個警告告知的很清楚,我們並未配置logging-admin,所以無法執行日誌的上報,我們本章節是獨立使用ApiBoot Logging日誌元件,所以這個警告資訊可以忽略。

控制檯列印請求日誌

ApiBoot Logging提供了一個配置api.boot.logging.show-console-log,該配置預設值為false,通過該配置可以實現在控制檯列印請求日誌。

application.yml配置檔案內新增配置如下所示:

api:
  boot:
    # ApiBoot Logging 日誌元件配置
    logging:
      show-console-log: true
複製程式碼

新增完成後,重啟專案,再次訪問測試介面,控制檯列印如下所示:

2019-10-16 10:20:18.489  INFO 3930 --- [         task-1] o.m.f.l.c.n.support.LoggingLocalNotice   : Request Uri:/test, Logging:
{"endTime":1571192418416,"httpStatus":200,"requestBody":"","requestHeaders":{"host":"localhost:8080","user-agent":"curl/7.64.1","accept":"*/*"},"requestIp":"0:0:0:0:0:0:0:1","requestMethod":"GET","requestParam":"{\"name\":\"hengboy\"}","requestUri":"/test","responseBody":"你好:hengboy","responseHeaders":{},"serviceId":"apiboot-unified-manage-request-logs","serviceIp":"127.0.0.1","servicePort":"8080","spanId":"35a22772-5015-438a-a441-ba407926b789","startTime":1571192418391,"timeConsuming":25,"traceId":"ec53d162-314e-4516-8c24-5d5e03181543"}
複製程式碼

這時我們就可以看到列印的請求日誌資訊了,不過列印的日誌內容並未進行美化,不要著急,ApiBoot Logging同樣提供了一個配置來進行美化輸出內容。

控制檯美化請求日誌

ApiBoot Logging提供了配置api.boot.logging.format-console-log-json,該引數預設為false,我們通過修改該配置的值可以實現美化列印請求日誌。

application.yml配置檔案內新增配置如下所示:

api:
  boot:
    # ApiBoot Logging 日誌元件配置
    logging:
      show-console-log: true
      format-console-log-json: true
複製程式碼

新增完成後我們再次來重啟專案後,訪問測試介面,控制檯列印如下所示:

2019-10-16 10:24:05.480  INFO 4051 --- [         task-1] o.m.f.l.c.n.support.LoggingLocalNotice   : Request Uri:/test, Logging:
{
	"endTime":1571192645404,"requestHeaders":{
		"accept":"*/*","host":"localhost:8080","user-agent":"curl/7.64.1"
	},"spanId":"277c0973-8042-4740-a8e7-2dbb0c7bb42c","startTime":1571192645381,"timeConsuming":23,"traceId":"7a742942-f3cc-4d72-9493-d828b090f1cc"
}
複製程式碼

這樣是不是很直接明瞭的看到了請求的詳細資訊了?不過建議根據自己專案的實際情況來配置,美化後的日誌會佔用更多的控制檯行

LoggingNotice日誌通知

ApiBoot Logging提供了日誌通知的介面,我們只需要實現該介面就可以獲取到每一次請求日誌物件,還可以自定義每一個日誌通知實現類的執行順序

ApiBoot Logging內部提供的實現類如下圖所示:

  • LoggingLocalNotice

    該類就是用於在控制檯列印請求日誌以及美化請求日誌的實現,優先順序為:Ordered#HIGHEST_PRECEDENCE(最高優先順序)。

  • LoggingAdminNotice

    該類用於將請求日誌上報到Logging Admin,優先順序為:Ordered#HIGHEST_PRECEDENCE +1,僅低於LoggingLocalNotice

使用LoggingNotice新增Header

在上面我們已經知道了兩個內建的LoggingNotice實現類,優先順序我們也已經清楚了,那麼我們如果新增自定義的LoggingNotice實現類來向本次請求日誌的RequestHeader內新增一個我們自定義的頭資訊該怎麼做呢?

AddHeaderLoggingNotice通知類原始碼如下所示:

/**
 * 通過{@link LoggingNotice}向日志的請求header內新增區域資訊
 *
 * @author 恆宇少年
 */
@Component
public class AddHeaderLoggingNotice implements LoggingNotice {
    /**
     * 區域頭資訊key
     */
    private static final String SERVER_REGION = "server-region";

    @Override
    public void notice(MinBoxLog minBoxLog) {
        minBoxLog.getRequestHeaders().put(SERVER_REGION,"JiNan");
    }

    /**
     * 最大優先順序
     *
     * @return
     */
    @Override
    public int getOrder() {
        return HIGHEST_PRECEDENCE;
    }
}
複製程式碼

由於minbox-logging在設計初期就已經考慮到了這一點,所以新增起來比較簡單,我們只需要調整我們自定義日誌通知的優先順序,然後通過#notice方法修改本次請求日誌物件的值即可。

敲黑板劃重點

本章節我們介紹了ApiBoot Logging的整合使用,可用於採集請求日誌,能力確不僅僅如此,使用得當它會很強大,日誌通知設計可以使我們很好的控制一個請求的日誌,對日誌進行新增標識歸類等,可以通過配置來控制日誌列印以及美化

作者個人 部落格 使用開源框架 ApiBoot 助你成為Api介面服務架構師