首頁 > 軟體

功能強大的TraceId 搭配 ELK使用詳解

2022-09-16 22:01:07

引言

之前寫了一篇關於 TraceId 的文章:為全域性請求新增 TraceId ,看紀錄檔再也不懵逼

今天就接著 TraceId 做一些優化,如果想快速的定位到問題,就要實現對紀錄檔的快速搜尋,所以本文就引入 ELK 技術棧。

ELK 是 ES、Logstash、Kibana 的總稱,其核心功能就是實現資料的收集、搜尋、視覺化。具體功能和使用在本文都會提到。

需求分析

先分析一下,我們想實現的核心功能是搜尋,必然是用 ES 實現,那問題就轉換成如何將紀錄檔收集並儲存到 ES

紀錄檔大家都不陌生了,可以在控制檯列印,也可以存入檔案,那能不能直接輸入 ES 呢,好像沒聽說過。

這裡就要用到 Logstash 來收集紀錄檔,Spring 預設的紀錄檔框架 Logback 已經對其提供了支援,我們要做的只是編寫組態檔。

Logstash 有個問題就是非常佔用記憶體,所以本文後面會介紹另一個比較輕量級的紀錄檔收集工具 FileBeat ,由 Go 語言編寫。

同時對於真實的線上環境為了保證吞吐量和可靠性,都會引入 Kafka 進行解耦,本文不做演示。

下面就進入實戰部分,搭建一套紀錄檔收集與搜尋系統。

ES

推薦大家去 elastic 的中文社群下載 ELK ,速度會比較快,官網當然也是可以的。目前最新版本是8.+,推薦還是下 7.+ 比較穩妥,具體版本隨意,但 ELK 的版本要一致。

本文使用 7.14.2 版本。下載下來解壓就行,不廢話。

修改組態檔

進入 config 目錄:

# elasticsearch.yml
path.data: /Users/li/programs/elasticsearch-7.14.2/data
path.logs: /Users/li/programs/elasticsearch-7.14.2/logs
ingest.geoip.downloader.enabled: false
# jvm.options
# 如果記憶體夠用也可以不修改
-Xms1g
-Xmx1g

啟動

./bin/elasticsearch
[2022-09-13T10:54:10,015][INFO ][o.e.n.Node               ] [LdeMacBook-Pro.mshome.net] started
[2022-09-13T10:54:10,730][INFO ][o.e.l.LicenseService     ] [LdeMacBook-Pro.mshome.net] license [b7a596e6-1b61-4e6d-af2f-7eab70fe693b] mode [basic] - valid

測試

瀏覽器存取:http://localhost:9200/

kibana

下面再安裝 ES 的視覺化工具,下載地址同上,版本號同上。

修改組態檔

# kibana.yml
server.port: 5601
server.host: "localhost"
elasticsearch.hosts: ["http://localhost:9200"]
kibana.index: ".kibana"
i18n.locale: "zh-CN" # 中文

啟動

./bin/kibana
[10:56:42.001] [info][status] Kibana is now degraded
[10:56:44.784] [info][status] Kibana is now available (was degraded)

測試

瀏覽器存取:http://localhost:5601/

新增資料並查詢

PUT /ecommerce/product/1
 {
     "name" : "gaolujie yagao",
     "desc" :  "gaoxiao meibai",
     "price" :  30,
     "producer" :  "gaolujie producer",
     "tags": [ "meibai", "fangzhu" ]
 }
GET /ecommerce/product/1

Logstash

下載地址同上,版本號同上。

拷貝組態檔 logstash-sample.conf

# logstash-log-boot.conf
input {
  tcp {
    mode => "server"
    host => "127.0.0.1"
    # 通過監聽9001埠進行採集紀錄檔
    port => 9001
    codec => json_lines
  }
}
output {
  elasticsearch {
    # ES的地址
    hosts => ["http://127.0.0.1:9200"]
    # 索引的名稱
    index => "boot-log-collection-%{+YYYY.MM.dd}"
  }
  stdout {
    codec => rubydebug
  }
}

啟動

./bin/logstash -f ./config/logstash-log-boot.conf

Logback

OK,到此 ELK 就搭建完了,接下來就是設定 boot 應用的紀錄檔輸出。logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_PATTERN"
              value="%d{yyyy-MM-dd} %d{HH:mm:ss.SSS} [%highlight(%-5level)] [%boldYellow(%X{traceId})] [%boldYellow(%thread)] %boldGreen(%logger{36} %F.%L) %msg%n">
    </property>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <!-- 控制檯列印INFO及以上級別的紀錄檔 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>
    <!--    LOGSTASH 紀錄檔收集-->
    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <!-- 在logstash啟動檔案logstash-log-boot.conf中設定的IP地址和埠 -->
        <destination>127.0.0.1:9001</destination>
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder" />
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
    </appender>
    <root>
        <appender-ref ref="STDOUT"/>
        <!-- 引入LOGSTASH-->
        <appender-ref ref="LOGSTASH" />
    </root>
</configuration>

如果報LogstashTcpSocketAppender這個類找不到,需要新增一個依賴:

	<dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
            <version>6.6</version>
        </dependency>

其實這個依賴就是用來網路通訊的,來傳輸紀錄檔。

測試

這時啟動應用,觀看 Logstash 的控制檯,會跟著列印紀錄檔,再開啟 ES ,建立我們設定好的查詢索引,神奇的事情發生了,紀錄檔一條一條的展示出來。

再結合 TraceId 進行搜尋,簡直逆天!

Filebeat

同樣是下載 FileBeat 。

修改組態檔

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /Users/li/IdeaProjects/cloud-alibaba/cloud-service-commerce/commerce-user/log/*.log
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
setup.template.settings:
  index.number_of_shards: 2
setup.kibana:
  host: "localhost:5601"
output.elasticsearch:
  hosts: ["localhost:9200"]
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~

因為 Filebeat 是基於監控紀錄檔檔案有沒有新增來同步資料的,所以需要設定紀錄檔檔案的目錄。

可以直接輸出到 ES ,也可以輸出到 Logstash 。二選一!

再設定 logback.xml

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--紀錄檔檔案輸出位置-->
        <File>/Users/li/IdeaProjects/cloud-alibaba/cloud-service-commerce/commerce-user/log/user.log</File>
        <encoder>
            <!--[%X{requestId}] 執行緒id,方便排查紀錄檔-->
            <pattern>%date %level [%thread] [%X{requestId}] [%logger{36}.%method():%line] %msg%n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 新增.gz 歷史紀錄檔會啟用壓縮 大大縮小紀錄檔檔案所佔空間 -->
            <!--<fileNamePattern>/home/log/stdout.log.%d{yyyy-MM-dd}.log</fileNamePattern>-->
            <fileNamePattern>
                /Users/li/IdeaProjects/cloud-alibaba/cloud-service-commerce/commerce-user/log/user-%d{yyyy-MM-dd}.log
            </fileNamePattern>
            <maxHistory>3</maxHistory><!-- 保留 3 天紀錄檔 -->
        </rollingPolicy>
    </appender>
		<root>
        <appender-ref ref="FILE"/>
    </root>

再次啟動專案,發現紀錄檔已寫入檔案

進入 ES 查詢,同樣查詢到紀錄檔。

經過測試,FileBeat 的紀錄檔收集延遲時間要比 Logstash 長,畢竟基於檔案進行同步,可以理解,而且本身業務實時性要求不高。

最後

內容看著比較多,實際很容易實現,但真正生產環境要複雜的多,還需不斷思考。

以上就是功能強大的TraceId 搭配 ELK使用詳解的詳細內容,更多關於TraceId 搭配 ELK的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com