本文紀錄如何把基礎的 Observability Tools 架設起來
主要是 influxDB + OpenTelemetry
我們的目標是在一個分散式系統上架設效能觀測工具,如下圖所示,在 Monitiored System [1..n] 上架設我們效能工具 (ddshark) 以及一個現成的觀測工具 (Node Exporter),兩種工具是用不同的協定發送觀測資料,因此有兩個 data storage 分別儲存效能資料。最後用 Grafana UI 視覺畫工具分析效能資料。
圖中,我們使用 ddshark 當作示範的客製化效能工具。ddshark 使用 opentelemetry 的協定發送 trace 資料。我們的目標是把 opentelmetry 格式的資料儲存到 InfluxDB 裡,但是 InfluxDB 是沒辦法直接接收 opentelmetry 的資料,因此我們需要另一個工具叫 Opentelemetry Collector
首先,下載 opentelemetry-collector-contrib,你可能會疑問,為何不下載官方版本的 opentelemetry-collector-releases 呢?這是因為能夠支援 trace 轉換成 InfluxDB 格式資料的 exporter 已經包含在 contrib 裡面,而官方版本並沒有這個功能。
移動到 opentelemetry-collector-contrib 的目錄底下,build 之後會有 otelcontribcol_linux_amd64 這個執行檔,首先,先確認我們的效能工具丟出的 opentelemetry trace 能夠被 otel-collector 接收。
修改 otel-collector 的 yaml 設定檔,位於 examples/demo/otel-collector-config.yaml
,把接收到的 opentelemetry trace 顯示在終端機上。
啟動 otel-collector 之後,執行我們的效能工具 (ddshark),並且丟出幾個測試用的 OpenTelemetry trace,可以看到 otel-collector 的確有接到到我們發送的資料。
如果需要用測試 otel-collector 跑在 docker container 可用以下命令
otel-collector 測試可以使用之後,接下來要加入 InfluxDB,確認我們工具丟出來的 trace 可以經由 otel-collector 最終寫入 InfluxDB 資料庫裡。
這裡我們直接使用 InfluxDB 官方提供的 docker image,省去自己準備環境的麻煩。使用以下命令啟動 InfluxDB,並將 container 中的連接埠號 8086 映射到主機的 8086。
在測試之前,還必須要設定 InfluxDB,當第一次啟動時,InfluxDB 會需要你設定基本資訊,以及 Organization Name, Bucket Name,這兩個資訊相當重要,等等在設定 otel-collector 時需要用到。
輸入完基本資訊,InfluxDB 就算設定好了,接下來會給你最高權限的 token,讓你可以任意寫入讀取 InfluxDB 裡的資料。
接下來回到 otel-collector 這邊,我們需要把剛剛的資訊填 otel-collector 的 yaml 設定檔。這裡我們中間 exporters
新增一個 InfluxDB 的 exporter,以及對應的 org
, bucket
, token
,讓 exporter 知道要把 OpenTelemtry trace 轉送到哪個地方。
同時,將最下面的 service
裡面 exporters
欄位改成 [logging, influxdb]
,讓 otel-collector 街收到 OpenTelemtry trace 的時候,把資訊送往終端機以及 InfluxDB。
在 InfluxDB 還正在跑的時候,我們重新啟動 otel-collector,並且用我們的效能工具 (ddshark) 丟出幾個測試用的 OpenTelemetry trace,如果一切運作正常,就能看到 trace 成功出現在 InfluxDB 的 data exporter 裡面,如下圖所示。
圖中是將界面切換成 "QUERY BUILDER" 之後,使用以下 InfluxDB Query 尋找資料。
如文中一開始的圖所示,這個觀測系統的必要基礎設施為圖中正中間框起來的三個工具 Opentelemetry Collector, InfluxDB, Prometheus。
我們遇到的一個問題是,每次把這些工具一個一個跑起來十分麻煩,有沒有可能一鍵把所有必要基礎設施架設起來?這裡我們使用 docker compose
這個命令將所有工具,啟動在個別的 docker container 裡面。
同時我們希望只需要設定 InfluxDB 一次就好,另外,當停止所有 container 時能夠把當前狀態以及資料庫,都存到本機上,等到下次再執行 docker compose
,所有的狀態都還存在。
使用的腳本參考這個 repo https://github.com/build-on-aws/instrumenting-java-apps-using-opentelemetry
以下為架設工具所需要的檔案及其結構,o11y-backend 目錄底下的資料不需要更改,有需要調校 InfluxDB 的效能或行為時再去修改即可。
原始 repo 中沒有提供 influxdb-config.yaml,以下列出我用的設定檔當作參考。
先看 docker-compose.yaml
這個設定檔,這個檔案能夠決定有多少 docker container 需要啟動,以及啟動他們的必要參數,如 container 名稱,連接埠號等。以下我們關注 otel-collector (collector
) 以及 InfluxDB (influxdb
)。
collector
container_name
, hostname
都設成 collectorvolume
: 將本機上的 ./collector-config local.yaml 檔案掛載到 container 內部的 /etc/collector-config.yamlports
: otel-collector 預設埠號為 4317,因此將本機的 4317 port 映射到 container 內部的 4317 portinfluxdb
container_name
, hostname
都設成 influxdbvolume
: 將本機上 InfluxDB 設定檔 ./o11y-backend/influxdb-config.yaml 檔案掛載到 container 內部的 /etc/influxdb2/config../influxdb2:/var/lib/influxdb2
,這樣能夠把 InfluxDB 的設定以及資料庫都保存到本機上。ports
: InfluxDB 預設埠號為 8086,因此將本機的 8086 port 映射到 container 內部的 8086 portdocker-compose.yaml
接下來看 otel-collector 的設定檔,跟之前一樣把所有必要資訊都填進去,這邊要注意的是 influxDB 的 endpoint 改成 http://influxdb:8086,因為我們剛剛有設定執行 InfluxDB 的 container 的名稱。
另外,在還沒有開始執行前,因為還沒設定 InfluxDB,所以一開始還不會知道 org
, bucket
,token
這三個資訊,因此,我們需要執行一次 docker compose
,進到 InfluxDB 裡面做第一次設定,把這些資訊都記錄下來,順便測試必要的工具都能啟動。
同時,因為我們把 InfluxDB 的狀態都紀錄到本機,所以不用擔心重新啟動 docker compose
之後資料會不見,第二次啟動之後也不需要再到 InfluxDB 裡面再做設定。
接下來試著用 docker compose
啟動所有工具。
到了這邊所有工具就都啟動起來了,啟動之後我們同樣用我們的效能工具 (ddshark) 丟出幾個測試用的 OpenTelemetry trace,看看是否運作正常。可以看到 Query 得到的資料跟一開始單獨測試時一樣。
以下為操作 InfluxDB 的幾個實用命令,如何用 docker 控制跑在 container 裡的 InfluxDB
刪除一個 bucket
建立一個 bucket
刪除 bucket 內某個特定範圍的資料,注意這類需要查詢的刪除會耗費大量時間
我們已經架起 InfluxDB,而且 Opentelemetry trace 已經存到資料庫裡面了,現在只剩下寫 Query 撈出我們想要的資料。如果是要用 Grafana 視覺化資料,學習 InfluxDB 查詢語法也是必須要的。
我目前使用的 InfluxDB 版本是 v2,使用的是 InfluxQL 的查詢語法,未來當 v3 開源之後,就會重新使用 SQL 的語法,但 v3 開源的時間未知,因此目前用 InfluxDB v2 必須學會使用 InfluxQL。
重要工具
map
https://docs.influxdata.com/flux/v0/stdlib/universe/map/
Output tables are the result of applying the map function (fn) to each record of the input tables.
例如以下範例用來處理 ddshark 的效能資料,因為我的資料存在 attribute 裡面,opentelemtry 會把 attribute 包裝成 json 格式給你,因此用以下 fn 將需要的 attribute 取出。
elapsed
https://docs.influxdata.com/flux/v0/stdlib/universe/elapsed/
elapsed() returns the time between subsequent records.
For each input table, elapsed() returns the same table without the first row (because there is no previous time to derive the elapsed time from) and an additional column containing the elapsed time.
應用以上
注意