阿里云云监控
功能特性
云监控支持的功能特性如下表所示。
功能 | 说明 |
---|---|
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()