Grafana新手教程-实现仪表盘创建和告警推送
前言
最近在使用Grafana的時候,發現Grafana功能比想象中要強大,除了配合Prometheus使用之外,他自身都可以做很多事情,可視化和監控平臺,還可以直接根據用戶自定義的告警規則完成告警和進行各種通知。于是在深入學習了一段時間之后,整理成此博文。溫馨提示,本文約1.3w字,幾十張示例圖片并且含描述。
一、Grafana介紹
Grafana是一個開源的數據可視化和監控平臺,它可以幫助用戶通過創建儀表盤和圖表來實時監控和分析數據。Grafana支持多種數據源,包括Prometheus、Graphite、InfluxDB、Elasticsearch等,用戶可以通過Grafana將這些數據源的數據整合在一起,進行統一的可視化展示和分析。
Grafana提供了豐富的圖表類型和插件,用戶可以根據自己的需求定制各種圖表和儀表盤,以便更直觀地了解數據的趨勢和變化。此外,Grafana還支持告警功能,用戶可以設置告警規則并及時收到通知,以便及時處理問題。
總的來說,Grafana是一個功能強大的數據可視化和監控平臺,適用于各種場景,包括IT運維、應用性能監控、工業物聯網等領域。它的開源特性也使得用戶可以根據自己的需求進行定制和擴展。
二、Grafana儀表盤創建
儀表盤創建有如下三個核心配置點:
- 創建數據源;
- 創建面板;
- 創建儀表盤;
Grafana結合Prometheus和Alertmanager在我之前寫的文章中 已經講解過了,這里就主要寫對接MySql直接實現儀表盤創建和告警推送。
Prometheus+Grafana+Alertmanager實現告警推送教程 ----- 圖文詳解
1.添加數據源
點擊data sources -> add new source->搜索mysql->填寫mysql的鏈接信息即可。
2.創建面板
選擇首頁-》儀表盤-》新建-》填寫對應信息即可。
3.創建儀表盤
我們可以在上面的創建的面板中,創建對應的儀表盤,點擊添加,即可創建。
對應的主要功能的說明在下列圖例匯總,這里就不過多描述了。
這里下列為了方便演示,統一使用如下sql數據進行。
創建的sql和示例數據語句:
-- 創建學生表
CREATE TABLE student (
id INT AUTO_INCREMENT PRIMARY KEY,
birthday_time DATETIME,
NAME VARCHAR(50),
classId INT,
source INT
);
-- 插入示例數據
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-01-01', '張三', 1, 80);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-02-02', '李四', 2, 75);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-03-03', '王五', 1, 90);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-04-04', '趙六', 3, 85);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-05-05', '小明', 2, 78);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-06-06', '小紅', 1, 92);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-07-07', '小剛', 3, 87);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-08-08', '小美', 2, 79);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-09-09', '小麗', 1, 88);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-10-10', '小強', 3, 82);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-11-11', '小雨', 2, 91);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-12-12', '小霞', 1, 76);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-01-13', '小風', 3, 83);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-02-14', '小雪', 2, 89);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-03-15', '小玲', 1, 84);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-04-16', '小華', 3, 77);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-05-17', '小龍', 2, 86);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-06-18', '小虎', 1, 93);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-07-19', '小燕', 3, 81);
INSERT INTO student (birthday_time, NAME, classId, source) VALUES ('2015-08-20', '小菲', 2, 74);
1.表單-最簡單的示例
這里為了方便演示,下列所有的我都是用code模式,也就是直接貼上sql語句。將寫好的sql貼上去之后,點擊run query,然后選擇對應的圖表即可顯示。
查詢的sql
select * from student;
顯示的圖表
2.表單-柱狀圖
這里我們也是用一個分詞簡單易懂的查詢來展示吧。
查詢的sql
SELECT
UNIX_TIMESTAMP(birthday_time) AS time_sec,
sum(source) AS VALUE,
CONCAT(classId,"班級") AS metric
FROM student
GROUP BY classId
ORDER BY birthday_time ASC
顯示的效果
點擊suggestions可以切換各種推薦圖表
3.折線圖
這里我們就統計一下學生的月份生日數量。這里我們需要用$__timeGroup和$__timeFilter函數,它們是Grafana的函數,他們的用法如下:
-
$__timeGroup函數用于將時間范圍分組成特定的時間間隔,例如每分鐘、每小時、每天等。這個函數通常用于創建時間序列圖表,幫助用戶將數據按照時間間隔進行聚合和展示。 -
$__timeFilter函數用于過濾特定的時間范圍,用戶可以使用該函數來限制數據的時間范圍,例如只顯示最近一小時的數據或者只顯示某個特定時間段的數據。
除了 $__timeGroup 和 $__timeFilter,Grafana 還提供了其他與時間相關的內置函數,例如:
-
$__timeFrom():用于指定起始時間,可以指定相對時間(例如“now-1h”表示當前時間的一小時前)或絕對時間(例如“2023-11-14T00:00:00”表示具體的時間點)。 -
$__timeTo():用于指定結束時間,同樣可以指定相對時間或絕對時間。 -
$__timeFilterGroup():用于根據時間范圍過濾數據,并且可以結合其他過濾條件使用。
查詢的Sql
SELECT
$__timeGroup(birthday_time, '1M') AS time_sec,
COUNT(id) AS '數量'
FROM student
WHERE $__timeFilter(birthday_time)
GROUP BY time_sec
對應的示例圖:
4.折線圖-多條數據
這里我們就根據統計上述的統計在加一條線,比如我這邊想看1班的情況。
查詢的sql
SELECT
$__timeGroup(birthday_time, '1M') AS time_sec,
COUNT(id) AS '數量',
SUM(classId =1 ) as '1班'
FROM student
WHERE $__timeFilter(birthday_time)
GROUP BY time_sec
示例圖:
5.折線圖-過濾篩選單條
根據上述的過程中,我們發現一點問題,上述的查詢sql是寫死的,那么我們有辦法增加一個變量去統計呢,比如上述的數據中我們想查單獨看1班的數據或2班的數據。那么這里我們就要用到Grafana的一個變量,他可以自定義變量,還可以設置變量。整體操作如下示例圖,相關注釋已寫。
這里我們還是根據上述的統計來進行改造,這里我們設置一個變量,支持按照班級統計。
對應的查詢SQL
SELECT
$__timeGroup(birthday_time, '1M') AS time_sec,
COUNT(id) AS '數量'
FROM student
WHERE $__timeFilter(birthday_time)
and classId = $class_name
GROUP BY time_sec
6.折線圖-過濾篩選多選聚合
上述示例中,我們添加了單條篩選,這里我們來添加多條篩選,以及添加自定義的常量數據來進行
篩選,常量數據配置如下示例圖:
這里在順便說下右邊的兩個小圖標的含義:
查詢的SQL如下:
SELECT
$__timeGroup(birthday_time, '1M') AS time_sec,
COUNT(id) AS '數量'
FROM student
WHERE $__timeFilter(birthday_time)
and classId in ($class_names)
GROUP BY time_sec
7.折線圖-動態多個數據分組
上述示例中,我們已經完成基本的簡單的創建,可以最基本的完成我們想要的圖表。
如果我們想要完成更復雜一點的,比如將每個Y軸指標通過頁面篩選呈現多條狀態數據,并可以根據頁面篩選進行數據圖表呈現。也就是我根據上述的多選條件,來生成對應的則線圖,選擇幾個就生成幾條。
這里的配置會稍微復雜一些。
查詢的SQL:
SELECT
$__timeGroup(birthday_time, '1M') AS time_sec,
CAST(classId AS CHAR) as '班級',
COUNT(classId) AS '數量'
FROM student
WHERE $__timeFilter(birthday_time)
and classId in ($class_names)
GROUP BY classId,time_sec
注: 如果統計的字段類型是整型,需要進行轉換,否則會不生效!
這里順便在說下樣式之類的調整,在右邊的選項中往下拉,可以對圖表進行樣式調整,相關說明都在示例圖中了。
我們要實現上述的功能,需要用到Transform功能,示例圖如下:
最終演示的效果圖圖如下:
上述的面板的json文件下載地址: https://files.cnblogs.com/files/xuwujing/測試面板-1699947693208.json?t=1699952258&download=true
8.折線圖-動態創建多個面板統計
上述的圖例中,我們完成了基本的圖例創建,這里我們就稍微玩點高級一點點圖表,根據下拉多選的數據,自動創建多個面板。
查詢sql
SELECT
$__timeGroup(birthday_time, '1M') AS time_sec,
CAST(classId AS CHAR) as '班級',
COUNT(classId) AS '數量'
FROM student
WHERE $__timeFilter(birthday_time)
and classId in ($class_names)
GROUP BY classId,time_sec
配置基于選擇的值進行重復查詢并針對變量每個成員應用到新面板.
最終效果圖如下:
三、Grafana告警規則配置
Grafana的告警核心配置:
- 告警聯絡點(通知方式,郵件、webhook等)配置;
- 告警規則(各個圖表的規則)配置;
- 告警通知策略(聯絡點和規則的關聯,告警發送頻率、靜默配置等)配置;
1.告警聯絡點配置
首先需要明確使用什么方式進行聯絡,目前使用比較多的是企微、釘釘和飛書,其中除了飛書稍微麻煩一點外,需要一個中轉服務,企微和釘釘不需要直接對接即可。
1.1 對接企微/釘釘
對接釘釘和企微畢竟簡單,下拉選擇釘釘和微信,然后填寫對應信息即可。
1.2 對接飛書
對接飛書比較麻煩一點,Grafana并不支持接入飛書,所以需要通過一個中轉服務來對Grafana的數據進行轉換成飛書需要的數據格式,然后進行告警消息推送。
這里選擇webhook,然后填寫中轉服務的地址,中轉服務只需要提供一個對應的接口地址即可,然后次http接口里面需要將接收Grafana請求的數據傳輸到飛書。
飛書對應的文檔鏈接:
https://www.feishu.cn/hc/zh-CN/articles/807992406756-webhook-觸發器
https://open.feishu.cn/document/client-docs/bot-v3/add-custom-bot
中轉服務代碼示例如下:
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.HashMap;
import java.util.Map;
/**
* @Author pancm
* @Description 飛書告警中轉服務
* @Date 2023/9/11
* @Param
* @return
**/
@RestController
@RequestMapping("alert")
@Slf4j
public class AlertController {
@Value("${feishu.webhook-url:https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxx}")
private String webHookUrl;
@Autowired
private RestTemplate restTemplate;
private String msg = "告警狀態: %s\n告警標題:%s\n告警描述:%s\n面板URL:%s\n發生時間:%s\n負責人: %s ";
@RequestMapping("/webhook/receive")
public void receive(@RequestBody String message) {
log.info("AlertController.receive 獲取的Grafana的告警數據:{}", message);
Map<String, Object> m = createMessage(getText(message));
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
log.info("AlertController.receive 發送飛書的告警內容:{}", m);
restTemplate.postForEntity(webHookUrl, new HttpEntity<>(m, headers), Void.class);
}
/**
* 構建通知報文
*
* @param content
* @return
*/
protected Map<String, Object> createMessage(String content) {
Map<String, Object> messageJson = new HashMap<>();
messageJson.put("msg_type", "text");
Map<String, Object> text = new HashMap<>();
text.put("text", content);
messageJson.put("content", text);
Long timestamp = System.currentTimeMillis() / 1000;
messageJson.put("timestamp", timestamp);
return messageJson;
}
/**
* 構建文本內容
*
* @param body
* @return
*/
private String getText(String body) {
JSONObject json = JSON.parseObject(body);
JSONObject alertObject = json.getJSONArray("alerts").getJSONObject(0);
String senMsg = String.format(msg,
getStatusMsg(json.getString("status")),
json.getString("title"),
json.getJSONObject("commonAnnotations").getString("description"),
alertObject.getString("panelURL"),
DateUtil.now(),
json.getJSONObject("commonAnnotations").getString("handler")
);
return senMsg;
}
private String getStatusMsg(String msg) {
if ("firing".equals(msg)) {
return "告警產生";
}
return "告警恢復";
}
}
2.告警規則配置
告警的規則創建有兩種方式
- 可以在告警規則面板上面進行規則創建,點擊警報-》警報規則;
- 也可以在指定監控圖表上面創建,點擊圖表-》edit-》Alert rule;
創建告警規則,目前的數據源是mysql,因此需要編寫sql語法來進行查詢,然后配置告警觸發條件,然后設置掃描時間,和在某短時間內都觸發了就進行告警,還需要配置告警的一些額外信息,告警的主題、描述等等。
直接在對應的儀表盤創建
在告警規則里面創建
3.告警策略配置
主要是將告警聯絡點和告警規則進行關聯匹配。
靜默規則配置
注:靜默時間的配置,存在時區情況,具體情況請看Grafana配置的時區。
4.一個簡單的告警通知示例
這里我們就隨便寫一個告警sql,讓他滿足觸發告警,比如主要有學生成績低于90分就進行告警
告警SQL如下
SELECT
COUNT(1) AS c
FROM student
WHERE
source < 90
配置示例圖如下:
最終在飛書群里發送的消息如下:
其他
參考資料
https://grafana.com/docs/grafana/latest/datasources/mysql/#query-editor
https://grafana.com/grafana/plugins/
https://grafana.com/docs/grafana/latest/developers
https://grafana.com/docs/grafana/latest/developers/http_api/dashboard/
https://blog.csdn.net/u014756339/article/details/107816038
https://blog.csdn.net/weixuan_/article/details/131848725
https://zhuanlan.zhihu.com/p/580145725
https://blog.csdn.net/qq_23598037/article/details/99850396
https://docs.aws.amazon.com/zh_cn/grafana/latest/userguide/v9-alerting-explore-labels-matching.html
一首很帶感的動漫鋼琴曲~
原創不易,如果感覺不錯,希望給個推薦!您的支持是我寫作的最大動力!
版權聲明:
作者:虛無境
博客園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm
個人博客出處:https://xuwujing.github.io/
總結
以上是生活随笔為你收集整理的Grafana新手教程-实现仪表盘创建和告警推送的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络之谜:记一次失败排查的故事
- 下一篇: GPTs破冰硅基文明社会