阿里云共享流量包分析脚本

pip install aliyun-python-sdk-ecs==4.24.13
pip install aliyun-python-sdk-slb==3.3.9
pip install aliyun-python-sdk-vpc==3.0.16
pip install aliyun-python-sdk-bssopenapi==2.0.3
pip install pandas
pip install xlrd
pip install openpyxl
#!/usr/bin/env python
# coding=utf-8
'''
Author: LJX
Date: 2022-01-06 16:31:14
LastEditors: LJX
LastEditTime: 2022-02-08 16:17:20
namespace: https://www.cnblogs.com/lanheader
Description: 计算流量使用情况
'''
from platform import platform
from aliyunsdkcore.client import AcsClient
from aliyunsdkcore.request import CommonRequest
from aliyunsdkcore.auth.credentials import AccessKeyCredential
from aliyunsdkcore.auth.credentials import StsTokenCredential
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException

from aliyunsdkecs.request.v20140526.DescribeInstancesRequest import DescribeInstancesRequest
from aliyunsdkslb.request.v20140515.DescribeLoadBalancersRequest import DescribeLoadBalancersRequest
from aliyunsdkbssopenapi.request.v20171214.QueryDPUtilizationDetailRequest import QueryDPUtilizationDetailRequest


import csv
import os
import json
import pandas as pd
import time
import datetime


class ParseNetwork(object):
    def __init__(self, filename=''):
        self.filename = filename

    def get_eip(self, postion):
        """
        :调用阿里云接口获取弹性IP地址
        :param page_size:
        :return:弹性IP地址
        """
        client = AcsClient(region_id=postion,
                           credential=self.credentials)
        request = CommonRequest()
        request.set_accept_format('json')
        request.set_domain('vpc.aliyuncs.com')
        request.set_method('POST')
        request.set_protocol_type('https')  # https | http
        request.set_version('2016-04-28')
        request.set_action_name('DescribeEipAddresses')
        request.add_query_param('RegionId', postion)
        request.add_query_param('PageNumber', "1")
        request.add_query_param('PageSize', "100")
        request.add_query_param('Status', "InUse")
        response = client.do_action(request)
        data = json.loads(str(response, encoding='utf-8')
                          )["EipAddresses"]['EipAddress']
        return data

    def parse_eip(self):
        """
        :pandas格式化弹性ip数据
        :param page_size:
        :return:弹性IPpandas 对象
        """
        data = []
        for postion in self.positions:
            restult = self.get_eip(postion)
            # print(postion + ':{0}'.format(len(restult)))
            data += restult
        print("eip总长度:{0}".format(len(data)))
        df = pd.DataFrame(data)
        # 这里可写入execl进行查看数据
        # df.to_excel('eip.xlsx', index=False)
        df.set_index('AllocationId', inplace=True)
        df.shape[0]
        return df

    def instances_count(self, postion, page_size=100):
        """
        返回页码数量
        :param page_size:
        :return:
        """
        # 创建 request,并设置参数
        client = AcsClient(region_id=postion,
                           credential=self.credentials)
        request = DescribeInstancesRequest()
        request.set_PageSize(page_size)
        # 发起 API 请求并打印返回
        response = client.do_action_with_exception(request)
        ret = json.loads(str(response, encoding='utf-8'))

        # 页码
        total_page, b = divmod(ret['TotalCount'], page_size)
        if b:
            total_page = total_page + 1
        return total_page

    def get_ecs(self, postion):
        """
        :获取ecs信息
        :param page_size:
        :return:ecs信息
        """

        client = AcsClient(region_id=postion,
                           credential=self.credentials)
        total_page = self.instances_count(postion, page_size=100)
        data = []
        for page_num in range(1, total_page + 1):
            request = DescribeInstancesRequest()
            request.set_accept_format('json')
            request.set_PageSize(100)
            request.set_PageNumber(page_num)

            response = client.do_action_with_exception(request)
            data += json.loads(str(response, encoding='utf-8')
                               )["Instances"]["Instance"]

        return data

    def parse_ecs(self):
        """
        :pandas格式化ecs信息
        :param page_size:
        :return:ecs格式化信息
        """
        data = []
        for postion in self.positions:
            restult = self.get_ecs(postion)
            data += restult
        print("ecs总长度:{0}".format(len(data)))
        df = pd.DataFrame(data)
        # 这里可写入execl进行查看数据
        # df.to_excel('ecs.xlsx', index=False)
        df.set_index("InstanceId", inplace=True)
        return df

    def get_slb(self, postion):
        """
        :获取slb信息
        :param page_size:
        :return:ecs信息
        """
        client = AcsClient(region_id=postion,
                           credential=self.credentials)
        request = DescribeLoadBalancersRequest()
        request.set_accept_format('json')
        response = client.do_action_with_exception(request)
        data = json.loads(str(response, encoding='utf-8')
                          )["LoadBalancers"]["LoadBalancer"]
        return data

    def parse_slb(self):
        """
        :pandas格式化slb数据
        :param page_size:
        :return:格式化slb数据
        """

        data = []
        for postion in self.positions:
            restult = self.get_slb(postion)
            data += restult
        print("slb总长度:{0}".format(len(data)))
        df = pd.DataFrame(data)
        # 这里可写入execl进行查看数据
        #df.to_excel('slb.xlsx', index=False)
        df.set_index("LoadBalancerId", inplace=True)
        return df

    def main_eip(self, df_eip, df_ecs, eip):
        """
        :清洗eip数据
        :param page_size:
        :return
        """
        try:
            if eip in df_eip.index:
                instanceid = df_eip.loc[eip, "InstanceId"]
                return "ECS+弹性IP:" + df_ecs.loc[instanceid, "InstanceName"]
            else:
                # print("未查到相关信息eip:{0}".format(eip))
                return "未绑定弹性IP:{0}".format(eip)
        except Exception as e:
            print(e)

    def main_slb(self, df_slb, i):
        """
        :清洗slb数据
        :param page_size:
        :return
        """

        return "SLB:" + df_slb.loc[i, "LoadBalancerName"]

    def main_ecs(self, df_ecs, i):
        """
        :清洗ecs数据
        :param page_size:
        :return
        """
        return "ECS+公网IP:" + df_ecs.loc[i, "InstanceName"]

    def get_data(self, postion, startTime, endTime, instance_id):
        """
        :获取数据
        :param page_size:
        :return
        """
        result = []
        count_result = 0
        count_once = 0
        lastToken = None
        while 1:
            client = AcsClient(region_id=postion,
                               credential=self.credentials)
            request = QueryDPUtilizationDetailRequest()
            request.set_accept_format('json')
            request.set_StartTime(startTime)
            if lastToken is not None:
                request.set_LastToken(lastToken)
            request.set_EndTime(endTime)
            request.set_IncludeShare(True)
            request.set_InstanceId(instance_id)
            request.set_Limit(300)
            response = client.do_action_with_exception(request)
            count_once += 1
            lastToken = json.loads(str(response, encoding='utf-8')
                                   )["Data"]["NextToken"]
            result += json.loads(str(response, encoding='utf-8')
                                 )["Data"]["DetailList"]["DetailList"]
            count = len(json.loads(str(response, encoding='utf-8')
                                   )["Data"]["DetailList"]["DetailList"])
            count_result += count
            print("当前{0} 次查询:{1}个,现在总数{2}".format(
                str(count_once), str(count), str(count_result)))
            if lastToken == "":
                break
        print("总条数共:{0}个".format(str(count_result)))
        return result

    def parse_source_data(self):
        """
        :pandas 格式化数据源
        :param page_size:
        :return
        """
        data = []
        # startTime = "2021-7-1 00:00:00"
        startTime = input("请输入查询起始时间,格式%Y-%m-%d %H:%M:%S :")
        endTime = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        instance_id = input("请输入资源包ID:")
        postion = "cn-shenzhen"
        data = self.get_data(
            postion, startTime, endTime, instance_id)
        print("数据源总长度:{0}".format(len(data)))
        df = pd.DataFrame(data)
        return df

    def main_api(self):
        """
        :阿里云读取接口
        :param page_size:
        :return
        """
        df = self.parse_source_data()
        print('共使用:{0}GB'.format(
            int(df.loc[:, 'DeductMeasure'].sum())/1024/1024/1024))
        print('共剩余:{0}GB'.format(int(input("请输入流量包总量(单位TB):"))*1024 -
                                 int(df.loc[:, 'DeductMeasure'].sum())/1024/1024/1024))

        unit = input("请输入过滤单位(KB/MB/GB)")
        if unit == "KB":
            val = 1024
        if unit == "MB":
            val = 1024*1024
        if unit == "GB":
            val = 1024*1024*1024

        df_eip = self.parse_eip()
        df_ecs = self.parse_ecs()
        df_slb = self.parse_slb()
        restult = []
        # 过滤弹性IP
        for i in df.loc[df["DeductedProductDetail"] == "弹性公网IP(后付费)", 'DeductedInstanceId'].unique():
            dic1 = {}
            used1 = int(df.loc[df['DeductedInstanceId'] == i,
                               'DeductMeasure'].sum())/val
            name1 = self.main_eip(df_eip, df_ecs, i)
            if name1 == None:
                name1 = i
            if int(used1) != 0:
                dic1["名称"] = name1
                dic1["使用量"] = int(used1)
                restult.append(dic1)
        # 过滤 ecs
        for i in df.loc[df["DeductedProductDetail"] == "云服务器ECS(包月)", 'DeductedInstanceId'].unique():
            dic2 = {}
            used2 = int(df.loc[df['DeductedInstanceId'] == i,
                               'DeductMeasure'].sum())/val
            name2 = self.main_ecs(df_ecs, i)

            if name2 == None:
                name2 = i
            if int(used2) != 0:
                dic2["名称"] = name2
                dic2["使用量"] = int(used2)
                restult.append(dic2)

        # 过滤 slb
        for i in df.loc[df["DeductedProductDetail"] == "传统型负载均衡CLB(按量付费)", 'DeductedInstanceId'].unique():
            dic3 = {}
            used3 = int(df.loc[df['DeductedInstanceId'] == i,
                               'DeductMeasure'].sum())/val
            name3 = self.main_slb(df_slb, i)

            if name3 == None:
                name3 = i
            if int(used3) != 0:
                dic3["名称"] = name3
                dic3["使用量"] = int(used3)
                restult.append(dic3)

        result_data = pd.DataFrame(restult)
        for index, row in result_data.sort_values(by='使用量', ascending=False).iterrows():
            print("{0}:使用量为{1} {2}".format(row["名称"], row["使用量"], unit))

    # 以下为读文件分析,非调用接口实现
    # def main_file(self):
    #     """
    #     :阿里云读取文件
    #     :param page_size:
    #     :return
    #     """
    #     df = pd.read_csv(self.filename, encoding='utf-8')
    #     print('共使用:{0}GB'.format(
    #         int(df.loc[:, '使用量(原始单位)'].sum())/1024/1024/1024))
    #     print('共剩余:{0}GB'.format(int(input("请输入流量包总量:"))*1024 -
    #                              int(df.loc[:, '使用量(原始单位)'].sum())/1024/1024/1024))
    #     df_eip = self.parse_eip()
    #     df_ecs = self.parse_ecs()
    #     df_slb = self.parse_slb()

    #     # 过滤弹性IP
    #     for i in df.loc[df["抵扣产品"] == "弹性公网IP", '抵扣实例ID'].unique():
    #         used = int(df.loc[df['抵扣实例ID'] == i,
    #                    '使用量(原始单位)'].sum())/1024/1024/1024
    #         name = self.main_eip(df_eip, df_ecs, i)
    #         print("{0}:使用量为{1} GB".format(name, used))
    #     # 过滤 ecs
    #     for i in df.loc[df["抵扣产品"] == "云服务器ECS-包年包月", '抵扣实例ID'].unique():
    #         used = int(df.loc[df['抵扣实例ID'] == i,
    #                    '使用量(原始单位)'].sum())/1024/1024/1024
    #         name = self.main_ecs(df_ecs, i)
    #         print("{0}:使用量为{1} GB".format(name, used))
    #     # 过滤 slb
    #     for i in df.loc[df["抵扣产品"] == "负载均衡", '抵扣实例ID'].unique():
    #         used = int(df.loc[df['抵扣实例ID'] == i,
    #                    '使用量(原始单位)'].sum())/1024/1024/1024
    #         name = self.main_slb(df_slb, i)
    #         print("{0}:使用量为{1} GB".format(name, used))


    def main(self):
        """
        :主方法
        :param page_size:
        :return
        """
        self.credentials = AccessKeyCredential(
            'xxxxx', 'xxxxx')
        self.positions = ['cn-shenzhen', 'cn-hongkong',
                          'cn-hangzhou', 'cn-chengdu', 'cn-qingdao']  # 这里可添加区域
        self.main_api()



if __name__ == '__main__':
    PN = ParseNetwork(
        filename="xxxxx.csv")
    PN.main()
posted @ 2022-02-08 16:36  兰嘉轩  阅读(95)  评论(0编辑  收藏  举报