推荐Go语言开源项目:Excelize ,获取阿里云ECS实例监控数据导出到自定义Excel表格(二)

简介: 推荐Go语言开源项目:Excelize ,获取阿里云ECS实例监控数据导出到自定义Excel表格(二)

需求


用阿里云云监控服务:

阿里云云监控没有grafana服务端,生成不了PDF,再加上Prometheus不能生成exl表格数据,阿里云云监控企业版太贵,一个报表0.14元。我们可以自己调取阿里云的api接口,获取ECS主机cpu负载、内存使用率等信息,生成报表定时发送指定邮箱。


有人会说了,为啥不自己搭建一个Prometheus服务端,然后把所有主机全部添加到自己的服务器上。这个想法好,但是如果“二次开发”阿里云 云监控平台,我们公司就不用单独购买服务器,毕竟人家做的也不错,除了有些功能收费以外。其实自己搭建Prometheus服务端我们已经实现了,目前可以做到监控数据生成PDF格式定时发送,动态添加主机(自动增删被监控主机,还未整理,主要是懒🌚),只不过想节省资源,也能为公司每个月省下好几百。


目前进度


1、(完成) 已获取所有主机指定时间段内的各种指标(目前该项目以cpu使用率为例)

2、(进行中) 已获取所有主机主机名和ip信息

3、(未开始) 把接口一获取到的instanceid和接口二获得的instanceid对比,如果相等,把接口二获取的主机名和ip写到该表行的“主机名”与“IP”列

4、(未开始)获取整个周期时间段数据的百分比,例如7天内,在10-12点的cpu使用率


效果一:获取单台主机资源信息


获取一个主机的7天内的cpu使用率信息,生成报表

1675242552355.jpg


阿里云API


阿里云 云监控服务API地址:https://next.api.aliyun.com/home

本篇使用的API网址:https://next.api.aliyun.com/api/Cms/2019-01-01/DescribeMetricTop?params={}


代码示例


// This file is auto-generated, don't edit it. Thanks.
package main
import (
  "encoding/json"
  "fmt"
  "github.com/xuri/excelize/v2"
  "os"
  cms20190101  "github.com/alibabacloud-go/cms-20190101/v2/client"
  openapi  "github.com/alibabacloud-go/darabonba-openapi/client"
  "github.com/alibabacloud-go/tea/tea"
  "strings"
)
type List struct {
  Order      int     `json:"order"`
  Timestamp  int     `json:"timestamp"`
  UserId     string  `json:"userId"`
  InstanceId string  `json:"instanceId"`
  Minimum    float32 `json:"Minimum"`
  Maximum    float32 `json:"Maximum"`
  Average    float32 `json:"Average"`
  Count      float32 `json:"_count"`
}
/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return Client
 * @throws Exception
 */
func CreateClient (accessKeyId *string, accessKeySecret *string) (_result *cms20190101.Client, _err error) {
  config := &openapi.Config{
    // 您的AccessKey ID
    AccessKeyId: accessKeyId,
    // 您的AccessKey Secret
    AccessKeySecret: accessKeySecret,
  }
  // 访问的域名
  config.Endpoint = tea.String("metrics.cn-hangzhou.aliyuncs.com")
  _result = &cms20190101.Client{}
  _result, _err = cms20190101.NewClient(config)
  return _result, _err
}
func _main (args []*string) (_err error) {
  client, _err := CreateClient(tea.String("LTxxxxxxxxx5dUc"), tea.String("G1WxxxxxxxxxxxxxxxxxxiF6"))
  if _err != nil {
    return _err
  }
  describeMetricListRequest := &cms20190101.DescribeMetricListRequest{
    StartTime: tea.String("1636905600000"),
    EndTime: tea.String("1637424000000"),
    MetricName: tea.String("cpu_total"),
    Namespace: tea.String("acs_ecs_dashboard"),
    Dimensions: tea.String("{\"instanceId\":\"i-8vxxxxxxxxgh\"}"),
    Period: tea.String("604800"),
  }
  // 复制代码运行请自行打印 API 的返回值
  M, _err := client.DescribeMetricList(describeMetricListRequest)
  N := *M.Body.Datapoints
  fmt.Println(N)
  N1 := strings.TrimLeft(N, "[")
  N2 := strings.TrimRight(N1, "]")
  //fmt.Printf("N类型:%T,N值:%v\n",N2,N2)
  fmt.Println(N2)
  var list List
  err1 := json.Unmarshal([]byte(N2), &list)
  if err1 != nil {
    fmt.Printf("序列化转化失败,%v",err1)
  }else {
    fmt.Println("序列化转化成功")
  }
  fmt.Println(list)
  f := excelize.NewFile()
  // 创建一个工作表
  index := f.NewSheet("主机列表")
  err2 := f.SetColWidth("主机列表", "A", "H", 23)
  if err2 != nil {
    fmt.Printf("表格创建失败,%v",err2)
  }else {
    fmt.Println("表格创建成功")
  }
  // 设置单元格的值
  f.SetCellValue("主机列表", "A1", "实例ID号")
  f.SetCellValue("主机列表", "A2", list.InstanceId)
  f.SetCellValue("主机列表","B1","7天CPU最小使用率")
  f.SetCellValue("主机列表","B2",list.Minimum)
  f.SetCellValue("主机列表","C1","7天CPU最大使用率")
  f.SetCellValue("主机列表","C2",list.Maximum)
  f.SetCellValue("主机列表","D1","7天CPU平均使用率")
  f.SetCellValue("主机列表","D2",list.Average)
  // 设置工作簿的默认工作表
  f.SetActiveSheet(index)
  // 根据指定路径保存文件
  if err := f.SaveAs("Book1.xlsx"); err != nil {
    fmt.Println(err)
  }
  if _err != nil {
    return _err
  }
  return _err
}
func main() {
  err := _main(tea.StringSlice(os.Args[1:]))
  if err != nil {
    panic(err)
  }
}


效果二:获取所有主机资源信息


1675242589646.jpg


阿里云API


https://next.api.aliyun.com/api/Cms/2019-01-01/DescribeMetricList?params={}

https://next.api.aliyun.com/api/Cms/2019-01-01/DescribeMetricLast?params={}


说实话,不知道这两个有什么区别。都可以用,而且两个获得数据不准,乱七八糟!先讲究用吧


代码实例


获取所有主机监控数据

// This file is auto-generated, don't edit it. Thanks.
package main
import (
  "encoding/json"
  "fmt"
  cms20190101 "github.com/alibabacloud-go/cms-20190101/v2/client"
  openapi "github.com/alibabacloud-go/darabonba-openapi/client"
  "github.com/alibabacloud-go/tea/tea"
  "github.com/xuri/excelize/v2"
  _ "github.com/xuri/excelize/v2"
  "os"
  "strconv"
)
type List struct {
  Order      int     `json:"order"`
  Timestamp  int     `json:"timestamp"`
  UserId     string  `json:"userId"`
  InstanceId string  `json:"instanceId"`
  Minimum    float32 `json:"Minimum"`
  Maximum    float32 `json:"Maximum"`
  Average    float32 `json:"Average"`
  Count      float32 `json:"_count"`
}
/**
 * 使用AK&SK初始化账号Client
 * @param accessKeyId
 * @param accessKeySecret
 * @return Client
 * @throws Exception
 */
func CreateClient(accessKeyId *string, accessKeySecret *string) (_result *cms20190101.Client, _err error) {
  config := &openapi.Config{
    // 您的AccessKey ID
    AccessKeyId: accessKeyId,
    // 您的AccessKey Secret
    AccessKeySecret: accessKeySecret,
  }
  // 访问的域名
  config.Endpoint = tea.String("metrics.cn-hangzhou.aliyuncs.com")
  _result = &cms20190101.Client{}
  _result, _err = cms20190101.NewClient(config)
  return _result, _err
}
func _main(args []*string) (_err error) {
  client, _err := CreateClient(tea.String("LTAIxxxxxxxxxxx"), tea.String("G1WBNxxxxxxxxxxxxxxxxxxxxxx"))
  if _err != nil {
    return _err
  }
  describeMetricListRequest := &cms20190101.DescribeMetricListRequest{
    StartTime:  tea.String("1636905600000"),
    EndTime:    tea.String("1637424000000"),
    MetricName: tea.String("cpu_total"),
    Namespace:  tea.String("acs_ecs_dashboard"),
    Dimensions: tea.String(""),
    Period:     tea.String("604800"),
  }
  // 复制代码运行请自行打印 API 的返回值
  M, _err := client.DescribeMetricList(describeMetricListRequest)
  N := *M.Body.Datapoints
  //fmt.Println("N值\n", N)
  var slice []map[string]interface{}
  //注意:反序列化map,不需要make,因为make操作被封装到Unmarshal函数
  err := json.Unmarshal([]byte(N), &slice)
  if err != nil {
    fmt.Printf("unmarshal err=%v\n", err)
  }
  f := excelize.NewFile()
  index := f.NewSheet("主机列表")
  f.SetCellValue("主机列表", "A1", "实例ID号")
  f.SetCellValue("主机列表", "B1", "7天内的CPU最大使用率")
  f.SetCellValue("主机列表", "C1", "7天内的CPU最小使用率")
  f.SetCellValue("主机列表", "D1", "7天内的CPU平均使用率")
  f.SetColWidth("主机列表", "A", "H", 23)
/*  fmt.Printf("反序列化后:%v\n", slice)
  fmt.Println("第一个切片是:", slice[0])
  fmt.Println("第二个切片是:", slice[1])
  //获取第一个主机信息
  Arr, err := json.Marshal(slice[0])
  if err != nil {
    fmt.Println(err)
    return
  }
  var List1 List
  err = json.Unmarshal(Arr, &List1)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(List1)
  f.SetCellValue("主机列表", "A2", List1.InstanceId)
  f.SetCellValue("主机列表", "B2", List1.Maximum)
  f.SetCellValue("主机列表", "C2", List1.Minimum)
  f.SetCellValue("主机列表", "D2", List1.Average)
    //获取第二个主机信息
  Arr1, err := json.Marshal(slice[1])
  if err != nil {
    fmt.Println(err)
    return
  }
  var List2 List
  err = json.Unmarshal(Arr1, &List2)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(List2)
  f.SetCellValue("主机列表", "A3", List2.InstanceId)
  f.SetCellValue("主机列表", "B3", List2.Maximum)
  f.SetCellValue("主机列表", "C3", List2.Minimum)
  f.SetCellValue("主机列表", "D3", List2.Average)
*/
//把上面单个获取主机方式改成for循环
  for  i :=2 ;i < len(slice); i++ {
    A1 :="A"
    //strconv.Itoa函数 可以将int类型转string类型
    A2 := fmt.Sprint(A1 + strconv.Itoa(i))
    B1 :="B"
    B2 := fmt.Sprint(B1 + strconv.Itoa(i))
    C1 :="C"
    C2 := fmt.Sprint(C1 + strconv.Itoa(i))
    D1 :="D"
    D2 := fmt.Sprint(D1 + strconv.Itoa(i))
    Arr, err := json.Marshal(slice[i-2])
    if err != nil {
      fmt.Println(err)
      return
    }
    var List1 List
    err = json.Unmarshal(Arr, &List1)
    if err != nil {
      fmt.Println(err)
      return
    }
    //fmt.Println(List1)
    f.SetCellValue("主机列表", A2, List1.InstanceId)
    f.SetCellValue("主机列表", B2, List1.Maximum)
    f.SetCellValue("主机列表", C2, List1.Minimum)
    f.SetCellValue("主机列表", D2, List1.Average)
  }
  // 设置工作簿的默认工作表
  f.SetActiveSheet(index)
  // 根据指定路径保存文件
  if err := f.SaveAs("Book1.xlsx"); err != nil {
    fmt.Println(err)
  }
  if _err != nil {
    return _err
  }
  return _err
}
func main() {
  err := _main(tea.StringSlice(os.Args[1:]))
  if err != nil {
    panic(err)
  }
}
相关实践学习
通义万相文本绘图与人像美化
本解决方案展示了如何利用自研的通义万相AIGC技术在Web服务中实现先进的图像生成。
7天玩转云服务器
云服务器ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,可降低 IT 成本,提升运维效率。本课程手把手带你了解ECS、掌握基本操作、动手实操快照管理、镜像管理等。了解产品详情:&nbsp;https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
存储 弹性计算 网络协议
阿里云服务器ECS自定义购买流程:亲测图文全解析
本文详细图解阿里云ECS自定义购买全流程,涵盖付费模式、地域选择、实例规格、镜像、存储、网络、安全组及登录设置等核心配置,助您轻松掌握专业级云服务器搭建方法。
266 0
|
10月前
|
网络协议 关系型数据库 应用服务中间件
如何迁移网站数据到新的服务器
迁移网站数据到新服务器是一个系统化的过程,需谨慎操作以避免数据丢失或服务中断。小编为您整理发布如何迁移网站数据到新的服务器,以下是详细步骤和注意事项。
|
7月前
|
弹性计算 网络协议 Linux
阿里云服务器简介及使用教程,附送云服务器ECS自定义创建流程
阿里云ECS是安全可靠、弹性灵活的云计算服务,支持多种实例规格与操作系统,可快速创建和管理云服务器。本文详解ECS介绍、购买流程及使用教程,涵盖配置选择、网络设置、安全组规则等,助您轻松上手。
672 16
|
7月前
|
存储 弹性计算 网络协议
超详细的阿里云服务器购买流程,ECS自定义购买配置教程
本文详细图解阿里云ECS服务器自定义购买全流程,涵盖付费模式、地域选择、网络配置、实例规格、镜像、存储、安全组及登录设置等核心步骤,助您轻松掌握专业级云服务器搭建方法。
|
缓存 人工智能 架构师
释放数据潜力:利用 MCP 资源让大模型读懂你的服务器
MCP(Model Control Protocol)资源系统是将服务器数据暴露给客户端的核心机制,支持文本和二进制两种类型资源。资源通过唯一URI标识,客户端可通过资源列表或模板发现资源,并使用`resources/read`接口读取内容。MCP还支持资源实时更新通知及订阅机制,确保动态数据的及时性。实现时需遵循最佳实践,如清晰命名、设置MIME类型和缓存策略,同时注重安全性,包括访问控制、路径清理和速率限制等。提供的示例代码展示了如何用JavaScript和Python实现资源支持。
1209 80
|
弹性计算 Ubuntu Linux
阿里云服务器镜像怎么选?公共/自定义/共享/云市场/社区镜像区别与适用场景梳理
在购买阿里云服务器的过程中,选择合适的镜像(即云服务器的操作系统)是至关重要的一步。阿里云服务器镜像涵盖了公共镜像、自定义镜像、共享镜像、云市场镜像(镜像市场)和社区镜像等多种类型,对于新手用户来说,面对这些不同类型的镜像,往往会感到困惑,不知道它们之间的区别,更不知道如何根据自身需求进行选择。本文为大家解析这些镜像的特点、区别,并为大家提供选择参考。
1758 60
|
存储 弹性计算 安全
阿里云服务器自定义、快速、活动、云市场镜像四种主流方式解析与选择参考
阿里云服务器如何购买?目前主要的购买方式有自定义购买、快速购买、通过活动购买、通过云市场镜像页面购买这四种购买方式。然而,面对阿里云服务器多样化的购买方式和配置选项,许多用户可能会感到迷茫,不知道该如何选择最适合自己的购买途径。本文将详细解析阿里云服务器的四种主流购买方式的适用场景及购买流程,以供大家了解他们之间的区别及选择参考。
391 58
|
9月前
|
存储 安全 数据管理
服务器违规资源被删,数据定时备份OSS 云存储才是 “救命稻草”
在数字化时代,数据已成为企业与个人的核心资产。然而,服务器违规、硬件故障等问题频发,导致数据丢失、业务中断,甚至造成不可挽回的损失。为保障数据安全与业务连续性,定时备份至关重要。阿里云国际站OSS提供高效、可靠的云存储解决方案,支持自动定时备份,帮助用户轻松应对数据风险。本文详解OSS备份操作步骤与注意事项,助你为数据穿上“防护甲”,实现安全无忧存储。
|
11月前
|
存储 弹性计算 网络协议
如何自定义购买阿里云服务器ECS?详细参考步骤,答疑解惑
阿里云ECS(弹性计算服务)支持用户根据需求自定义配置服务器,包括实例规格、存储、带宽、镜像类型及安全组等。购买前需完成实名认证并确保账户余额充足。操作流程涵盖选择付费模式(包年包月/按量付费)、地域、镜像、网络设置、登录凭证及高级选项等。创建实例约需3-5分钟,建议慎重选择不可更改的配置(如地域),并注意安全性与带宽计费策略。详细步骤可参考官方文档。