阿里云云监控API(Python)

阿里云云监控

功能特性

云监控支持的功能特性如下表所示。

功能 说明
Dashboard 为您提供自定义查看监控数据的功能。您可以在一个监控大盘中跨产品、跨实例查看监控数据,将相同业务的不同产品实例集中展现。
应用分组 为您提供跨云产品、跨地域的云产品资源分组管理功能。支持您从业务角度集中管理业务线涉及到的服务器、数据库、负载均衡、存储等资源。从而按业务线来管理报警规则,查看监控数据,可以迅速提升运维效率。
主机监控 主机监控服务通过在服务器上安装插件,为您提供CPU、内存、磁盘、网络等三十种监控项,并对所有监控项提供报警功能,您可以选择从实例、应用分组、全部资源三个角度设置报警规则。从不同业务角度使用报警功能,可以满足您对服务器的基本监控与运维需求。目前支持Linux和Windows操作系统。
事件监控 为您提供事件类型数据的上报、查询、报警功能,方便您将业务中的各类异常事件或重要变更事件收集上报到云监控,并在异常发生时接收报警。
自定义监控 您可以针对自己关心的业务指标进行自定义监控,将采集到的监控数据上报至云监控,由云监控来进行数据的处理,并根据处理结果进行报警。
日志监控 为您提供日志数据实时分析、监控图表可视化展示和报警服务。您只需要开通日志服务,将本地日志通过日志服务进行收集,即可解决企业的监控运维与运营诉求。此外,日志服务还可完美结合云监控的主机监控、云服务监控、站点监控、应用分组、Dashboard、报警服务,形成完整的监控闭环。
站点监控 为您提供互联网网络探测的监控服务,主要用于通过遍布全国的互联网终端节点,发送模拟真实用户访问的探测请求,监控全国各省市运营商网络终端用户到您服务站点的访问情况。
云服务监控 为您提供查询已购买云服务实例的各项性能指标的情况,帮助您分析使用情况、统计业务趋势,及时发现并诊断相关问题。
报警服务 为您提供监控数据的报警功能。您可以通过设置报警规则来定义报警系统如何检查监控数据,并在监控数据满足报警条件时发送报警通知。您对重要监控指标设置报警规则后,便可在第一时间得知指标数据发生异常,迅速处理故障。
资源消耗 为您提供查看资源消耗详情的功能,您也可以购买短信资源包或电话报警资源包。

Python API使用手册

  • 请求结构
  • 云监控接入地址
  • API授权
  • API签名

云监控接口调用是向云监控API的服务端地址发送HTTP GET请求,并按照接口说明在请求中加入相应请求参数,调用后系统会返回处理结果。请求及返回结果都使用UTF-8字符集进行编码。

请求结构

云监控的API是RPC风格,您可以通过发送HTTP请求调用云监控API。

其请求结构如下:

http://endpoint/?Action=xx¶meters

其中:

  • Endpoint是调用的云服务的接入点,云监控的接入点是metrics.aliyuncs.com。各地域的服务地址,参见云监控接入地址。
  • Action是要执行的操作,如使用DescribeMetricList接口查询某一实例的监控数据。
  • Version要使用的API版本,云监控的API版本是2019-01-01。
  • Parameters是请求参数,每个参数之间用&分隔。请求参数由公共请求参数和API自定义参数组成。公共参数中包含API版本号、身份验证等信息。

下面是一个调用DescribeMetricList接口查询某一实例的监控数据的示例。

http://metrics.cn-hangzhou.aliyuncs.com/?Action=DescribeMetricList
&EndTime=2017-05-17+11%3A30%3A27
&StartTime=2017-05-17+11%3A20%3A27
&Period=60
&Dimensions=%7B%22instanceId%22%3A%22i-abcdefgh123456%22%7D
&Timestamp=2017-03-22T09%3A30%3A57Z
&Namespace=acs_ecs_dashboard
&Metric=cpu_idle

云监控接入地址

地域名称 服务地址
华北 1(青岛) metrics.cn-qingdao.aliyuncs.com
华北 2(北京) metrics.cn-beijing.aliyuncs.com
华北 3(张家口) metrics.cn-zhangjiakou.aliyuncs.com
华北 5(呼和浩特) metrics.cn-huhehaote.aliyuncs.com
华东 1(杭州) metrics.cn-hangzhou.aliyuncs.com
华东 2(上海) metrics.cn-shanghai.aliyuncs.com
华南 1(深圳) metrics.cn-shenzhen.aliyuncs.com
中国香港(香港) metrics.cn-hongkong.aliyuncs.com
亚太东南 1(新加坡) metrics.ap-southeast-1.aliyuncs.com
亚太东南 2(悉尼) metrics.ap-southeast-2.aliyuncs.com
亚太东南 3(吉隆坡) metrics.ap-southeast-3.aliyuncs.com
亚太东南 5(雅加达) metrics.ap-southeast-5.aliyuncs.com
亚太南部 1(孟买) metrics.ap-south-1.aliyuncs.com
亚太东北 1(东京) metrics.ap-northeast-1.aliyuncs.com
美国西部 1(硅谷) metrics.us-west-1.aliyuncs.com
美国东部 1(弗吉尼亚) metrics.us-east-1.aliyuncs.com
欧洲中部 1(法兰克福) metrics.eu-central-1.aliyuncs.com
英国(伦敦) metrics.eu-west-1.aliyuncs.com
中东东部 1(迪拜) metrics.me-east-1.aliyuncs.com

API授权

为了确保您的账号安全,建议您使用子账号的身份凭证调用API。如果您使用RAM账号调用云监控API,您需要为该RAM账号创建、附加相应的授权策略。

API签名

为保证API的安全调用,在调用API时阿里云会对每个API请求通过签名(Signature)进行身份验证。当您手动发起API请求时,需要按照RFC 2104的定义,使用AccessSecret对编码、排序后的整个请求串计算HMAC值作为签名。更多详细信息,请参见RPC API签名。

RPC API要按如下格式在API请求的中增加签名(Signature):

https://endpoint/?SignatureVersion=1.0&SignatureMethod=HMAC-SHA1&Signature=CT9X0VtwR86fNWSnsc6v8YGOjuE%3D&SignatureNonce=3ee8c1b8-83d3-44af-a94f-4e0ad82fd6cf

以DescribeMetricList为例,如果使用的AccessKey ID是testid,AccessKey Secret是 testsecret,则签名前的请求URL为:

http://metrics.aliyuncs.com/?Action=DescribeMetricList&period=60&StartTime=2016-03-22T11:30:27Z&Dimensions={instanceId:'i-abcdefgh123456'}&Timestamp=2017-03-23T06:59:55Z&Namespace=acs_ecs_dashboard&SignatureVersion=1.0&Format=JSON&SignatureNonce=aeb03861-611f-43c6-9c07-b752fad3dc06&Version=2015-10-20&AccessKeyId=TestId&MetricName=cpu_idle&SignatureMethod=HMAC-SHA1

计算得到的待签名字符串StringToSign为:

GET&%2F&AccessKeyId%3DTestId&Action%3DDescribeMetricList&Dimensions%3D%257B%2522instanceId%2522%253A%2522i-abcdefgh123456%2522%257D&Format%3DJSON&Metric%3Dcpu_idle&Period%3D60&Namespace%3Dacs_ecs_dashboard&SignatureMethod%3DHMAC-SHA1&SignatureNonce%3Daeb03861-611f-43c6-9c07-b752fad3dc06&SignatureVersion%3D1.0&StartTime%3D2016-03-22T11%253A30%253A27Z&Timestamp%3D2017-03-23T06%253A59%253A55Z&Version%3D2015-10-20

因为AccessKey Secret是testsecret,所以用于计算HMAC的Key为testsecret&,计算得到的签名值是:

TLj49H/wqBWGJ7RK0r84SN5IDfM=

将签名作为Signature参数加入到URL请求中,得到最后的URL为:

http://metrics.cn-hangzhou.aliyuncs.com/?Action=DescribeMetricList&StartTime=2016-03-22T11%3A30%3A27Z&Period=60&Dime

个人应用

基本参数配置


获取所有报警规则

alarm_list

主机监控

query_last

历史报警记录(30分钟前)

ListAlarmHistory

完整代码

#!/usr/bin/env python
# coding=utf-8
"""
author:mi
阿里云监控api,每半小时检测一次
用到的api有ListAlarm、QueryMetricLast、ListAlarmHistory
"""
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
import json
import pandas as pd
import time
import database_operation
import config
import datetime
import mail

class ali_monitor_api:
    def __init__(self):
        self.accessKeyId = '*'   #accesskey
        self.accessSecret = '*'
        self.client = AcsClient(self.accessKeyId, self.accessSecret, 'default')
        self.request = CommonRequest()
        self.request.set_accept_format('json')
        self.request.set_domain('metrics.cn-hangzhou.aliyuncs.com')
        self.request.set_method('POST')
        self.request.set_protocol_type('https')  # https | http
        self.request.set_version('2018-03-08')
        self.request.add_query_param('RegionId', 'default')

    def ListAlarm(self):  #获取所有报警规则
        self.request.set_action_name('ListAlarm')
        self.request.add_query_param('IsEnable', 'true')
        response = self.client.do_action_with_exception(self.request)
        alarm = json.loads(str(response, encoding='utf-8'))
        print(alarm)
        _alarm = alarm["AlarmList"]["Alarm"]
        alarm_list = {"Name": [], "MetricName": [], "Namespace": [], "Id": []}
        for i in _alarm:
            Name = i["Name"]
            MetricName = i["MetricName"]
            Namespace = i["Namespace"]
            Id = i["Id"]
            alarm_list["Name"].append(Name)
            alarm_list["MetricName"].append(MetricName)
            alarm_list["Namespace"].append(Namespace)
            alarm_list["Id"].append(Id)
            # print(Name,MetricName,Namespace)
        alarm_list = pd.DataFrame(alarm_list)
        print(alarm_list)
        return alarm_list

    def QueryMetricLast(self):   #主机监控
        sql = ("SELECT deviceid as instanceid,DeviceName FROM op_iot_devicelist "
               "where devicetype='acs_ecs_dashboard' and flag=1;")
        instancename = database_operation.data_out_mysql(config.xinyiplatform, sql)  #op_iot_devicelist表取instanceid
        project = "acs_ecs_dashboard"
        self.request.set_action_name('QueryMetricLast')
        self.request.add_query_param('Project', project)
        query_last = pd.DataFrame(
            columns=["Name", "metricname", "project", "period", "Average", "Maximum", "Minimum", "timestamp",
                     "instanceid","diskname"])
        # print(instancename)
        Metriclist = ["cpu_total", "memory_usedutilization", "diskusage_utilization"]
        for i in range(len(instancename)):
            instanceid = instancename.loc[i, "instanceid"]
            Name = instancename.loc[i, "DeviceName"]
            for metricname in Metriclist:
                self.request.add_query_param('Metric', metricname)
                self.request.add_query_param('Dimensions', '[{"instanceId":"%s"}]' % instanceid)
                response = self.client.do_action_with_exception(self.request)
                # print(Name, MetricName, Project, json.loads(str(response, encoding='utf-8')))
                data = json.loads(str(response, encoding='utf-8'))
                Period = data["Period"]
                Datapoints = data["Datapoints"]
                if Datapoints:
                    datapoints = json.loads(data["Datapoints"])
                    for n in datapoints:
                        Average = str(n["Average"]) + "%"
                        Maximum = str(n["Maximum"]) + "%"
                        Minimum = str(n["Minimum"]) + "%"
                        instanceid = n["instanceId"]
                        timestamp = n["timestamp"]
                        timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(timestamp / 1000))
                        if "device" in data["Datapoints"]:
                            diskname = n["diskname"]
                            querymetriclast1 = {"Name": Name, "metricname": metricname, "project": project,"diskname":diskname,
                                                "period": Period, "Average": Average,
                                                "Maximum": Maximum, "Minimum": Minimum, "timestamp": timestamp,
                                                "instanceid": instanceid}
                            querymetriclast1 = pd.DataFrame.from_dict(querymetriclast1, orient='index').T
                            query_last = query_last.append(querymetriclast1)
                        # print(querymetriclast)
                        else:
                            querymetriclast2 = {"Name": Name, "metricname": metricname, "project": project, "period": Period, "Average": Average,
                                               "Maximum": Maximum, "Minimum": Minimum, "timestamp": timestamp, "instanceid": instanceid}

                            querymetriclast2 = pd.DataFrame.from_dict(querymetriclast2,orient='index').T
                            # print(querymetriclast2)
                            query_last = query_last.append(querymetriclast2)
        # print(query_last)
        query_last[["diskname"]] = query_last[["diskname"]].where(
            query_last[["diskname"]].notnull(), None)
  
        # print(query_last)
        database_operation.data_into_mysql(config.xinyiplatform, query_last, "op_ali_querymetriclast")

    def ListAlarmHistory(self):  #历史报警记录
        ListAlarmHistory = pd.DataFrame(columns=["Value", "LastTime", "AlarmTime", "EvaluationCount", "Name",
                                                 "Status", "MetricName", "State", "project", "Id", "ContactGroups",
                                                 "InstanceName"])
        alarm_list = self.ListAlarm()
        for i in range(len(alarm_list)):
            Id = alarm_list.loc[i, "Id"]
            self.request.set_action_name('ListAlarmHistory')
            self.request.add_query_param('Id', Id)
            # EndTime = "2019-03-20 00:00:00"
            # StartTime = "2019-03-19 00:00:00"
            EndTime = (datetime.datetime.now()).strftime('%Y-%m-%d %H:%M:%S')
            StartTime = (datetime.datetime.strptime(EndTime, '%Y-%m-%d %H:%M:%S')-datetime.timedelta(minutes=3000)).strftime('%Y-%m-%d %H:%M:%S')
            # StartTime = (datetime.datetime.now()).strftime('%Y-%m-%d ') + "00:00:00"
            self.request.add_query_param('StartTime', StartTime)
            self.request.add_query_param('EndTime', EndTime)
            response = self.client.do_action_with_exception(self.request)
            data = json.loads(str(response, encoding='utf-8'))
            print(data)
            AlarmHistory = data["AlarmHistoryList"]["AlarmHistory"]
            if AlarmHistory:
                alarmhistory = {"Value": [], "LastTime": [], "AlarmTime": [], "EvaluationCount": [], "Name": [],
                                "Status": [], "MetricName": [], "State": [], "project": [], "Id": [],
                                "ContactGroups": [], "InstanceName": []}
                for i in range(len(AlarmHistory)):
                    Value = AlarmHistory[i]["Value"]
                    LastTime = AlarmHistory[i]["LastTime"] / 1000
                    AlarmTime = AlarmHistory[i]["AlarmTime"]
                    AlarmTime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(AlarmTime / 1000))
                    EvaluationCount = AlarmHistory[i]["EvaluationCount"]
                    Name = AlarmHistory[i]["Name"]
                    Status = AlarmHistory[i]["Status"]
                    MetricName = AlarmHistory[i]["MetricName"]
                    State = AlarmHistory[i]["State"]
                    Namespace = AlarmHistory[i]["Namespace"]
                    Id = AlarmHistory[i]["Id"]
                    ContactGroups = AlarmHistory[i]["ContactGroups"]
                    InstanceName = AlarmHistory[i]["InstanceName"]
                    alarmhistory["Value"].append(Value)
                    alarmhistory["LastTime"].append(LastTime)
                    alarmhistory["AlarmTime"].append(AlarmTime)
                    alarmhistory["EvaluationCount"].append(EvaluationCount)
                    alarmhistory["Name"].append(Name)
                    alarmhistory["Status"].append(Status)
                    alarmhistory["MetricName"].append(MetricName)
                    alarmhistory["State"].append(State)
                    alarmhistory["project"].append(Namespace)
                    alarmhistory["Id"].append(Id)
                    alarmhistory["ContactGroups"].append(ContactGroups)
                    alarmhistory["InstanceName"].append(InstanceName)
                alarmhistory = pd.DataFrame(alarmhistory)
                ListAlarmHistory = ListAlarmHistory.append(alarmhistory)
 
        if not ListAlarmHistory.empty:
            # delete_time = (datetime.datetime.now()).strftime('%Y-%m-%d')
            # sql = "delete FROM op_ali_listalarmhistory where date(alarmtime)=\'%s\'" % (delete_time)
            database_operation.data_into_mysql(config.xinyiplatform, ListAlarmHistory, "op_ali_listalarmhistory")

def main():
    print("ali-monitoring is starting......")
    try:
        aa = ali_monitor_api()
        aa.QueryMetricLast()
        aa.ListAlarmHistory()
    except Exception as e:
        print(e)
        mail.send_mail("ali_monitor_api error",repr(e))
    print("ali-monitoring is over......")

database_operation.py

# -*- coding: utf-8 -*-

import pymysql
import pymssql
import pandas as pd


# mysql取数
def data_out_mysql(DB, sql):
    conn = pymysql.connect(host=DB["host"], user=DB['user'], passwd=DB['passwd'],
                           db=DB['db'], use_unicode=True, charset="utf8",read_timeout=20,write_timeout=20,connect_timeout=20)
    cursor = conn.cursor()
    cursor.execute(sql)
    data = cursor.fetchall()
    cols = cursor.description
    conn.commit()
    conn.close()
    col = []
    for i in cols:
        col.append(i[0])
    data = list(map(list, data))
    data = pd.DataFrame(data, columns=col)
    return data


# sql server取数
def data_out_sql_server(DB, sql):
    conn = pymssql.connect(server=DB["host"], user=DB['user'], password=DB['passwd'], database=DB['db'], charset='utf8')
    cursor = conn.cursor(as_dict=True)
    cursor.execute(sql)
    data = cursor.fetchall()
    conn.commit()
    conn.close()
    data = pd.DataFrame(data)
    for col in data.columns:  # 解决中文乱码的问题
        try:
            data[col] = (data[col].str.encode('latin-1')).str.decode('gbk')
        except:
            pass
    return data


# mysql 写数
# data为dataframe格式,columns类型为字符串
# sql_del删除数据用,不用默认为select 1;
def data_into_mysql(DB, data, table, sql_del="select 1;"):
    names = data.columns
    s = '%s'
    for i in range(len(names) - 1):
        s = s + ' ,%s'
    names = ','.join(names)
    sql = 'INSERT INTO ' + table + " (" + names + ') VALUES( ' + s + ' )'
    d = [tuple(None if j == None else str(j) for j in data.iloc[i, :]) for i in range(len(data))]
    conn = pymysql.connect(DB['host'], DB['user'], DB['passwd'], DB['db'], charset='utf8',read_timeout=20,write_timeout=20,connect_timeout=20)
    cursor = conn.cursor()
    cursor.execute(sql_del)
    cursor.executemany(sql, d)
    conn.commit()
    conn.close()

# sql server写数
# data为dataframe格式,columns类型为字符串
# sql_del删除数据用,不用默认为select 1;
def data_into_sql_server(DB, data, table, sql_del="select 1;"):
    names = data.columns
    s = '%s'
    for i in range(len(names) - 1):
        s = s + ' ,%s'
    names = ','.join(names)
    sql = 'INSERT INTO ' + table + " (" + names + ') VALUES( ' + s + ' )'
    d = [tuple(None if j == None else str(j) for j in data.iloc[i, :]) for i in range(len(data))]
    conn = pymssql.connect(DB['host'], DB['user'], DB['passwd'], DB['db'], charset='utf8')
    cursor = conn.cursor()
    cursor.execute(sql_del)
    cursor.executemany(sql, d)
    conn.commit()
    conn.close()

你可能感兴趣的:(阿里云云监控API(Python))