想要观察阿里云上所有实例每周的cpu 平均使用率情况,根据阿里OpenAPI 提供的 " DescribeInstanceMonitorData " api来获取实例所有监控数据,之后再处理数据得到自己想要的指标。
OpenAPI 网址: https://api.aliyun.com
- 使用 python3
- 需要安装阿里OpenAPI SDK: python3 -m pip install aliyun-python-sdk-ecs
官方提供的 DescribeInstanceMonitorData python 版代码:
#!/usr/bin/env python
#coding=utf-8
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkecs.request.v20140526.DescribeInstanceMonitorDataRequest import DescribeInstanceMonitorDataRequest
client = AcsClient('<accessKeyId>', '<accessSecret>', 'cn-hangzhou')
request = DescribeInstanceMonitorDataRequest()
request.set_accept_format('json')
request.set_InstanceId("InstanceId")
request.set_StartTime("2020-04-09T00:00:00Z")
request.set_EndTime("2020-04-09T12:00:00Z")
request.set_Period(600)
response = client.do_action_with_exception(request)
# python2: print(response)
print(str(response, encoding='utf-8'))
修改成适合自己使用的:
#!/usr/bin/env python
# coding=utf-8
import json
import csv
from datetime import datetime, date
from datetime import timedelta
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkecs.request.v20140526.DescribeInstanceMonitorDataRequest import DescribeInstanceMonitorDataRequest
from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
def get_ecs_instance(access_key_id, access_secret):
client = AcsClient(access_key_id, access_secret, 'cn-hangzhou') # us-east-1
request = DescribeInstancesRequest()
request.set_accept_format('json')
request.set_PageNumber(1)
request.set_PageSize(100)
ins_ids = []
response = client.do_action_with_exception(request)
js = json.loads(response)
for i in js["Instances"]['Instance']:
ins_id = i["InstanceId"]
ins_ids.append(ins_id)
total_count = js["TotalCount"]
if int(total_count) > 100:
request.set_PageNumber(2)
response = client.do_action_with_exception(request)
js = json.loads(response)
for i in js["Instances"]['Instance']:
ins_id = i["InstanceId"]
ins_ids.append(ins_id)
return ins_ids
def get_ecs_info(access_key_id, access_secret, instance_id):
client = AcsClient(access_key_id, access_secret, 'cn-hangzhou')
request = DescribeInstancesRequest()
request.set_accept_format('json')
request.set_InstanceIds(f"[\"{instance_id}\"]")
response = client.do_action_with_exception(request)
js = json.loads(response)
ins = js["Instances"]['Instance'][0]
# create_time = ins["CreationTime"]
# expire_time = ins["ExpiredTime"]
instance_name = ins["InstanceName"]
# os_name = ins["OSName"]
# status = ins["Status"]
intranet_ip = ins["VpcAttributes"]["PrivateIpAddress"]["IpAddress"][0]
if ins["EipAddress"]["IpAddress"]:
eip = ins["EipAddress"]["IpAddress"]
# bandwidth = ins["EipAddress"]["Bandwidth"]
else:
eip = '-'
# bandwidth = ins["InternetMaxBandwidthOut"]
public_ip = ins["PublicIpAddress"]["IpAddress"][0] if ins["PublicIpAddress"]["IpAddress"] else eip
# cpu = ins["Cpu"]
# memory = ins["Memory"]
# ins_type = ins["InstanceType"]
try:
group = ins["Tags"]["Tag"][0]["TagValue"]
except:
group = '-'
return instance_name, intranet_ip, public_ip, group
# 获取 n 天前时间,并格式化为api指定格式时间戳
def get_date(days=0):
return (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%dT%H:%M:00Z")
# 格式化json输出
def get_pretty_print(res):
dat = json.loads(res)
js = json.dumps(dat, sort_keys=True, indent=4, separators=(',', ': '), ensure_ascii=False)
return js
# 设置获取起始时间点(阿里api限制,故每次获取一天数据)并获取数据
def do_request(access_key_id, access_secret, days=0, ins_id=""):
client = AcsClient(access_key_id, access_secret, 'cn-hangzhou')
instance_id = [] # 在此填入所有阿里实例ID,如:instance_id = ["i-bp1db2tn3cvfxxxxxxxx", "i-bp1auiw4jkbbxxxxxxxx"] 所有实例ID可由另一个api "DescribeInstances" 获得
request = DescribeInstanceMonitorDataRequest()
request.set_accept_format('json')
start_time = get_date(days) # 起始时间
end_time = get_date(days - 1) # 截止时间
request.set_InstanceId(ins_id)
request.set_StartTime(start_time)
request.set_EndTime(end_time)
request.set_Period(600) # 获取监控数据的间隔时间,设置为10分钟,阿里每次最多返回400条监控数据
res = client.do_action_with_exception(request)
return res
# key.txt 包含形如 '英合 LTAI4FzbQHxxxxxxxxxxx h9jINL03zxxxxxxxxxxxxxxxx' 的key
with open('key.txt', 'r', encoding='utf-8') as f:
data = f.readlines()
with open('ali_cpu.csv', 'w', encoding='utf-8', newline="") as f:
writer = csv.writer(f)
writer.writerow(
['实例ID', '名称', '公网ip', '内网ip', '7天平均CPU', '项目', '账号'])
for string in data:
account_name, access_key_id, access_secret = [n for n in string.split()]
ins_ids = get_ecs_instance(access_key_id, access_secret)
print(ins_ids)
for ins in ins_ids:
avg_s = 0
try:
for day in range(7, 0, -1): # 获取一周数据
r = do_request(access_key_id, access_secret, day, ins)
js = json.loads(r)
datas = js["MonitorData"]["InstanceMonitorData"]
sum = 0
for d in datas:
cpu = d['CPU'] if 'CPU' in d.keys() else 0
sum += cpu
avg = sum / len(datas)
avg_s += avg
except Exception as e:
print(e, ins)
avg_7d = int(avg_s / 7)
instance_name, intranet_ip, public_ip, group = get_ecs_info(access_key_id, access_secret, ins)
row = [ins, instance_name, public_ip, intranet_ip, avg_7d, group, account_name]
writer.writerow(row)
print(f'{instance_name} done')
需要观察其他指标可自行处理监控数据项。
Comments | 15 条评论
我不太懂 博主
wow! Python!
mocuishle 博主
@我不太懂
咬你
我不太懂 博主
@mocuishle
猪肉可贵了
mocuishle 博主
@我不太懂
不吃不吃
我不太懂 博主
if [-e new post]; then comment;
fi
mocuishle 博主
@我不太懂
悄悄告诉你 ‘[‘ 右侧和 ‘]’ 左侧要加个空格
: ) 不错不错
我不太懂 博主
@mocuishle
好了好了,知道了( )
LOGI 博主
dalao
mocuishle 博主
@LOGI
哈哈不是不是
repo 博主
能拉Memory吗研究了半天
mocuishle 博主
@repo
mem的api我也没找到,翻遍了
repo 博主
@mocuishle
我拉了CPU存到了数据库里,内存的一直没找到在哪,但是我我看到运维界面有内存的数据,不知道从而来
mocuishle 博主
@repo
是啊没开放出来吧,所以我每天云监控看一眼所有机子数据
我烧开后就爆炸 博主
这就很Nice了
mocuishle 博主
@我烧开后就爆炸
哈,就自己稍微改下用用