## 參考文件
1. prometheus:完整的中文介紹 https://p8s.io/docs/basic/overview/
2. Prometheus, loki, tempo 整合1:https://grafana.com/go/webinar/opinionated-observability-stack-prometheus-loki-tempo/
3. Prometheus, loki, tempo 整合2:https://grafana.com/blog/2020/03/31/how-to-successfully-correlate-metrics-logs-and-traces-in-grafana/
4. Spring Boot 教學:https://www.springcloud.io/post/2022-02/monitoring-springboot-applications/#gsc.tab=0
5. alert 配置文件:https://grafana.com/docs/grafana/latest/alerting/set-up/provision-alerting-resources/file-provisioning/
## Observability
典型的可觀察性可以分成三個部分:指標(Metrics)、日誌(Logs) 和跟踪(Traces),以下是使用工具以及簡略說明。
* Metrics 使用 prometheus
* Logs 使用 Grafana Loki
* Trace 使用 Grafana Tempo
* 最後將三種資料使用 Grafana 做資料視覺化
1. Metrics (指標):
Metrics 代表系統中的數值資料,例如 CPU、Memory 的使用量,或是呼叫 HTTP 請求的次數。
2. Logs (日誌):
就是應用程式發出的 Logs ,這些資料龐雜且觸發時間不固定,但對於解決問題是很有用的資訊。
3. Traces(追蹤):
Traces 指的是單次請求範圍內系統的所有數據,如一次 HTTP 請求時經過所有 Microservices 的資料,透過 Tracing 可以追蹤這些數據。
## Metrics, Logs, Traces 之間關係

1. 收到報警,需要解決問題
2. 查看 dashboard,了解詳細資訊(可能是哪些 Metrics 過量)
3. Adhoc query: 即時查詢
4. 使用 log 資料協助解決問題
5. 使用 trace 來詳細查看經過的為服務及處理時間,來發現瓶頸
Observability 協助 Devops 工程師在 request 需求量過大,或是硬體配置資源不夠需要擴展時,可以適時地解決問題。
早期只能使用 Logs 來了解系統的資訊及健康程度,但是 Logs 有一些缺點像是資訊量複雜且龐大,不好查找問題。
現今的監控加上 Metric 以及 Trace 這兩個強大的監控資訊,可以幫助我們更了解系統及為服務之間的關係,也讓解決問題的效率提升。
## 如何將資料視覺化

使用 grafana 來將上述的資料視覺化
### 優點
與上述提到的三個資料來源有很高的相容性
有美觀的 dashboard,且使用簡單
詳細的說明及配置會在後面說明
## Prometheus
Prometheus是一個監控系統和時序數據庫(TSDB, time series databse),特別適合監控雲原生環境,它具有多維數據模型和強大的查詢語言(PromQL),並在一個生態系統中集成了檢測、指標收集、服務發現和報警等功能,以特定的時間間隔使用 http 向監控對象拉取數據。
官方文檔:https://prometheus.io/docs/prometheus/latest/getting_started/
github: https://github.com/prometheus/prometheus
> Prometheus 之架構圖

重要應用說明
1. prometheus server:
retrieval: 負責抓取數據(pull metrics)
TSDB: 負責儲存數據
HTTP server: 負責提供查詢服務
3. push gateway:
4. exporter: 準備數據讓 prometheus 抓取
5. alertmanger: 處理報警
6. Grafana: 數據可視化
7. PromQL: 查詢語言
> Prometheus 之數據模型 metric

Metric是連續且帶有時間戳的測量數值. 類型是固定的, 所以在存儲的效能, 計算處理, 壓縮和檢索查找都有很棒的優化效果。
1. metric name: 描述該 metric 的含義
2. label name: 對於該 metric 的一些標記
3. timestamp: 該 metric 的時間戳
4. value: metric 值
## 安裝 Prometheus server
1. 先從官網的下載頁面,獲取 Prometheus 的最新版本和下載地址。
https://prometheus.io/download/
2. 解壓縮後,進入該目錄,
3. 配置 Prometheus: 使用以下程式碼覆蓋現有的 prometheus.yml。
```
global:
scrape_interval: 5s #拉取資料時間間隔
scrape_configs:
- job_name: "telegraf"
static_configs:
- targets: ["telegraf:9273"] #拉取數據的port
```
4. 啟動: 正常情况下 Prometheus 會啟動並在 http://localhost:9090/ 上顯示prometheus 的 webUI,幾秒鐘過後會從自身的 HTTP 指標端點收集關於自己的數據。
```
./prometheus
```
5. 嘗試使用 http://localhost:9090/graph 來查詢指標資料,可以查查詢下面的指標,表示自進程開始以來被攝入 Prometheus 本地存儲中的樣本總數。
```
ping_average_response_ms
```

6. 使用 http://localhost:9090/targets 可以查看 Prometheus 目前正在抓取資料的目標。

## Prometheus 之優缺點
* 優點:
1. 監控的精細程度可到1~5秒
2. 部署快速,減少時間成本
3. 基於數學計算模型,有很多實用的函數
4. 與grafana的結合可以產生美觀的圖形
* 缺點:
1. 數學命令行較難自學,中文資料較少
2. 若採集數據太多,會遇到性能瓶頸
## Prometheus 之指標類型

Prometheus 定義了 4 種不同的指標類型:Counter(計數器)、Gauge(儀表盤)、Histogram(直方圖)、Summary(摘要)。
1. Counter: Counter(只增不減的計數器) 類型的指標其工作方式和計數器一樣,只增不減,所以它對於存儲諸如服務的 HTTP 請求數量或使用的CPU 時間之類的信息非常有用。常見的監控指標,如http_requests_total、node_cpu_seconds_total都是Counter 類型的監控指標。
2. Gauge: 與Counter 不同,Gauge(可增可減的儀錶盤)類型的指標側重於反應系統的當前狀態,因此這類指標的樣本數據可增可減。常見指標如node_memory_MemFree_bytes(當前主機空閒的內存大小)、node_memory_MemAvailable_bytes(可用內存大小)都是 Gauge 類型的監控指標。由於Gauge 指標仍然帶有時間戳存儲,所有我們可以看到隨時間變化的值,通常可以直接把它們繪製出來,這樣就可以看到值本身而不是變化率了,通過Gauge 指標,用戶可以直接查看系統的當前狀態。
3. Histogram: 與統計較有關,比較少用到
4. Summary: 與統計較有關,比較少用到
## PromQL
PromQL是 Prometheus 監控系統內的一種查詢語言,類似於SQL的語法,PromQL 允許你以靈活的方式選擇、聚合等其他方式轉換和計算時間序列數據,該語言僅用於讀取數據。
我們可以使用PromQL 從TSDB 中讀取數據,同時可以對所選的數據執行過濾、聚合以及其他轉換操作。
### 嵌套結構
與 SQL 查詢語言(SELECT * FROM ...)不同,PromQL 是一種嵌套的函數式語言,就是我們要把需要查找的數據描述成一組嵌套的表達式,每個表達式都會評估為一個中間值,每個中間值都會被用作它上層表達式中的參數,而查詢的最外層表達式表示你可以在表格、圖形中看到的最終返回值。
### 如何查詢
1. 以 metric name 作為開頭
2. 用 label 來過濾及篩選metric,常用的 label operator 有
* = equal
* != not equal
* =~ matches regex
* !~ doesn't match regex
3. checkout more operator:(包含更多PromQL語法介紹) https://prometheus.io/docs/prometheus/latest/querying/operators/
### Range vector & instant vector
**range vector selector:**
http_requests_total{job="prometheus"}[5m] => 五分鐘內資料

**instant vector selector:**
http_requests_total{job="prometheus", group="canary"}
## Exporter 扮演的角色
若現在有一個 linux 的 server 我們想對其進行監控,Prometheus 的 exporter 會向 linux server 拉取 data 並轉換成 prometheus 認可的格式,並且將資料傳送至/metrics 路徑,廣義上所以可以向 prometheus 提供監控數據的都可以被稱作 Exporter。
以下介紹兩個常見的 exporter。
### push gateway
特殊的 exporter 專門解決 Prometheus Server 沒辦法使用 pull 來抓取資料的情況。
### Node exporter
Node Exporter 提供了許多監控指標來監控本機的硬體資訊,包括 CPU 使用率、內存使用率、磁盤使用情況、網絡流量、系統負載等等。它通過公開一個 HTTP 端點,Prometheus 可以定期抓取該端點上的指標數據。
## Alertmanager
運維人員可以實時了解當前被監控對象的運行情況,但是他們不可能時時坐在電腦邊上盯著 DashBoard,這就需要一個告警功能,當服務器或應用指標異常時發送告警,通過郵件或者短信的形式告訴運維人員及時處理。接下來就來介紹非常重要的功能——告警。
### Alert rules
使用 alert rules 來告知 Prometheus 在什麼樣的情況下需要報警
```
groups:
- name: example
rules:
- alert: PacketLoss > 0
expr: ping_percent_packet_loss != 0
for: 2m
labels:
severity: urgent
```

如果持續丟包 2 分鐘則觸發報警。

* inactive: 未觸發報警
* pending: 觸發但未達到設定的時間門檻
* firing: 正式觸發報警
### Alert manager 配置
1. 在 docker-compose.yml 中的配置
```
alertmanager:
image: prom/alertmanager:latest
restart: always
container_name: alertmanager
hostname: alertmanager
ports:
- 9093:9093
volumes:
- ./alertmanager:/etc/alertmanager
command:
- --config.file=/etc/alertmanager/alertmanager.yml
```
2. 可透過 http://localhost:9093/ 訪問 Alertmanager 的頁面

3. 使用 gmail 接收 alert, 在 alertmanager.yml 中配置 email 訊息
```
receivers:
- name: email-default
email_configs:
- to: gai910802@gmail.com
from: gai910802@gmail.com
smarthost: smtp.gmail.com:587
auth_username: gai910802@gmail.com
auth_identity: gai910802@gmail.com
auth_password: enxvroebuxcueipc
send_resolved: true
```
**auth_password 需要登入google acoount 申請 app password**
**除了透過 prometheus 設置 alertmanager 之外,也可以使用Grafana的頁面進行手動設置alert**
## Grafana Loki
### 介紹
Grafana Loki 主要是用來記錄 Log 資訊,
### Log
Log 用來捕捉系統運作過程中的事件、錯誤和警告等訊息的紀錄。當系統遇到問題時,查看 Log 可以提供有關問題的詳細資訊,並幫助進行故障排除。透過 Log 集中管理和分析,可以更好地了解系統的運作情況和健康狀態。
### 參考配置網址
https://www.cnblogs.com/a120608yby/p/17168340.html
### 如何查看 loki
使用 explore 介面,資料來源點選 loki(記得要 add datasource)

## Grafana Tempo
### 介紹
Grafana Tempo 可以用來追蹤 Trace 資料類別。
### Trace
Trace 是指在分散式系統中追蹤 request 或事務的流程和過程。
當請求在多個服務之間進行處理時,Trace 可以調用鏈路中所有經過的路徑跟請求的結構,顯示請求在每個服務中所花費的時間,並顯示可能的延遲或錯誤點。
這對於了解複雜的服務間相互作用和解決 Bottleneck 非常重要。
### trace diagram example
可以看見每個 span 的時長

### service graph
可以看見每個微服務之間的關係

## Grafana
### grafana 介紹
Grafana是一個監控儀表系統,它是由Grafana Labs 公司開源的的一個系統監測工具,它可以大大幫助我們簡化監控的複雜度,我們只需要提供需要監控的數據,它就可以幫助生成各種可視化儀表,同時它還有報警功能,可以在系統出現問題時發出通知。
### grafana 面板
面板(Panel)是Grafana 中基本可視化構建塊,每個面板都有一個特定於面板中選擇數據源的查詢編輯器,每個面板都有各種各樣的樣式和格式選項,面板可以在儀表板上拖放和重新排列,它們也可以調整大小,所以要在Grafana 上創建可視化的圖表,面板是我們必須要掌握的知識點。
### 在grafana中增加數據源
想要將資料呈現於 grafana 的 dashboard 上最重要的是設定資料來源(否則什麼東西都查不到,都會顯示No Data)。
增加 datasource 最主要有兩種方式,手動加入或是撰寫datasource.yml 檔,須注意手動加入有可能在下次開啟時就不見。
1. 點擊datasource增加數據源

2. 選取資料來源為 prometheus

3. 在 dashboard 上新增 panel

4. 配置這個 panel 的設定

* metrics: 使用 PromQL 設定 metric name
* Min step: 最小資料間隔
* Resolution: 數據解析度
* Instant: 適合獲取最新的值
### dashboard
* 可以使用不同的資料表示方式,主要使用有Graph, Stat, Gauge, Table...

* 最終成果

### Grafana Alert

在 panel 底下的設置可以選擇 alert 的條件,這邊方便測試,所以當CPU使用率超過 20% ,且時常超過一分鐘,就會發出報警。

報警的管道使用的是 discord。

實際收到時的畫面
### 參考配置網址
1. https://cloud.tencent.com/developer/article/1739655
2. https://grafana.com/docs/tempo/latest/getting-started/docker-example/
### Metrics, Logs, Traces 之關係


## Demo
### 步驟
**step 1.**
使用 spring boot 的後端 app 作為被監控的對象。
參考網站:
**step 2.**
撰寫 docker-compose.yml : 主要分為兩部分,第一部分是監控會使用到的 service,有 loki, tempo, grafana, prometheus,第二部分則是 spring boot app
**step 3.**
撰寫 grafana 和 prometheus 的配置文件
**step 4.**
使用 request.sh 此腳本檔案發送 request
參考網站:介紹 seige 使用方式 https://github.com/JoeDog/siege
**注意:** grafana 如果沒有使用 provision 來保存資料,每次 `docker-compose down` 之後就需要重新調整 dashboard 以及 datasource 等設定(非常麻煩),所以利用 provision 我們可以將過往設定好的 dashboard, datasource, alert 變成 json 或 yaml 的格式,方便之後使用,後面會更詳細說明。
### 如何使用
1. `docker-compose up -d` 可以啟用服務
2. 一開始會看見 dashboard ,no data 是因為還沒發送 request。

3. 輸入指令`bash request.sh` 則會使用該腳本發送 request,而 spring boot app 正是我們需要監控的對象。
4. 跑完指令會看見如下圖的 dashboard。

第一排左:各端口平均 requst duration
第一排中:各端口接收到的 request count
第一排右:request count 總數
第二排左:各端口每秒收到多少 request
第二排中:前 5% 耗時的 requsts 秒數
第二排右:前 1% 耗時的 requsts 秒數
第三排左:log panel,可以查看 logs 及 traces
第三排右:alert panel
### Provision 是什麼?
provision 是 grafana 提供給使用者可以儲存 dashboard,datasource,alert 等資料的方式。
將這些服務存成 json 檔或是 yaml 檔之後,存進自己的 project 檔案夾中,就可以保存這些資料,且無需再進行任何手動設定。
以下會提供將這些資料存成檔案的步驟。
#### Dashboard:
1. 點選 dashboard 左上角的 settings。

2. settings 最下方有 json model

3. 點入就可以看見該 dashboard 的 json 檔。
4. 存放位置為 etc/dashboard/dashboard.json
#### Datasource:
Datasource 沒有可以匯出檔案的地方,因此需要上網找模板,或是參考我的 etc/grafana/datasource.yml
#### Alert:
Alert 的 provision 主要分為三個檔案,以下簡單介紹其功用。
1. alert-rules.yml:負責報警的規則,像是超過多少門檻...。
2. contact-points.yml:負責報警的管道,可以多個。
3. policy.yml:因為 contact point 只用來設置我們報警管道的基本資訊,並不會成為實際的收到通知,設定 policy,可以讓我們針對不一樣的報警去涵蓋多個管道。

其中,因為 alert-rules 的配置較麻煩,所以只有 alert-rules 可以使用 grafana 的 WebUI export 出 yml 檔案(上圖中的 export ),另外兩者皆須自己找類似模板。
### 手動設定 alert

主要設定的有 alert rules, contact points, notification policies。
1. alert rules 手動設定

按下creat alert rules 之後就可以看見上圖的畫面。其中 A 可以設置主要想監控的 metric,B 和 C 則是設定 condition ,像是數值低於或高於多少就要發送報警。
2. contact points 手動設定

我使用的是 discord 作為報警通知的管道,但是可以選擇的管道非常多,像是 email, slack, pagerduty...。每個管道的設定程序都不太一樣。
3. notification policy
