---
# System prepended metadata

title: 【101】Prometheus + Grafana + TG 架設
tags: [監控系統, tool, benjamin]

---

# 【101】Prometheus + Grafana + TG 架設
:::info
:bulb: 學習架設基礎的 Prometheus 與 Grafana 進行監控，搭配 TG 告警通知
:::
> [TOC]

---

# 一、學習資料來源:open_book:
### 1. Google
### 2. [Prometheus 官網](https://prometheus.io/)
### 3. [Youtube](https://www.youtube.com/watch?v=STVMGrYIlfg&list=PLyBW7UHmEXgylLwxdVbrBQJ-fJ_jMvh8h&index=2)

---

# 二、事前準備:clipboard:
### 1. VM (本篇使用 Ubuntu 22.04 LTS)
### 2. 一顆充滿學習熱誠的心
### 3. 看過 Prometheus 生態架構圖（下圖）
![Architecture of Prometheus and some of its ecosystem components](https://hackmd.io/_uploads/BkFYMZfPyx.png)
:::success
:bulb: 本篇將介紹 Prometheus 監控主機、網站、資料庫，並搭配 Alertmanager 作為告警系統
:::

---

# 三、Prometheus:fire:
![Prometheus icon](https://hackmd.io/_uploads/SyESoLGPye.png =85%x)
### 1. Prometheus 是什麼？
  - **功能概述：**
    Prometheus 是一個開源的監控和警報系統，它被設計用來收集、儲存和查詢來自各種系統的監控數據，並支持高效的警報和查詢功能。
    
  - **特點：**
    - 時間序列數據庫：
    Prometheus 儲存數據時以時間序列的形式存儲，這意味著每個數據點都與時間戳相關聯，並且可以隨著時間推移查看變化。
    
    - 自動拉取數據：
    Prometheus 通過定期拉取目標（如應用、伺服器、服務等）的指標數據，而不是由目標主動推送數據。
    
    - 強大的查詢語言（PromQL）：
    Prometheus 提供了強大的查詢語言，可以進行複雜的數據篩選、聚合、過濾等操作，並且可以根據這些查詢生成視覺化圖表。
    
    - 支持多維度數據：
    數據可以有多個標籤（labels），這些標籤使得你能夠根據不同的維度來過濾和查詢數據。
    
    - 警報機制：
    Prometheus 支持基於查詢結果觸發警報。這些警報可以通過不同的方式（如電子郵件、Slack 等）發送通知。
    
    - 自動發現與靈活的配置：
    Prometheus 支持自動發現機制，可以自動發現和配置監控目標。也支持基於配置文件進行手動配置。
    
    - 高效儲存和擴展性：
    Prometheus 儲存數據高效且支持大規模數據的擴展，適合高頻次數據收集與查詢。
    
    - 視覺化：
    Prometheus 可以與如 Grafana 等工具集成，實現數據的視覺化展示。
  </br>

---

### 2. 實作範例
  :::info
  :::spoiler **安裝 Prometheus**
  </br>

  **1. 更新 apt 套件**
  ```
  sudo apt update
  ```
  ```
  sudo apt upgrade -y
  ```
  </br>

  **2. 下載 Prometheus 安裝檔**
  - **可自行選擇版本 https://prometheus.io/download/**
    ```
    wget https://github.com/prometheus/prometheus/releases/download/v3.1.0-rc.0/prometheus-3.1.0-rc.0.linux-amd64.tar.gz
    ```

  - **解壓縮**
    ```
    tar -xvzf prometheus-3.1.0-rc.0.linux-amd64.tar.gz
    ```

  - **刪除縮檔**
    ```
    sudo rm prometheus-3.1.0-rc.0.linux-amd64.tar.gz
    ```
  </br>
  :::
  
  :::info
  :::spoiler **配置 Prometheus**
  **1. 移至 Prometheus 目錄（directory）**
  ```
  cd prometheus-3.10.0.linux-amd64
  ```
  </br>
  
  **2. 將 Prometheus binaries 移至 /usr/local/bin/ 讓所有使用者都能使用**
  ```
  sudo mv prometheus /usr/local/bin/
  ```
  ```
  sudo mv promtool /usr/local/bin/
  ```
  </br>
    
  **3. 建立必要的 目錄 用來儲存 Prometheus 配置及資料**
  ```
  sudo mkdir /etc/prometheus
  ```
  ```
  sudo mkdir /var/lib/prometheus
  ```
  ```
  sudo mkdir /var/lib/prometheus/data
  ```
  </br>
    
  **4. 將 預設配置檔案 複製到 /etc/prometheus**
  ```
  sudo cp prometheus.yml /etc/prometheus/
  ```
  </br>
    
  **5. 建立 Prometheus.service 檔案（將 Prometheus 加入系統 Service）**
  - **建立 prometheus.service 在 /etc/systemd/system/**
  ```
  sudo vim /etc/systemd/system/prometheus.service
  ```
  - **新增以下內容（可自行修改）**
  ```
  [Unit]
  Description=Prometheus
  After=network.target     # 確保 Prometheus 在網路服務啟動後再啟動
  
  [Service]
  ExecStart=/usr/local/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data
  User=root
  Group=root
  Restart=always     # Prometheus 停止時（包含正常停止），Systemd 會自動重新啟動服務
  [Install]
  WantedBy=multi-user.target
  ```
  </br>
    
  **6. 重啟系統 及 啟動 Prometheus**
  - **重新啟動 systemd 套用更改**
  ```
   sudo systemctl daemon-reload
  ```
  - **設定在每次開機時自動啟動**
  ```
  sudo systemctl enable prometheus
  ```
  - **啟動 prometheus**
  ```
  sudo systemctl start prometheus 
  ```
  </br>
      
  **7. 訪問 Prometheus**
  - **在  ~/.bashrc 新增修改環境參數**
  ```
  sudo vim ~/.bashrc
  ```
  - **修改配置**
  ```
  export HOST=127.0.0.1 → export HOST=0.0.0.0
  ```
  - **使環境參數生效**
  ```
  source ~/.bashrc 
  ```
  - **打開瀏覽器搜尋（記得 SG 要允許 port 9090）**
  ```
  http://your_public_ip_address:9090
  ```
  </br>
  :::
  
  :::info
  :::spoiler **配置 Prometheus.yml**
  </br>
  
  **1. 移至 Prometheus 目錄（directory）**
  ```
  cd /etc/prometheus/prometheus.yml
  ```
  </br>

  **2. 修改 Prometheus.yml (可以先將預設的備份)**
  ```
  sudo vim peometheus.yml
  ```
  - **新增以下內容（可自行修改）**
  ```
  global:
   scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.

  scrape_configs:
  - job_name: "prometheus"                  # 設定 工作名稱
    static_configs:
     - targets: ['localhost:9090']          # 設定 Prometheus 自身作為抓取目標

  - job_name: "node_exporter"
    static_configs:
     - targets: ['XXX.XXX.XXX.XXX:9100']    # 設定 目標 IP 的主機 作為抓取目標

  - job_name: "mysqld_exporter"
    static_configs:
     - targets: ['XXX.XXX.XXX.XXX:9104']    # 設定 目標 IP 的主機 作為抓取目標

  - job_name: "blackbox_exporter"
    metrics_path: /probe
    params:
     module: [http_2xx_example]             # 使用 http_2xx_example 模組
    static_configs:
     - targets:
       - https://syzstudio.com/             # 探測目標網站URL（可自行替換）
       - https://screenwriterleo.com/
       - https://aesthetictrend.com/lander/
       - https://www.circlezine.com/
       - https://www.way2creative.com/
       - https://publish.flipermag.com/

    relabel_configs:
      - source_labels: [__address__]
        target_label: __param_target
      - source_labels: [__param_target]
        target_label: instance
      - target_label: __address__
        replacement: localhost:9115         # blackbox exporter 主機位置:port
        
  - job_name: "domain"
   metrics_path: /metrics
   static_configs:
    - targets: ['localhost:9222']

   relabel_configs:
    - source_labels: [__address__]
      target_label: __param_target
    - target_label: __address__
      replacement: localhost:9222  # domain_exporter 的服務位址
    - source_labels: [__param_target]
      target_label: instance
  ```
  </br>
    
  **3. 重啟 Prometheus**
  - **重啟 prometheus 以套用新的 yml 設置**
  ```
  sudo systemctl restart prometheus
  ```
  - **檢查 Prometheus 運行狀況**
  ```
  sudo systemctl status prometheus
  ```
  </br>
  :::

---

# 四、Exporter:telescope:
![Node exporter & blackbox](https://hackmd.io/_uploads/BJChyPGwkg.jpg)
### 1. Exporter 是什麼？
  - **功能概述：**
    Prometheus Exporter 是一個可以讓 Prometheus 監控不同類型的系統、服務或應用程式的工具或程序。它的主要功能是 將被監控系統的指標（metrics）以 Prometheus 能夠理解的格式暴露出來，以便 Prometheus 可以定期拉取這些數據進行監控。
    
  - **特點：**
    - 數據暴露端點：
    Exporter 通常會在特定的 HTTP 端點上提供指標數據，這些數據以 Prometheus 能夠理解的格式暴露。通常端點為 /metrics，例如：http://your_host:port/metrics。
    
    - 自動收集指標：
    Exporter 負責從被監控的系統或應用中收集各種性能指標，例如 CPU 使用率、記憶體消耗、磁碟空間、網絡流量等。這些指標會自動收集並暴露，而無需手動干預。

    - 標準化的指標格式：
    所有 Exporter 都會將收集的指標數據轉換成一個統一的文本格式，使得 Prometheus 能夠解析這些數據。這樣，Prometheus 能夠不依賴於具體的服務或應用，通過統一的接口拉取數據。

    - 靈活的配置：
    Exporter 通常有靈活的配置選項，用戶可以根據自己的需求調整暴露的指標範圍和頻率。

    - 支持多種應用或服務：
      - Node Exporter：監控操作系統層面的指標（如 CPU、內存、磁碟等）。
      - MySQL Exporter：監控 MySQL 資料庫的運行狀態。
      - PostgreSQL Exporter：監控 PostgreSQL 資料庫的指標。
      - MongoDB Exporter：監控 MongoDB 資料庫。
      - 詳見官網（https://prometheus.io/docs/instrumenting/exporters/）

    - 支持多種指標：
      - 計數器（Counter）：不會減少的累積計數，例如請求數量。
      - 儀表（Gauge）：可能會增加或減少的數值，例如當前內存使用量。
      - 直方圖（Histogram）：用於收集分佈數據的指標，例如響應時間。
      - 摘要（Summary）：與直方圖類似，用於收集一組數據的統計信息。

    - 高擴展性：
    由於 Exporter 的工作是將指標暴露成一個簡單的 HTTP 接口，這使得它們非常容易擴展，無論是監控一台主機，還是監控整個集群，都能通過安裝不同的 Exporter 來輕鬆擴展。

    - 開源和可自定義：
    大多數 Exporter 都是開源的，用戶可以根據自己的需求修改或創建自定義的 Exporter。

    - 錯誤處理和日誌：
    儘管大部分 Exporter 都相對簡單，但它們通常會處理錯誤情況，並生成相關的日志，幫助運維人員了解指標收集過程中的問題。
  </br>
  
---

### 2. 實作範例
  - **對預監控的項目安裝對應的 exporter （https://prometheus.io/download/）**
  - **範例使用三種方式執行，有興趣可以自行研究或是來找我討論~**

  :::danger
  :warning: 注意 node exporter、mysqld exporter 要安裝在監控目標的主機
  :::
  :::info
  :::spoiler **範例一、Node_exporter**
  </br>

  **1. 下載 node_exporter 安裝檔**
  - **可自行選擇版本 https://prometheus.io/download**
    ```
    wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
    ```
  - **解壓縮**
    ```
    tar -xvzf node_exporter-1.8.2.linux-amd64.tar.gz
    ```
  - **刪除縮檔**
    ```
    sudo rm node_exporter-1.8.2.linux-amd64.tar.gz
    ```
  </br>
  
  **2. 移至 node_exporter 目錄（directory）**
  ```
  cd node_exporter-1.8.2.linux-amd64
  ```
  </br>
    
  **3. 執行 node_exporter（記得 SG 要允許 port 9100）**
  - **在背景執行 node_exporter**
    ```
    ./node_exporter &
    ```
  - **開起預設以外的監控項目（以 TCP Stat 為例）**
    ```
    ./node_exporter --collector.tcpstat &
    ```
  </br>
  :::
  
  :::info
  :::spoiler **範例二、Blackbox_exporter**
![How_blackbox_works](https://hackmd.io/_uploads/rkSeYjEDkl.png)
**1. 下載 blackbox_exporter 安裝檔**
  - **可自行選擇版本 https://prometheus.io/download**
    ```
    wget  https://github.com/prometheus/blackbox_exporter/releases/download/v0.25.0/blackbox_exporter-0.25.0.linux-amd64.tar.gz
    ```
  - **解壓縮**
    ```
    tar -xvzf blackbox_exporter-0.25.0.linux-amd64.tar.gz
    ```
  - **刪除縮檔**
    ```
    sudo rm blackbox_exporter-0.25.0.linux-amd64.tar.gz
    ```
  </br>

  **2. 建立 blackbox.service 檔案（將 blackbox_exporter 加入系統 Service）**
  - **建立 blackbox.service 在 /etc/systemd/system/**
    ```
    sudo vim /etc/systemd/system/blackbox.service
    ```
  - **新增以下內容（可自行修改，或參考[官方配置檔](https://github.com/prometheus/blackbox_exporter/blob/master/example.yml)）**
    ```
    [Unit]
    Description=Prometheus Blackbox Exporter
    Documentation=https://prometheus.io/docs/introduction/overview/
    After=network-online.target   # 確保 Blackbox Exporter 在網路服務啟動並完全連線且可用後再啟動

    [Service]
    User=ubuntu
    Restart=on-failure     # blackbox 崩潰或停止時，Systemd 會自動重新啟動服務
    ExecStart=/path/to/blackbox_exporter-0.25.0.linux-amd64/blackbox_exporter --config.file=/path/to/blackbox_exporter-0.25.0.linux-amd64/monitor_website.yml

    [Install]
    WantedBy=multi-user.target
    ```
  </br>
  
  **3. 重啟系統 及 啟動 blackbox**
  - **重新啟動 systemd 套用更改**
    ```
    sudo systemctl daemon-reload
    ```
  - **設定在每次開機時自動啟動**
    ```
    sudo systemctl enable blackbox
    ```
  - **啟動 blackbox**
    ```
    sudo systemctl start blackbox 
    ```
  </br>
    
  **4. 配置 blackbox.yml**
  - **移動至 blackbox_exporter-0.25.0.linux-amd64 目錄**
    ```
    cd /path/to/blackbox_exporter-0.25.0.linux-amd64
    ```
  - **新增 blackbox.yml (可以先將預設的備份)**
    ```
    sudo vim blackbox.yml
    ```
  - **新增以下內容（可自行修改）**
    ```
    modules:
      http_2xx_example:
        prober: http
        timeout: 5s
        http:
          valid_http_versions: ["HTTP/1.1", "HTTP/2", "HTTP/2.0"]
          valid_status_codes: [200, 301, 302]
          method: GET
          follow_redirects: true
          fail_if_ssl: false
          fail_if_not_ssl: false
          tls_config:
            insecure_skip_verify: false
          preferred_ip_protocol: "ip4"
          ip_protocol_fallback: false
    ```
  </br>

  **4. 重啟 blackbox**
  - **重啟 blackbox 以套用新的 yml 設置**
  ```
  sudo systemctl restart blackbox 
  ```
  - **檢查 Blackbox 運行狀況**
  ```
  sudo systemctl status blackbox
  ```
  </br>
     
  **5. 查看 blackbox metrix**
  - **打開瀏覽器搜尋（記得 SG 要允許 port 9100）**
  ```
  http://your_public_ip_address:9100
  ```
  </br>
  :::
  
  :::info
  :::spoiler **範例三、MySQLd_exporter**
  </br>
  
  **1. 下載 node_exporter 安裝檔**
  - **可自行選擇版本 https://prometheus.io/download**
    ```
    wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.16.0/mysqld_exporter-0.16.0.linux-amd64.tar.gz
    ```
  - **解壓縮**
    ```
    tar -xvzf mysqld_exporter-0.16.0.linux-amd64.tar.gz
    ```
  - **刪除縮檔**
    ```
    sudo rm mysqld_exporter-0.16.0.linux-amd64.tar.gz
    ```
  </br>
  
  **2. 移至 mysqld_exporter-0.16.0.linux-amd64 目錄（directory）**
    ```
    cd mysqld_exporter-0.16.0.linux-amd64
    ```
  </br>
    
  **3. 將 mysqld_exporter 移至 /usr/local/bin/ 下**
    ```
    sudo mv mysqld_exporter /usr/local/bin/
    ```
  </br>
      
  **4. 配置 .my.cnf 檔案**
  - **新增 .my.cnf 檔案**
    ```
    sudo vim /usr/local/bin/.my.cnf
    ```
  - **新增以下內容（可自行修改）**
    ```
    [client]
    user=your_mysql_user
    password=your_password
    host=localhost
    port=3306
    ```
  </br>
      
  **5. 建立 myslqd_exporter.service 檔案（將 myslqd_exporter 加入系統 Service）**
  - **建立 mysqld_exporter.service 在 /etc/systemd/system/**
    ```
    sudo vim /etc/systemd/system/mysqld_exporter.service
    ```
  - **新增以下內容（可自行修改）**
    ```
    [Unit]
    Description=Prometheus MySQL Exporter
    After=network.target

    [Service]
    User=root
    ExecStart=/usr/local/bin/mysqld_exporter --config.my-cnf=/usr/local/bin/.my.cnf
    Restart=on-failure     # mysqld 崩潰或停止時，Systemd 會自動重新啟動服務

    [Install]
    WantedBy=multi-user.target
    ```
  </br>
 
  **6. 重啟系統 及 啟動 mysqld_exporter**
  - **重新啟動 systemd 套用更改**
    ```
    sudo systemctl daemon-reload
    ```
  - **設定在每次開機時自動啟動**
    ```
    sudo systemctl enable mysqld_exporter
    ```
  - **啟動 mysqld_exporter**
    ```
    sudo systemctl start mysqld_exporter
    ```
  - **檢查 mysqld_exporter 運行狀況**
    ```
    sudo systemctl status mysqld_exporter
    ```
  </br>
     
  **7. 查看 mysqld_exporter metrix**
  - **打開瀏覽器搜尋（記得 SG 要允許 port 9104）**
  ```
  http://your_public_ip_address:9104
  ```
  </br>
  :::
  
  :::info
  :::spoiler **範例四、Domain_exporter**
  </br>

  **1. 下載 domain_exporter 安裝檔**
  - **可自行選擇版本 https://github.com/caarlos0/domain_exporter/releases**
    ```
    wget https://github.com/caarlos0/domain_exporter/releases/download/v1.24.1/domain_exporter_1.24.1_linux_amd64.tar.gz
    ```
  - **解壓縮**
    ```
    tar -xvzf domain_exporter_1.24.1_linux_amd64.tar.gz
    ```
  - **刪除縮檔**
    ```
    sudo rm domain_exporter_1.24.1_linux_amd64.tar.gz
    ```
  </br>
  
  **2. 移至 domain_exporter 目錄（directory）**
    ```
    cd domain_exporter_1.24.1_linux_amd64
    ```
  </br>
    
  **3. 將 domain_exporter 移至 /usr/local/bin/ 下**
    ```
    sudo mv domain_exporter /usr/local/bin/
    ```
  </br>
      
  **4. 配置 domains.yaml 檔案** 
  - **新增 domains.yaml 檔案**
    ```
    sudo vim /usr/local/bin/domains.yaml
    ```
  - **新增以下內容（可自行修改）**
    ```
    domains:
      - syzstudio.com
      - screenwriterleo.com
      - circlezine.com
      - way2creative.com
      - flipermag.com
    ```
  </br>
  
  **5. 建立 domain_exporter.service 檔案（將 domain_exporter 加入系統 Service）**
  - **建立 domain_exporter.service 在 /etc/systemd/system/**
    ```
    sudo vim /etc/systemd/system/domain_exporter.service
    ```
  - **新增以下內容（可自行修改）**
    ```
    [Unit]
    Description=Domain Exporter
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    User=benjamin
    Restart=on-failure
    RestartSec=5
    ExecStart=/usr/local/bin/domain_exporter --config=/usr/local/bin/domains.yaml
    
    [Install]
    WantedBy=multi-user.target
    ```
  </br>
 
  **6. 重啟系統 及 啟動 domain_exporter**
  - **重新啟動 systemd 套用更改**
    ```
    sudo systemctl daemon-reload
    ```
  - **設定在每次開機時自動啟動**
    ```
    sudo systemctl enable domain_exporter
    ```
  - **啟動 domain_exporter**
    ```
    sudo systemctl start domain_exporter
    ```
  - **檢查 domain_exporter 運行狀況**
    ```
    sudo systemctl status domain_exporter
    ```
  </br>
  
  **7. 查看 domain_exporter metrix**
  - **打開瀏覽器搜尋（記得 SG 要允許 port 9222）**
  ```
  http://your_public_ip_address:9222
  ```
  </br>
  :::
  
---

# 五、Grafana:bar_chart:
![Grafana_logo.svg](https://hackmd.io/_uploads/BJ4VxvfPJl.png =50%x)
### 1. Grafana 是什麼？
  - **功能概述：**
  Grafana 是一個開源的數據可視化和監控平台，主要用來展示時間序列數據。它允許用戶通過創建交互式和動態的儀表板來查看和分析來自各種資料來源（例如 Prometheus、Elasticsearch、InfluxDB、MySQL 等）的數據。

  - **特點：**
    - 支持多資料來源：
    Grafana 能夠支持多種數據源，讓用戶可以將不同來源的資料集成在一個儀表板中。例如，Prometheus、InfluxDB、MySQL、PostgreSQL、Elasticsearch 等。這使得你能夠從各種不同的系統（如監控系統、資料庫、雲端服務）拉取數據，進行統一的展示和分析。

    - 強大的資料可視化功能：
        - 圖表：支持折線圖、柱狀圖、餅圖等，可以展示時間序列數據。
        - 儀表板：即時顯示多種指標，例如 CPU 使用率、內存消耗等。
        - 熱圖：顯示資料的密度分布，適合視覺化大規模資料。
        - 表格：顯示數據的原始值，對於需要詳細數據的場景非常有用。
        - 地圖：展示地理位置數據，如位置基於的監控。

    - 實時數據監控
    Grafana 允許顯示即時數據變化並進行自動更新。當與像 Prometheus 這樣的時間序列數據庫配合使用時，數據會隨著時間的推移動態變化，並且 Grafana 會自動刷新顯示的圖表和數據，讓用戶能隨時了解系統狀況。

    - 警報系統
    Grafana 允許根據設置的條件創建警報規則。例如，當某些指標（如 CPU 使用率或記憶體消耗）超過預設閾值時，Grafana 可以發送警報通知給相關人員。通知方式包括電子郵件、Slack、PagerDuty 等，從而幫助快速處理異常情況。

    - 自定義儀表板
    用戶可以創建完全自定義的儀表板，並根據需要調整每個面板的大小、布局和顯示方式。這使得每個儀表板可以精確符合用戶的需求，例如顯示特定服務的監控數據或針對某個業務指標進行分析。

    - 開源與插件支持
        - 資料來源插件：可以接入更多的資料來源。
        - 面板插件：提供更多的可視化方式，滿足不同的展示需求。
        - 應用插件：可集成各種應用服務，擴展功能。

    - 用戶管理與權限控制
    Grafana 支持多用戶協作，並可以為不同用戶設置訪問權限。管理員可以控制哪些用戶可以查看、修改儀表板，還能夠設置只讀或完全控制的權限。這對於團隊協作和保護敏感數據非常重要。

    - 集成與 API 支持
    Grafana 提供 RESTful API，支持與其他工具進行集成。例如，可以用於自動化儀表板配置、數據提取等操作。這使得 Grafana 能夠與 CI/CD 流程、DevOps 工具鏈以及其他內部系統進行無縫集成。

    - 集群和高可用性
    Grafana 支持在分佈式或高可用性環境中運行，適用於企業級部署。通過設置多個 Grafana 節點，可以實現負載均衡和故障恢復，確保服務的穩定運行。
  </br>

---

### 2. 實作範例
  :::info
  :::spoiler **安裝 Grafana**
  </br>
  
  **1. 更新 apt 套件**
  ```
  sudo apt update
  ```
  ```
  sudo apt upgrade -y
  ```
  </br>

  **2. 下載 Prometheus 安裝檔**
  - **安裝 software-properties-common 套件**
    ```
    sudo apt install software-properties-common  -y
    ```
  - **新增 Grafana 源到 repository（以便可以從這個源安裝或更新 Grafana）**
    ```
    sudo add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
    ```
  - **新增 Grafana GPG Key**
    ```
    sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9F0C8E9F
    ```
  - **若失敗，改手動下載並添加 Grafana GPG Key 至 /etc/apt/trusted.gpg.d/ 目錄中**
    ```
    wget -q -O - https://packages.grafana.com/gpg.key | sudo tee /etc/apt/trusted.gpg.d/grafana.asc
    ```
  - **更新 apt 套件**
    ```
    sudo apt update
    ```
  - **安裝 Grafana**
    ```
    sudo apt install grafana -y
    ```
  - **設定在每次開機時自動啟動**
    ```
    sudo systemctl enable grafana-server
    ```
  - **啟動 Grafana**
    ```
    sudo systemctl start grafana-server
    ```
  </br>
  :::
  
  :::info
  :::spoiler **Grafana 串接 Prometheus** 
  **1. 訪問 Grafana**
  - **打開瀏覽器搜尋（記得 SG 要允許 port 3000）**
  ```
  http://your_public_ip_address:3000
  ```
  </br>
  
  **2. 登入 Grafana**

  - **預設使用者名稱：admin 預設密碼：admin** 
  ![Grafana Login](https://hackmd.io/_uploads/B19V0WGPkg.png)

  - **跳出更新密碼，先按 Skip**
  ![Change password](https://hackmd.io/_uploads/SJehR-zDye.png)

  - **新增 Data Source**
  ![Add your fisrt data source](https://hackmd.io/_uploads/B1xyyfzwJe.png)

  - **選擇 Prometheus**
  ![Select data source](https://hackmd.io/_uploads/BJmX1ffDyx.png)

  - **輸入要連線的 URL（範例使用本機）**
  ![Url for connect](https://hackmd.io/_uploads/SyB41Mfwkx.png)

  - **剩下維持預設即可，下拉按 Save & test**
  ![Save & test](https://hackmd.io/_uploads/r1NB1MGwJg.png)

  - **新增 Dashboard**
  ![Add new dashboard](https://hackmd.io/_uploads/SJBUyGMwJg.png)

  - **尋找或匯入 Dashboard 並點選 Import:**
  ![Import dashboard](https://hackmd.io/_uploads/HJKwkzMPyl.png)

       - **若要串接 node_exporter 推薦使用 Dashboard id: [1860](https://grafana.com/grafana/dashboards/1860-node-exporter-full/)、[16098](https://grafana.com/grafana/dashboards/16098-node-exporter-dashboard-20240520-job/)**
       - **若要串接 blackbox_exporter 推薦使用 Dashboard id: [7587](https://grafana.com/grafana/dashboards/7587-prometheus-blackbox-exporter/)、[13659](https://grafana.com/grafana/dashboards/13659-blackbox-exporter-http-prober/)**
       - **若要串接 MySQLd_exporter 推薦使用 Dashboard id: [7362](https://grafana.com/grafana/dashboards/7362-mysql-overview/)、[14031](https://grafana.com/grafana/dashboards/14031-mysql-dashboard/)**

  - **選擇 Prometheus data source 並點選 Import**
  ![Import](https://hackmd.io/_uploads/Byf01GGDyx.png)

  - **配置完成**
  ![Complete](https://hackmd.io/_uploads/r1HggfGv1l.png)

  </br>
  :::
  
---

# 六、Alertmanager:bell:
![Alertmanager](https://hackmd.io/_uploads/SkDWMDzDkg.jpg =40%x)
### 1. Alertmanager 是什麼？
  - **功能概述：**
  Prometheus Alertmanager 是 Prometheus 監控系統中的一個重要元件，主要負責處理 Prometheus 發出的警報訊息。當 Prometheus 監控的指標達到設定的警報條件時，它會把這些警報傳送給 Alertmanager，然後由 Alertmanager 根據設定進行處理，比如通知相關人員或系統。
  
  - **特點：**
    - 警報分組與抑制（Silencing）：
    Alertmanager 會把相同或類似的警報合併，減少通知頻率，同時也可以設定在特定時間內忽略某些警報，避免不必要的干擾。
    
    - 警報路由與通知發送：
    根據警報的標籤，Alertmanager 會將警報發送到不同的通知目標（例如電子郵件、Slack、PagerDuty 等），確保適當的人員或系統能及時收到警報。
    
    - 重試與降噪：
    Alertmanager 支援重試機制，當通知失敗時會重新嘗試發送，同時也會避免過於頻繁的通知，減少無用的警報。
  </br>
  
---

### 2. 實作範例
  :::info
  :::spoiler **安裝 Alertmanager**
  </br>
  
  **1. 下載 Alertmanager 安裝檔**
  - **可自行選擇版本 https://prometheus.io/download/**
    ```
    wget https://github.com/prometheus/alertmanager/releases/download/v0.28.0-rc.0/alertmanager-0.28.0-rc.0.linux-amd64.tar.gz
    ```

  - **解壓縮**
    ```
    tar -xvzf alertmanager-0.28.0-rc.0.linux-amd64.tar.gz
    ```

  - **刪除縮檔**
    ```
    sudo rm alertmanager-0.28.0-rc.0.linux-amd64.tar.gz
    ```
  </br>
  :::
  
  :::info
  :::spoiler **配置 Alertmanager**
  **1. 移至 Alertmanager 目錄（directory）**
  ```
  cd alertmanager-0.28.0-rc.0.linux-amd64
  ```
  </br>
  
  **2. 將 Alertmanager binaries 移至 /usr/local/bin/ 讓所有使用者都能使用**
  ```
  sudo mv alertmanager /usr/local/bin/
  ```
  ```
  sudo mv amtool /usr/local/bin/
  ```
  </br>
    
  **3. 建立必要的 目錄 用來儲存 Alertmanager 配置及資料**
  ```
  sudo mkdir /etc/alertmanager
  ```
  ```
  sudo mkdir /var/lib/alertmanager/data
  ```
  </br>
    
  **4. 將 預設配置檔案 複製到 /etc/alertmanager**
  ```
  sudo cp alertmanager.yml /etc/alertmanager/
  ```
  </br>
    
  **5. 建立 alertmanager.service 檔案（將 Alertmanager 加入系統 Service）**
  - **建立 alertmanager.service 在 /etc/systemd/system/**
  ```
  sudo vim /etc/systemd/system/alertmanager.service
  ```
  - **新增以下內容（可自行修改）**
  ```
  [Unit]
  Description=alertmanager
  After=network-online.target          # 確保 Alertmanager 在網路服務啟動後再啟動

  [Service]
  ExecStart=/usr/local/bin/alertmanager --config.file=/etc/alertmanager/alertmanager.yml --storage.path=/var/lib/alertmanager/data --web.listen-address=:9093 --data.retention=120h
  Restart=on-failure                   # alertmanager 崩潰或停止時，Systemd 會自動重新啟動服務
  LimitNOFILE=65536                    # 增加文件描述符數量限制
  TimeoutStartSec=30s                  # 設定啟動超時時間
  TimeoutStopSec=30s                   # 設定停止超時時間

  [Install]
  WantedBy=multi-user.target
  ```
  </br>
    
  **6. 重啟系統 及 啟動 Alertmanager**
  - **重新啟動 systemd 套用更改**
  ```
   sudo systemctl daemon-reload
  ```
  - **設定在每次開機時自動啟動**
  ```
  sudo systemctl enable alertmanager
  ```
  - **啟動 alertmanager**
  ```
  sudo systemctl start alertmanager 
  ```
  </br>
  
  **7. 訪問 Alertmanager**
  - **打開瀏覽器搜尋（記得 SG 要允許 port 9093）**
  ```
  http://your_public_ip_address:9093
  ```
  </br>
  :::
  
  :::info
  :::spoiler **Alertmanager 串接 Prometheus**
  **1. 先至 /etc/prometheus 目錄（directory）**
  ```
  cd /etc/prometheus
  ```
  </br>
  
  **2. 新增一個 alert.yml**
  ```
  sudo vim alert.yml
  ```
  </br>
  
  **3. 新增以下內容（可自行修改）**
  ```
  groups:
  - name: Prometheus Alert
    rules:
      # Alert for any instance that is unreachable for >5 minutes.
      - alert: Instance Down
        expr: probe_success == 0
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Instance {{ $labels.instance }} down"
          description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
  ```
  </br>

  **4. 編輯 prometheus.yml**
  ```
  sudo vim prometheus.yml
  ```
  </br>
    
  **5. 新增以下內容到 prometheus.yml**
  ```
  global:
   evaluation_interval: 15s     #在 global 新增這句

  alerting:
    alertmanagers:
      - static_configs:
          - targets: ['localhost:9093']

  rule_files:
    - alert.yml

  #在 global 和 scrape_configs 中間新增上面兩欄(alerting, rule_files) 

  scrape_configs:
  ...
  ```
  </br>
  
  **6. 重啟 prometheus**
  ```
  sudo systemctl restart prometheus
  ```
  </br>
  
  **7. 打開瀏覽器登入 Grafana**
  ```
  http://your_public_ip_address:3000
  預設使用者名稱：admin
  預設密碼：admin 
  ```
  </br>
  
  **8. 點選左側欄位 Alerting 裡的 Alert rules**
  ![Alert_rules](https://hackmd.io/_uploads/rkjP8bLD1e.png)
  <font color="#000000">若有看到有一項 Data source-managed 代表配置成功！</font>
  </br>
  :::
  
  
  :::info
  :::spoiler **申請 Telegram Bot PAI Token**
  **1.  打開 Telegram 搜尋 BotFather**
  ![BotFather](https://hackmd.io/_uploads/r1kIMXUPyx.png)
  :warning:<font color="#ff0000">注意記得找有藍勾勾的</font>
  </br>

  **2.  申請 Bot**
  ![start](https://hackmd.io/_uploads/BkiPUX8wkl.png)
  <font color="#000000">1. 輸入 /start</font>
  <font color="#000000">機器人會回應你能做的事情</font>
  </br>
  
  ![create_bot](https://hackmd.io/_uploads/ByKTuXIPJe.png)
  <font color="#000000">2. 輸入 /newbot</font>
  <font color="#000000">3. 輸入 Bot 想取的名稱(隨意，之後能修改)</font>
  <font color="#000000">4. 輸入 Uesrname(必須以 bot 結尾，之後<font color="#ff0000">不能</font>修改)</font>
  <font color="#000000">5. 你的 Bot 聊天室連結</font>
  <font color="#000000">6. 你的 Bot API Token(記得保管好)</font>
  </br>
  
  **3.  查詢 Chat id**
  ![find_chat_id_01](https://hackmd.io/_uploads/HJ7u5XLwJx.png)
  <font color="#000000">1. 先到 Bot 聊天室輸入 /start</font>
  <font color="#000000">2. 接著傳送隨意一則訊息。</font>
  
  ![find_chat_id_02](https://hackmd.io/_uploads/SJRK3XUvJg.png)
  <font color="#000000">3. 打開瀏覽器輸入下面網址就會看到你的 Chat id:</font>
  <font color="#0000FF">https://api.telegram.org/bot{Your-Bot-Token}/getUpdates</font>
  <font color="#ff0000">將 {Your-Bot-Token} 替換成你的 Bot Token</font>
      
  <font color="#000000">範例如下:</font>
  <font color="#000000">https://api.telegram.org/bot1985044907:AAEdySrbzTc8tVdBjfymlfyaBUJGeu7r-v4/getUpdates</font>  
  </br>
  :::
  
  :::info
  :::spoiler **配置 Telegram 告警通知**
  **1. 點選左側欄位 Alerting 裡的 Contact points**
  ![Contact_points_01](https://hackmd.io/_uploads/BJ91Y-Uwkl.png)
  <font color="#000000">  點選 Create contact point。</font>
  </br>

  **2. 配置告警資料**
  ![Contact_points_02](https://hackmd.io/_uploads/HkFfs-8vye.png)
  <font color="#000000">1. 依照項目填入資料。(其它預設即可)</font>

  <font color="#000000">2. 都填完後，可以先按 Test 測試是否成功。</font>
  
  <font color="#000000">3. 接著按 Save contact point。</font>
  </br>
  ![Test_message](https://hackmd.io/_uploads/Sk1W6GLvye.png)
  <font color="#000000">測試成功就會在 Telegram 收到訊息。</font>
  </br>

  **3. 告警通知**
  ![Alert_Firing](https://hackmd.io/_uploads/SyC0AzUP1e.png)
  <font color="#000000">若 Instance 掛了就會收到通知。</font>
  </br>
  ![Alert_Resolved](https://hackmd.io/_uploads/rkCHymUwye.png)
  <font color="#000000">若 Instance 恢復了也會收到通知。</font>
  </br>
  :::
  
  :::info
  :::spoiler **更改 Telegram 告警通知模板**
  **1. 移至 etc/alertmanager 目錄（directory）**
  ```
  cd /etc/alertmanager
  ```
  </br>
  
  **2. 新增一個 alert.yml**
  ```
  sudo vim alert.yml
  ```
  </br>
  
  **3. 新增以下內容至 alert.yml 並儲存（可自行修改）**
  ```
  global:
    resolve_timeout: 1m

  templates:
    - '/etc/alertmanager/templates/alertmanager.tmpl'

  route:
    group_by: ['alertname', 'instance']
    group_wait: 30s
    group_interval: 5m
    repeat_interval: 1h
    receiver: 'telegram'

  receivers:
    - name: 'telegram'
      telegram_configs:
      - api_url: 'https://api.telegram.org'
        bot_token: 'Your_Bot_API_Token'        # change to yours
        chat_id: Your_Chat_ID                  # change to yours
        disable_notifications: false
        send_resolved: true
        message: |
            {{ if gt (len .Alerts.Firing) 0 }}
            🚨 Alerts Firing:
            {{ range .Alerts.Firing }}
            {{ template "alert" . }}
            {{ end }}
            {{ end }}
            {{ if gt (len .Alerts.Resolved) 0 }}
            🔧 Alerts Resolved:
            {{ range .Alerts.Resolved }}
            {{ template "alert" . }}
            {{ end }}
            {{ end }}

  inhibit_rules:
    - source_match:
        severity: 'critical'
      target_match:
        severity: 'warning'
      equal: ['alertname', 'dev', 'instance']

  ```
  </br>
  
  **4. 新增一個叫 templates 的目錄**
  ```
  sudo mkdir templates
  ```
  </br>

  **5. 新增一個 alertmanager.tmpl**
  ```
  sudo vim alertmanager.tmpl
  ```
  </br>

  **6. 新增以下內容（可自行修改）**
  ```
  {{ define "alert" }}
  Alert: {{ .Labels.alertname }}
  instance: {{ .Labels.instance }}
  job: {{ .Labels.job }}
  Severity: {{ .Labels.severity }}
  Description: {{ .Annotations.description }}
  {{ end }}
  ```
  </br>
  
  **7. 重啟 alertmanager**
  ```
  sudo systemctl restart alertmanager
  ```
  </br>
  
  **8. 重啟 prometheus**
  ```
  sudo systemctl restart prometheus
  ```
  </br>
  
  **9. 告警通知**
  ![image](https://hackmd.io/_uploads/Bk3X4chPkx.png)
  <font color="#000000">若 Instance 掛了就會收到通知。</font>
  </br>
  ![image](https://hackmd.io/_uploads/BkFHzF3vJg.png)
  <font color="#000000">若 Instance 恢復了也會收到通知。</font>
  </br>
  :::
  
---

# 七、錯誤排查:bug:
### 常見錯誤
  - **Prometheus 正常運行但抓不到資料**
  
      1. 確認 VM 的 SG 或是 防火牆（通常是 UFW 或 iptables）設置是否正確，要開放對應的 Port 給 Prometheus。
      ```
      sudo ufw status
      sudo iptables -L
      ```
      2. 確認 prometheus.yml 有作對應的更改（目標 IP 或是 域名之類的）。
      ```
      sudo vim /etc/prometheus/prometheus.yml
      ```  
      </br>
      
   - **無法訪問 Your_IP:port**
  
      1. 確認 VM 的 SG 或是 防火牆（通常是 UFW 或 iptables）設置是否正確，要開放對應的 Port。
      ```
      sudo ufw status
      sudo iptables -L
      ```
      2. 確認該服務已正確啟動。
      ```
      sudo systemctl status Your_Service_Name.service
      ```
      3. 確認 Your_Service_Name.yml 有作對應的更改。
      ```
      sudo vim /etc/Your_Service_Name/Your_Service_Name.yml
      ```     
      4. 確認 /etc/systemd/system/Your_Service_Name.service 路徑配置是正確的。 
      ```
      sudo vim /etc/systemd/system/Your_Service_Name.service
      ```    
      </br>
      
  - **無法使用服務**
      1. 重啟服務。
      ```
      sudo systemctl restart Your_Service_Name.service
      ```
      2. 查看服務運行狀況。
      ```
      sudo systemctl status Your_Service_Name.service
      ```
      3. 查看服務日誌。
      ```      
      sudo journalctl -u Your_Service_Name.service
      ```
    </br>
        
  - **Telegram 測試告警失敗**
      1. Token 打錯。
      2. Chat ID 打錯。
      3. YAML 設置錯誤，可以使用 amtool 檢查。
      ```    
      sudo amtool check-config /etc/alertmanager/alert.yml
      ```
  </br>
  
---
