Elastic APM 基礎教學 運用 APM client 和 server 端的函式庫來做應用程式層級的監控

me
林彥成
2020-09-12 | 4 min.
文章目錄
  1. 1. Elastic APM 基礎教學
    1. 1.1. Node.js 實作
    2. 1.2. 安裝 APM
    3. 1.3. 運用 Kibana 監看 APM
    4. 1.4. 應用程式層級監控
  2. 2. Elastic APM 深入理解
    1. 2.1. APM Data Modal
    2. 2.2. APM Server
    3. 2.3. APM Agents

Elastic APM 基礎教學

這篇文章將簡介如何運用 Elastic APM client 和 server 端的函式庫來進行應用程式性能監控。我們將示範如何安裝並使用 APM 監控 Node.js 服務狀態,將數據傳送至 Elasticsearch,並利用 Kibana 進行即時監控,協助您更快找到效能瓶頸。

為什麼服務的監控對於應用程式性能監控至關重要?

  • 同一台主機上可能運行多個服務,了解各服務的資源消耗(CPU、記憶體、流量)是優化的關鍵。

Elastic APM 解決的痛點:

  • 方便分析服務的資源消耗。
  • 快速識別耗時過長的 API 端點。
  • 記錄流程面(非系統崩潰)的應用程式錯誤。
    Elastic APM 錯誤捕獲範例

Node.js 實作

Server 端實作大致分成幾個步驟

  • npm install express --save
  • 開 API
    • / 一般 API
    • /slow 回應很慢的 API
    • /erro 拋出錯誤的 API
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const app = require("express")();

app.get("/", function (req, res) {
res.json("Hello World!");
});

app.get("/slow", function (req, res) {
setTimeout(() => {
res.json("Hello World!");
}, 50);
});

app.get("/error", function (req, res) {
apm.captureError(err);
res.status(500);
});

app.listen(3000);

Client 端就是在瀏覽器一直打 API,方便我們之後看報表

1
2
3
4
5
6
7
8
9
function test() {
for (let index = 0; index < 999; index++) {
fetch("/");
fetch("/slow");
if (index % 17) {
fetch("/error");
}
}
}

安裝 APM

  1. npm install elastic-apm-node --save
  2. 把 APM 引入並放在程式最前面
  3. 補上 apm.captureError(err);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Add this to the VERY top of the first file loaded in your app
var apm = require("elastic-apm-node").start({
// Override service name from package.json
// Allowed characters: a-z, A-Z, 0-9, -, _, and space
serviceName: "",

// Use if APM Server requires a token
secretToken: "",

// Set custom APM Server URL (default: http://localhost:8200)
serverUrl:
"https://18f3dcb3963748b7b2014755329bded7.apm.asia-east1.gcp.elastic-cloud.com:443",
});

app.get("/error", function (req, res) {
var err = new Error("Ups, something broke!");
apm.captureError(err);
res.status(500);
});

運用 Kibana 監看 APM

目標是讓 APM 的紀錄進來,所以到 Kibana 選單中 Observability 的 APM 監控,有幾個方便的功能:

  • Transactions 記錄各個 API 花了多少時間

    時間維度的圖表
    Elastic APM Transaction 響應時間趨勢圖

    各 API 分析,Slow 明顯比較慢
    Elastic APM Performance 監控:API 響應時間分析

  • Errors 記錄錯誤是在哪裏發生

    可以看出發生的行數
    Elastic APM Errors 錯誤追蹤介面

  • Metrics 基本硬體資訊紀錄

    Elastic APM Metrics 基礎硬體資源監控

  • Service Map 所有的服務地圖

    Elastic APM Service Map 服務關係圖

應用程式層級監控

在使用者操作前端網頁時,如果發生了不可預期的錯誤,我們該怎麼記錄起來? 在還沒有使用其他工具前,如果要監控並記錄錯誤,直觀通常就是寫出像是底下的程式,透過實作 logMyErrors 及搭配的後端 API 來協助。

  • 連線不正常: 先存 storage 下次使用者重新進入網頁時偷偷打 API 送回後端資料庫
  • 連線正常: 直接打 API 傳回去 DB 存
1
2
3
4
5
6
7
8
let data;
try {
// 需要測試的語句
data = getData(); // 可拋出例外的函數
} catch (e) {
data = "unknown";
logMyErrors(e); // 把例外物件傳給錯誤處理器
}

Elastic APM 深入理解

當然也有其他工具像是最近幾年也蠻多人使用的 Sentry,不過這系列主要是討論 Elastic Stack,APM 的存在就是為了簡化實作的部分,提供了:

  • 應用程式層的監控
  • client 端相關效能監控 (real user monitoring)

主要提供兩個大家會想知道的答案 (根本只有攻城獅才想知道?!!XDDD)

  • 每次 request 的回應時間
  • 服務在什麼時候出現哪些錯誤

一套完整的 APM 會由以下組成

  • APM Agents: 是一個 lib 需要寫進去我們的程式裡
  • APM Server:
    • beat framwork 實作的 http server
    • 協助驗證並轉換格式寫入 Elasticsearch
    • 資料灌爆來不及寫入的時候可以當 bufffer
    • 與使用者之間多了一層 server 對資料來說也更安全
    • 開 API 讓更多類型的 client 容易串接
  • Elasticsearch: 全文檢索的搜尋引擎
  • Kibana: 相當於 Elasticsearch 的後台 GUI

APM Data Modal

APM 記錄了不同類型的資訊:

  • Spans: 算是最基礎的單位,紀錄的內容包含執行的行數,會記錄某個活動的開始到結束
    • transaction.id: 紀錄對應到哪個 transaction
    • parent.id: Span 可能被 Span 或 transaction 包含
    • start time and duration
    • name
    • type
    • stack trace (optional)
  • Transactions: 多加上一些特殊 attribute 的 span,通常紀錄像是打到 server 的 request、Batch 或背景任務,通常理論上就是看這個
    • 事件發生當下的 timestamp
    • unique id, type, name
    • 相關的執行環境
      • service: environment, framework, language
      • host: architecture, hostname, IP
      • process: args, PID, PPID
      • URL: full, domain, port, query
      • user: email, ID, username (如果有)
  • Errors: 原始的 exception 訊息
    • 例外發生時的訊息
    • 在哪裏發生的
    • 相關的 Transaction ID

APM Server

最重要的就是要先下載並安裝 APM server,裝在本機跑起來之後預設會是 http://localhost:8200,然後會傳到 http://localhost:9200 的 Elasticsearch,把 apm-server.yml 中的 apm-server.rum.enabled,使用 Elastic Cloud 的話就是要注意要記得選有 APM 的,選對就會看到如下圖,接著點 kibana 首頁的 Add APM 照著教學裡面自動帶入的參數使用即可。

確認選到有 APM 模組的
Elastic Cloud APM 模組選擇
按照下圖範例中自動帶入的連結、token
Kibana Add APM 設定範例

APM Agents

APM agents 主要分成 Server 端和 Client 端兩種,且都需要自行加入到專案中,依照常撰寫的語言進行下載配置即可,Server 端 Node.js 的實作在剛剛已經示範過了。下面介紹的是 Client 端 JS 的部分,其中 serviceName 是用來分類用的,可自行命名。在 Client 端的實作也可以叫做 Real User Monitoring:

1
2
3
4
5
6
7
8
9
10
11
12
var apm = ininApm({
// Override service name from package.json
// Allowed characters: a-z, A-Z, 0-9, -, _, and space
serviceName: "virus-and-where-to-find-them",

// Use if APM Server requires a token
secretToken: "",

// Set custom APM Server URL (default: http://localhost:8200)
serverUrl:
"https://e9047bd2f1e84a619b8462911fe9378b.apm.asia-east1.gcp.elastic-cloud.com:443",
});

APM agents 在配置好後通常會自動蒐集相關可以蒐集的數據資訊,應該理論上就可以從這些 client 或 Server 中蒐集的數據找到程式的效能瓶頸,當然其他進階的部分還是要看相關 API 進行相關程式碼撰寫,初步可以看出的相關資訊可能如下:

  • Server 是否有 latency
  • 部分類似 GA 的統計

進行網頁操作後產生的數據範例
Elastic APM Transactions 數據範例


喜歡這篇文章,請幫忙拍拍手喔 🤣