1. 程式人生 > 程式設計 >初識MinBox Logging

初識MinBox Logging

I. MinBox Logging 是什麼?

1. 採集端 & 服務端

MinBox Logging是由minbox-projects開源組織推出的一款零侵入分散式鏈路日誌元件,可用於微服務、RPC、單體應用使用。

MinBox Logging記憶體在兩個概念,分別是:ClientServer

  • Client

    Client我們可以理解為日誌的採集端,也就是我們的業務服務端,你的服務需要記錄日誌就可以理解作為Client端。

  • Server

    Server是日誌的管理服務端點,提供日誌的儲存、閥值分析提醒(暫未釋出)、鏈路分析(暫未釋出)等功能,統一接收日誌採集端上報的請求日誌資訊並做記錄,目前支援寫入資料庫、自定義儲存機制,下一步整合訊息佇列

    來處理大批量日誌的儲存問題。

    服務端通過整合服務註冊中心可以完成負載均衡多節點部署。

II. MinBox Logging 可以做什麼?

MinBox Logging可以用來記錄你的應用程式請求日誌資訊,可以將發起請求的IP頭資訊URL引數請求主體引數耗時響應內容異常堆疊資訊等。

下面是MinBox Logging可以獲取到的基本資訊,如下所示:

{
	"endTime":1568252359448,"httpStatus":200,"requestBody":"","requestHeaders":{
		"accept":"*/*","host":"localhost:40030"
,"user-agent":"curl/7.54.0" },"requestIp":"10.180.98.120","requestMethod":"GET","requestParam":"{}","requestUri":"/open/system/time/current","responseBody":"{\"code\":\"SUCCESS\",\"data\":1568252359425,\"errorMsg\":\"\",\"success\":true,\"timestamp\":1568252359425}","responseHeaders":{},"serviceId":"bff-open-api"
,"serviceIp":"10.180.98.245","servicePort":"40030","spanId":"56aaa01c-cad5-41c6-bd46-bf94626d77bd","startTime":1568252359416,"timeConsuming":32,"traceId":"ad9ff32c-6195-4f75-adf2-1eb1ed98aaf9" } 複製程式碼

以上資訊是由MinBox Logging進行在控制檯格式化並列印輸出(前提:配置輸出日誌引數),我們可以通過MinBox Logging提供的日誌通知介面來實現自己的業務邏輯,詳見org.minbox.framework.logging.client.notice.LoggingNotice原始碼。

2. 日誌來源

Client採集的每一條請求日誌都會攜帶產生的伺服器IP應用程式名稱應用程式埠號並且一併上傳到Server,根據這些內容可以直接定位到日誌的來源位置,可根據Client上報的數量進行佔比分析,來決定服務請求分發負載均衡權重配置

3. 耗時分析

每一次請求都會產生耗時,而介面耗時過長,可能會導致介面阻塞(如果應用程式沒有加入熔斷機制),針對這個問題MinBox Logging提供了計算耗時的方式,通過MinBoxLog#timeConsuming欄位獲取本次請求的耗時時間,單位是:毫秒,根據自己的業務自定義一個耗時閥值來進行通知耗時過長的請求給指定郵箱或者其他途徑。

4. 異常解決

如果在使用者請求過程中遇到了異常資訊,而應用程式的控制檯日誌檔案過大進行篩選異常資訊時會耽誤一定的時間,針對這個問題MinBox Logging提供獲取請求中遇到異常的堆疊資訊,通過異常資訊可以精準的定位出現異常的程式碼位置。

5. 引數監控

使用者傳送的請求引數,我們無法進行限制,不過我們可以進行引數監控,通過制定引數對應的引數值來進行分析、監控,將分析結果通過儲存或者通知方式告知。

6. 敏感頭資訊監控

請求引數一致,通過請求頭資訊我們同樣能做的事情有很多。

7. 請求IP分析

通過這個功能,我們可以記錄每一個發起請求的IP地址介面訪問量訪問的頻率峰值等資訊。

8. 其他

等待發掘合適的業務.

III. 日誌獲取方式

日誌資訊在ClientServer都可以獲取,拿到請求日誌資訊後,可以實現上面的擴充套件功能。

9. Client獲取日誌

Client端可以通過LoggingNotice方式來獲取MinBoxLog日誌物件,根據物件的欄位值來進行處理分析等業務,可建立多個LoggingNotice實現類來分析處理不同的業務,優先順序根據LoggingNotice#getOrder方法的返回值而定。

/**
 * 自定義日誌通知
 * 當不上報日誌到`Logging Admin`時,可使用{@link LoggingNotice}來進行本地處理日誌
 * 上報日誌與本地處理不衝突,可並存
 *
 * @author 恆宇少年
 */
@Component
public class CustomerLoggingNotice implements LoggingNotice {
    /**
     * 通知方法
     *
     * @param minBoxLog ApiBoot Log
     */
    @Override
    public void notice(MinBoxLog minBoxLog) {
        System.out.println(minBoxLog.getTraceId());
      	// MinBoxLog 物件即為控制檯列印的json資訊,可以拿到裡面的全部欄位內容
    }

    /**
     * 通知執行優先順序
     * {@link #getOrder()}方法返回值值越小優先順序越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 1;
    }
}
複製程式碼

通過notice方法的引數可以直接獲取到MinBoxLog物件,可根據引數值進行自定義業務判斷處理。

10. Server獲取日誌

建議在Server端進行日誌統一處理,雖然Client可以通過實現LoggingNotice介面來擴充套件日誌處理,不過也是針對單個Client應用程式,對於分散式微服務應用程式來說卻顯得那麼的無力。

因為每個Client都會進行上報到Server,所以在Server進行日誌處理是最好的選擇。

Server可以通過監聽ReportLogEvent事件來獲取Client的基本資訊以及上報的日誌列表(如果Client配置了延遲上報,每次可上報多條。),如下所示:

/**
 * 自定義上報日誌事件{@link ReportLogEvent}監聽
 *
 * @author 恆宇少年
 */
@Component
public class CustomerReportEventListener implements SmartApplicationListener {
    /**
     * logger instance
     */
    static Logger logger = LoggerFactory.getLogger(CustomerReportEventListener.class);

    /**
     * 判斷事件型別為{@link ReportLogEvent}
     *
     * @param eventType
     * @return
     */
    @Override
    public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
        return ReportLogEvent.class == eventType;
    }

    /**
     * 自定義處理業務
     * Client一次可上報多條日誌{@link MinBoxLog}資訊
     *
     * @param event {@link ReportLogEvent}
     */
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        ReportLogEvent reportLogEvent = (ReportLogEvent) event;
        LoggingClientNotice loggingClientNotice = reportLogEvent.getLogClientNotice();

        // MinBoxLog 日誌列表
        List<MinBoxLog> logs = loggingClientNotice.getLoggers();

        logger.debug("上報日誌服務:{},IP地址:{},埠號:{},日誌列表:",loggingClientNotice.getClientServiceId(),loggingClientNotice.getClientServiceIp(),loggingClientNotice.getClientServicePort(),logs);
    }
}
複製程式碼

SmartApplicationListenerSpring提供的事件監聽介面,由於該介面繼承了Ordered所以擁有了#getOrder方法,通過該方法可以調整自定義日誌監聽的執行優先順序。

IV. 原始碼 & 檔案 & 整合實踐