# Telegraf+Prometheus+Grafana學習筆記
> [TOC]
---
# 一、學習資料來源
### 1. [Hiskio線上課程](https://hiskio.com/)
### 2. [Github教材資源](https://github.com/udemy-course/telegraf-prometheus-grafana)(共24個Branch)
### 3. [延伸學習-正規表達式(Regular Expression, Regex)](https://hackmd.io/@aaronlife/regular-expression)
---
# 二、事前準備
### 1. [安裝 Docker Engine](https://docs.docker.com/engine/install/)
### 2. [安裝 Docker Compose](https://docs.docker.com/compose/install/)
---
# 三、Telegraf
### 1. Telegraf是什麼

Telegraf使用GO語言撰寫,支援Linux和Windows作業系統。主要用於收集系統和服務的數據資料並進行數據處理、聚合,後續可以針對數據設置告警、可視化的操作。大致架構可以分為4個套件:

- **Input Plugins數據收集:**
收集系統、資料庫、網路、服務、第三方套件的數據。
- **Processor Plugins數據處理:**
轉換、處理、過濾等資料處理。
- **Aggregator Plugins數據聚合:**
針對數據的特徵,進行數據聚合。
- **Output Plugins數據輸出:**
撰寫Metric數據,可以發送至儲存空間、其他採集數據的應用程式,如Prometheus。
---
### 2. Telegraf官方文檔資源
- [官方文檔連結](https://docs.influxdata.com/telegraf/v1/)
- [官方Github資源](https://github.com/influxdata/telegraf)
---
### 3. 實作範例
:::info
:::spoiler **啟動Telegraf容器**
</br>
**1. 創建Telegraf目錄**
```
mkdir -p telegraf && cd telegraf
```
```
mkdir -p app && cd app
```
</br>
**2. Telegraf容器啟動文件**
- **docker-compose.yml文件(運行Telegraf容器)**
```
version: "3.0"
services:
telegraf:
image: telegraf:latest
restart: always
container_name: telegraf
hostname: telegraf
ports:
- 9273:9273
volumes:
- /本地config路徑/telegraf.conf:/etc/telegraf/telegraf.conf
#本地telegraf.config文件路徑:容器的telegraf.conf文件路徑
command: telegraf --config /etc/telegraf/telegraf.conf
```
- **telegraf.conf文件(設定Telegraf要監控的數據)**
```
[agent]
# https://docs.influxdata.com/telegraf/v1/configuration/
interval = "30s"
## 每次執行input套件的時間
flush_interval = "10s"
## 每次執行output套件的時間
[[inputs.ping]]
# https://github.com/influxdata/telegraf/tree/master/plugins/inputs/ping/README.md
urls = ["google.com"]
method = "exec"
## 執行ping的方式
count = 3
## 執行ping的次數
[[inputs.cpu]]
# https://github.com/influxdata/telegraf/blob/master/plugins/inputs/cpu/README.md
## 本地主機的CPU
percpu = true
totalcpu = true
collect_cpu_time = false
report_active = false
[[inputs.mem]]
# https://github.com/influxdata/telegraf/blob/master/plugins/inputs/mem/README.md
## 本地主機的MEM
[[outputs.prometheus_client]]
# https://github.com/influxdata/telegraf/tree/master/plugins/outputs/prometheus_client/README.md
listen = ":9273"
## 監聽的Port號
metric_version = 2
```
- **.env文件(避免與其它專案容器搞混)**
```
COMPOSE_PROJECT_NAME=telegraf
```
</br>
**3. 運行Telegraf容器**
```
docker compose up -d
```
```
docker compose ps
```

</br>
**4. 訪問瀏覽器查看監控數據**
```
主機IP:9273/metrics
domain:9273/metrics
```

可以看到標籤都有『host="telegraf"』

</br>
:::
:::info
:::spoiler **為全局的監控數據添加靜態標籤**
</br>
**1. 編輯telegraf.conf文件**
```
[global_tags]
environment = "testing"
```

</br>
**2. 重新啟動Telegraf容器**
```
docker compose restart
```
</br>
**3. 重新整理瀏覽器查看監控數據**

</br>
:::
:::info
:::spoiler **針對輸入套件添加靜態標籤**
</br>
**1. 針對Ping套件添加標籤**
```
[inputs.ping.tags]
version = 'PingV2'
```

</br>
**2. 針對CPU套件添加標籤**
```
[inputs.cpu.tags]
type = 'CPU'
```

</br>
**3. 針對MEM套件添加標籤**
```
[inputs.mem.tags]
type = 'MEM'
```

</br>
**4. 重新啟動Telegraf容器**
```
docker compose restart
```
</br>
**5. 重新整理瀏覽器查看監控數據**



</br>
:::
:::info
:::spoiler **為Ping輸入套件添加動態標籤**
</br>
**1. 使用Regex處理套件為Ping輸入套件添加**
```
[[processors.regex]]
# https://github.com/influxdata/telegraf/blob/master/plugins/processors/regex/README.md
namepass = ["ping"]
## 處理包含ping字串的數據資料
[[processors.regex.tags]]
## 選擇regex的tags套件
key = "url"
## 要處理url的標籤內容
pattern = "^([^.]+).*$"
## 表達式,表達要抓取的內容(domain不抓取頂級域名)
replacement = "${1}"
## 如何替換pattern抓取的內容
result_key = "service_name"
## 新的標籤,同時保留url標籤
```

</br>
**2. 重新啟動Telegraf容器**
```
docker compose restart
```
</br>
**3. 重新整理瀏覽器查看監控數據**

</br>
:::
:::info
:::spoiler **透過telegraf.d以組織的方式管理監控數據**
</br>
**1. 建立telegraf.d資料夾**
```
mkdir -p telegraf.d && cd telegraf.d
```
</br>
**2. 添加組織的監控config**
```
vim 組織名稱.conf
```
</br>
**3. 編輯該組織的監控config內容**
本文新增amazon.config、google.config的Ping套件為範例,如下:
- amazon.config:
```
[[inputs.ping]]
# https://github.com/influxdata/telegraf/tree/master/plugins/inputs/ping/README.md
urls = ["amazon.com", "amazon.jp", "amazon.cn", "amazon.uk"]
method = "exec"
## 執行ping的方式
count = 3
## 執行ping的次數
[[processors.regex]]
namepass= ["ping"]
[[processors.regex.tags]]
key = "url"
pattern = "^([^.]+).*$"
replacement = "${1}"
result_key = "service_name"
[inputs.ping.tags]
version = 'PING-Amazon'
```
- google.config:
```
[[inputs.ping]]
# https://github.com/influxdata/telegraf/tree/master/plugins/inputs/ping/README.md
urls = ["www.google.com"], ["www.google.co.jp"], ["www.google.cn"], ["www.google.de"]
method = "exec"
## 執行ping的方式
count = 3
## 執行ping的次數
[[processors.regex]]
namepass= ["ping"]
[[processors.regex.tags]]
key = "url"
pattern = "^([^.]+).*$"
replacement = "${1}"
result_key = "service_name"
[inputs.ping.tags]
version = 'PING-Google'
```
備註:可以刪除原本在telegraf.conf中的群組PING套件內容。
</br>
**4. 修改docker-compose.yml內容**
```
vim docker-compose.yml
```
為Telegraf容器添加telegraf.d掛載目錄,docker-compose.yml內容修正如下:
```
volumes:
- "本地telegraf.d目錄路徑/:/etc/telegraf/telegraf.d/
#本地telegraf.d目錄路徑:容器telegraf.d目錄路徑
command: telegraf --config /etc/telegraf/telegraf.conf --config-directory "容器telegraf.d目錄路徑"
```

</br>
**5. 暫停telegraf docker容器**
```
docker compose stop
```
</br>
**6. 刪除telegraf docker容器**
因為有修改docker-compose.yml內容,因此必須重新啟動一個docker容器。
```
docker compose rm
```
</br>
**7. 重新運行Telegraf容器**
```
docker compose up -d
```

</br>
:::
---
# 四、Prometheus 
### 1. Prometheus是什麼
- **功能概述:**
監控+告警的開源應用程式工具集。
- **特點:**
- 基於時間序列的數據儲存。
- 提供並使用 `PromQL` 語言來查詢數據。
- 與其他監控工具不同,是在固定時間從目標對象拉取監控數據 Metric。
---
### 2. Prometheus架構元件、流程圖

- **Prometheus Server:**
從指定的 `Jobs/Exporter` 抓取數據並將數據按時間序列排序。
- **Client Libraries:**
提供不同程式語言的客戶端套件。
- **Push Gateway:**
若Prometheus Server無法從 `Jobs/Exporter` 抓取某些數據,則可以透過撰寫腳本/程式碼的方式將數據推送到 Push Gateway(使 Push Gateway 擔任 Exporter 的角色)。
- **Exporters:**
負責向外部提供抓取Metrics的通道。
- **Alertmanager:**
根據告警規則,處理告警通知。
---
### 3. 數據指標(Metrics)類型
|**名稱**|**說明**|**範例場景**|
| -- | -- | -- |
|**Counters**|單調遞增計數器,適合累計的事件。|HTTP請求總數、消息處理總數|
|**Gauges**|可以增減,反映實時的數值。|記憶體使用空間、磁碟可用空間|
|**Histogram**|1.追蹤事件並定義事件的不同統計分組(chunk_range_bucket)。</br></br>2.最終提供SUM加總平均、Count次數。|回應時間chunk1:小於10=5次</br>chunk2:小於20=1次</br>chunk3:小於30=2次</br></br>統計:</br>SUM=平均16.25</br>COUNT=8次|
|**Summary**|與Histogram分組統計相似,但以PR數值(quantiles)來分組數據。|quantile1(0.5=PR50):10</br>quantile2(0.9=PR90):20</br>quantile3(0.99=PR99):30</br></br>統計:</br>SUM=平均16.25</br>COUNT=8次|
---
### 4. Prometheus官方文檔資源
- [官方文檔連結](https://prometheus.io/docs/introduction/overview/)
- [官方Github資源](https://github.com/prometheus)
---
### 5. 實作範例:運行Prometheus應用程式
:::info
:::spoiler **啟動Prometheus容器**
</br>
**1. 抓取Prometheus docker image**
```
docker pull prom/prometheus
```
</br>
**2. 建立Prometheus目錄**
```
mkdir -p prometheus && cd prometheus
```
```
mkdir -p prometheus && mkdir -p telegraf
```
```
cp /root/telegraf/app/telegraf.conf /root/prometheus/telegraf/telegraf.conf
```
```
cp /root/telegraf/app/docker-compose.yml /root/prometheus/docker-compose.yml
```
```
cp -r /root/telegraf/app/telegraf.d/ /root/prometheus/telegraf/telegraf.d/
```
```
cd prometheus && vim prometheus.yml
```
- 最終目錄、文件會如下圖所示:
```mermaid
graph TD;
Prometheus --> docker-compose.yml;
Prometheus --> prometheus;
Prometheus --> telegraf;
prometheus --> prometheus.yml;
telegraf --> telegraf.conf;
telegraf --> telegraf.d;
```
</br>
**3. 撰寫 Prometheus.yml 文件**
```
global:
scrape_interval: 15s
#全局設定每15秒去抓取一次metrics。
scrape_configs:
- job_name: "telegraf"
static_configs:
- targets: ["telegraf:9273"]
# 指定 docker-compose.yml 裡面的telegraf容器(hostname)。
```

- 其它 Prometheus configuration 內容請參考 [Prometheus官方文檔](https://prometheus.io/docs/prometheus/latest/configuration/configuration/)
</br>
**4. 修改 docker-compose.yml 文件**
```
version: "3.0"
services:
telegraf:
image: telegraf:latest
restart: always
container_name: telegraf
hostname: telegraf
ports:
- 9273:9273
volumes:
- 本地telegraf.conf路徑:/etc/telegraf/telegraf.conf
- 本地telegraf.d路徑:/etc/telegraf/telegraf.d/
#本地telegraf.config文件路徑:容器的telegraf.conf文件路徑
command: telegraf --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d
prometheus:
image: prom/prometheus:latest
restart: always
container_name: prometheus
hostname: prometheus
ports:
- 9090:9090
volumes:
- 本地prometheus.yml路徑:/etc/prometheus/prometheus.yml
command: --config.file=/etc/prometheus/prometheus.yml
```

</br>
**5. 停止並刪除舊有的Telegraf容器**
```
docker compose stop
```
```
docker compose rm
```
```
y
```

</br>
**6. 用docker-compose啟動Telegraf+Prometheus容器**
```
docker compose up -d
```

</br>
**7. 確認Telegraf+Prometheus容器運行狀態**
```
docker compose ps
```

```
主機IP:9273/metrics
```

```
主機IP:9090
```




</br>
:::
---
### 6. 使用PromQL查看Metric數據
- **說明**
使用Prometheus Web UI搜尋Metric數據,例如:`ping_average_response_ms`,搜尋後若希望針對Metric數據中Label標籤值或Metric值進行數據篩選,篩選一共可以分為2種類型:
| |**Instant Vector Selector**|**Range Vector Selector**|
|--|--|--|
|**Metric數據範圍**|單個時間點上的數據值|一段時間內的數據值集合|
|**返回數據類型**|單個值(標量數據)|值的集合(向量數據)|
|**聚合函數應用**|不需要時間範圍|需要時間範圍(如:avg_over_time)|
|**語法範例**|`metric_name{label_selector}`|`metric_name{label_selector}[time_range]`|
|**適用場景**|僅查看數據內容|數據分析、趨勢分析|
</br>
- **標籤篩選(Label Selector)說明**
用於篩選Metric數據中的標籤,大致格式如下:
{`label_name標籤名稱` `運算符` `label_value標籤值`}`比較運算符` `Metric_value值`
{`label_name標籤名稱` `運算符` `Regex正規表達式label_value標籤值`}`比較運算符` `Metric_value值`
- **運算符**
`=`:等於
`!=`:不等於
`=~`:符合正規表達式
`!~`:不符合正規表達式
- **比較運算符**
`>`:大於
`<`:小於
`>=`:大於等於
`<=`:小於等於
`==`:等於
`!=`:不等於
- **什麼是正規表達式**
[正規表達式(Regular Expression, Regex)](https://hackmd.io/lrXV3iXPT52ggzHZ87Zr_w?both#3-%E5%BB%B6%E4%BC%B8%E5%AD%B8%E7%BF%92%EF%BC%8D%E6%AD%A3%E8%A6%8F%E8%A1%A8%E9%81%94%E5%BC%8F%EF%BC%88Regular-Expression-Regex%EF%BC%89)
</br>
- **時間範圍(time_range)說明**
指定時間範圍,支持的時間格式如下:
`S`:秒
`m`:分鐘
`h`:小時
`d`:天
`w`:周
`y`:年
</br>
:::info
:::spoiler **Instant vector selector(單點時間)**
</br>
**1. Metric數據**
```
metric_name
```

</br>
**2. Metric數據+指定Label標籤值**
- 篩選條件:`version`等於`PING-HIGHERCLOUD`
```
metric_name{version="version值"}
```

- 篩選條件:`version`不等於`PING-HIGHERCLOUD`
```
metric_name{version!="version值"}
```

- 篩選條件:`version`等於`PING-Boyu`+`service_name`等於`circlecreative`
```
metric_name{version="version值", service_name="service_name值"}
```

</br>
**3. Metric數據+正規表達式篩選Label標籤值**
- 篩選條件:`url`以`.com`結尾的二級域名
```
metric_name{url=~"^[^.]+\\.com$"}
```

- 篩選條件:`url`以`.com`結尾的二級域名+`service_name`以`s`作為開頭
```
metric_name{url=~"^[^.]+\\.com$", service_name=~"^s.*"}
```

- 篩選條件:`url`以`.com`結尾的二級域名+`service_name`以`s`作為開頭+Metric值大於30
```
metric_name{url=~"^[^.]+\\.com$", service_name=~"^s.*"}>30
```

</br>
:::
:::info
:::spoiler **Range vector selector(時間範圍)**
</br>
篩選條件:`url`以`.com`結尾的二級域名
```
metric名稱{Label運算符+值(正規表達式可選)}<比較運算符>metric值
```

</br>
:::
---
### 7. 配置Prometheus Alerting and Rules