大家一般都是用Grafana自定义Dashboard来监控Prometheus数据的,作者这次尝试用ECharts来绘制Prometheus数据图表,一方面可以减少依赖,另一方面可以将监控界面灵活的集成进应用系统。至于如何在被监测机器上安装NodeExporter以及如何部署Prometheus作者就不描述了,园子里有很多文章介绍。
一、数据查询及转换
Prometheus提供了Http Api来执行promql查询,但需要将返回的数据格式转换为ECharts的格式,好在EChars的xAxis.type可以设置为’time’类型,与Prometheus返回的格式接近。作者写了个简单的服务来执行查询及转换数据,详见以下代码:
public class MetricService
{
private static readonly HttpClient http = new HttpClient()
{
//请修改指向Prometheus地址
BaseAddress = new Uri("http://10.211.55.2:9090/api/v1/"),
Timeout = TimeSpan.FromSeconds(2)
};
public async Task<object> GetCpuUsages(string node, DateTime start, DateTime end)
{
var promql = $"100-irate(node_cpu{
{instance='{node}:9100',mode='idle'}}[5m])*100";
return await QueryRange(promql, start, end, 20, 2);
}
public async Task<object> GetMemUsages(string node, DateTime start, DateTime end)
{
var promql = $"(1-(node_memory_MemAvailable{
{instance='{node}:9100'}}/(node_memory_MemTotal{
{instance='{node}:9100'}})))*100";
return await QueryRange(promql, start, end, 20, 2);
}
public async Task<object> GetNetTraffic(string node, DateTime start, DateTime end)
{
var downql = $"irate(node_network_receive_bytes{
{instance='{node}:9100',device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}}[5m])";
var ls = await QueryRange(downql, start, end, 15/*4*/, 0);
var upql = $"irate(node_network_transmit_bytes{
{instance='{node}:9100',device!~'tap.*|veth.*|br.*|docker.*|virbr*|lo*'}}[5m])";
ls.Add(await QueryRange(upql, start, end, 15/*4*/, 0));
return ls;
}
public async Task<object> GetDiskIO(string node, DateTime start, DateTime end)
{
var readql = $"irate(node_disk_bytes_read{
{instance='{node}:9100'}}[1m])";
var ls = await QueryRange(readql, start, end, 15/*10*/, 0);
var writeql = $"irate(node_disk_bytes_written{
{instance='{node}:9100'}}[1m])";
ls.Add(await QueryRange(writeql, start, end, 15/*10*/, 0));
return ls;
}
#region ====Parse PromQL====
private static async Task<List