├── .gitignore
├── ALI.py
├── AWS.py
├── KSC.py
├── README-en.md
├── README.md
├── cloud2falcon.py
├── config.yml
├── info.png
├── log.py
├── logging.yml
├── multiCloud.py
├── requirements.txt
└── templates
├── ali-connect
├── ali-connect-max
├── ali-eip
├── ali-eip-max
├── ali-nat
├── ali-oss
├── aws-connect
├── aws-lb
├── aws-nat
├── aws-s3
├── ksc-connect
├── ksc-connect-max
├── ksc-eip
├── ksc-eip-max
├── ksc-elb
├── ksc-elb-max
├── ksc-nat
└── ksc-nat-max
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | __pycache__/
3 | *.pyc
4 | log/*
5 | venv/
6 | test.py
--------------------------------------------------------------------------------
/ALI.py:
--------------------------------------------------------------------------------
1 | import json
2 | import logging
3 | import datetime
4 | import oss2
5 | import time
6 | from aliyunsdkcore.request import CommonRequest
7 | from aliyunsdkcore.client import AcsClient
8 | from aliyunsdkslb.request.v20140515 import DescribeLoadBalancersRequest
9 | from aliyunsdkvpc.request.v20160428 import DescribeEipAddressesRequest
10 | from aliyunsdkvpc.request.v20160428 import DescribeNatGatewaysRequest
11 | from cloud2falcon import PERIOD
12 |
13 |
14 | def chunks(l, n):
15 | for i in range(0, len(l), n):
16 | yield l[i: i + n]
17 |
18 |
19 | def get_metric_data(period, namespace, name, id_list,
20 | metricname, ak, sk, region):
21 | metric_data = []
22 | if metricname == 'BandWidth':
23 | ts = time.time()
24 | t = int(ts)
25 | for id in id_list:
26 | v = int(id['BandWidth']) * 1024 * 1024
27 | if v == 0:
28 | continue
29 | data = {"id": id['l'], "ip": id['d'], "region": region['site'], "metric": metricname,
30 | "time": t, "value": v}
31 | metric_data.append(data)
32 | for instance_id in list(chunks(id_list, 50)):
33 | data = get_metric_data_50(
34 | period,
35 | namespace,
36 | name,
37 | instance_id,
38 | metricname,
39 | ak,
40 | sk,
41 | region)
42 | metric_data += data
43 | return metric_data
44 |
45 |
46 | def get_metric_data_50(period, namespace, name, id_list,
47 | metricname, ak, sk, region):
48 | metric_data = []
49 | clt = AcsClient(ak, sk, region['name'])
50 | request = CommonRequest()
51 | request.set_accept_format('json')
52 | request.set_domain('metrics.cn-hangzhou.aliyuncs.com')
53 | request.set_method('POST')
54 | request.set_version('2018-03-08')
55 | request.set_action_name('QueryMetricList')
56 | request.add_query_param('Metric', metricname)
57 | request.add_query_param('Period', period)
58 | request.add_query_param('Project', name)
59 | request.add_query_param(
60 | 'StartTime',
61 | datetime.datetime.now() -
62 | datetime.timedelta(
63 | minutes=PERIOD))
64 | request.add_query_param('EndTime', datetime.datetime.now())
65 | list = []
66 | for instance_id in id_list:
67 | if (name == "acs_nat_gateway" and metricname == "SnatConnection") \
68 | or name == "acs_publicip"\
69 | or name == "acs_express_connect":
70 | list.append({'instanceId': str(instance_id['d'])})
71 | elif name == "acs_oss":
72 | list.append({'BucketName': str(instance_id['d'])})
73 | else:
74 | list.append({'instanceId': str(instance_id['l'])})
75 |
76 | request.add_query_param('Dimensions', list)
77 | response = clt.do_action_with_exception(request)
78 | response1 = str(response)
79 | response1 = json.loads(response1)
80 | try:
81 | data = response1['Datapoints']
82 | data1 = json.loads(data)
83 | except BaseException:
84 | logging.debug("no data responce: " + metricname)
85 | return metric_data
86 |
87 | if name == "acs_slb_dashboard":
88 | for record in data1:
89 | timestamp = int(record['timestamp'] / 1000)
90 | data = {"id": record['instanceId'], "ip": record['vip'], "region": region['site'], "metric": metricname,
91 | "time": timestamp, "value": record['Average']}
92 | metric_data.append(data)
93 | elif name == "acs_nat_gateway" and metricname == "SnatConnection":
94 | for record in data1:
95 | timestamp = int(record['timestamp'] / 1000)
96 | data = {"id": record['instanceId'], "ip": "", "region": region['site'], "metric": metricname,
97 | "time": timestamp, "value": record['Maximum']}
98 | metric_data.append(data)
99 | elif name == "acs_publicip":
100 | for record in data1:
101 | timestamp = int(record['timestamp'] / 1000)
102 | data = {"id": instance_id['l'], "ip": record['ip'], "region": region['site'], "metric": metricname,
103 | "time": timestamp, "value": record['value']}
104 | metric_data.append(data)
105 | elif name == "acs_oss":
106 | for record in data1:
107 | timestamp = int(record['timestamp'] / 1000)
108 | data = {"id": record['BucketName'], "ip": '', "region": region['site'], "metric": metricname,
109 | "time": timestamp, "value": record[metricname]}
110 | metric_data.append(data)
111 | else:
112 | for record in data1:
113 | timestamp = int(record['timestamp'] / 1000)
114 | data = {"id": record['instanceId'], "ip": '', "region": region['site'], "metric": metricname,
115 | "time": timestamp, "value": record['Value']}
116 | metric_data.append(data)
117 |
118 | metric_data.sort(key=lambda x: x["time"])
119 | return metric_data
120 |
121 |
122 | def get_id(resource, ak, sk, region):
123 | if resource == "ELB":
124 | return elb(ak, sk, region)
125 | elif resource == "EIP":
126 | return eip(ak, sk, region)
127 | elif resource == "NAT":
128 | return nat(ak, sk, region)
129 | elif resource == "connect":
130 | return connect(ak, sk, region)
131 | elif resource == "oss":
132 | return oss(ak, sk, region)
133 |
134 |
135 | def elb(ak, sk, region):
136 | id_list = []
137 | client = AcsClient(ak, sk, region)
138 | request = DescribeLoadBalancersRequest.DescribeLoadBalancersRequest()
139 | request.set_accept_format('json')
140 | response = client.do_action_with_exception(request)
141 | response1 = str(response)
142 | response1 = json.loads(response1)
143 | for record in response1['LoadBalancers']['LoadBalancer']:
144 | id_list.append({"l": record['LoadBalancerId'], "d": record['Address']})
145 | return id_list
146 |
147 |
148 | def eip(ak, sk, region):
149 | id_list = []
150 | client = AcsClient(ak, sk, region)
151 | request = DescribeEipAddressesRequest.DescribeEipAddressesRequest()
152 | request.set_accept_format('json')
153 | response = client.do_action_with_exception(request)
154 | response1 = str(response)
155 | response1 = json.loads(response1)
156 | id = []
157 | for record in response1['EipAddresses']['EipAddress']:
158 | id_list.append({"l": record['AllocationId'],
159 | "d": record['IpAddress'],
160 | "BandWidth": record['Bandwidth']})
161 | return id_list
162 |
163 |
164 | def nat(ak, sk, region):
165 | id_list = []
166 | client = AcsClient(ak, sk, region)
167 | request = DescribeNatGatewaysRequest.DescribeNatGatewaysRequest()
168 | request.set_accept_format('json')
169 | response = client.do_action_with_exception(request)
170 | response1 = str(response)
171 | response1 = json.loads(response1)
172 | for record in response1['NatGateways']['NatGateway']:
173 | for band in record['BandwidthPackageIds']['BandwidthPackageId']:
174 | id_list.append({"l": band, "d": record['NatGatewayId']})
175 | return id_list
176 |
177 |
178 | def connect(ak, sk, region):
179 | id_list = []
180 | client = AcsClient(ak, sk, region)
181 | request = CommonRequest()
182 | request.set_accept_format('json')
183 | request.set_domain('vpc.aliyuncs.com')
184 | request.set_method('POST')
185 | request.set_version('2016-04-28')
186 | request.set_action_name('DescribeRouterInterfaces')
187 | request.add_query_param('PageSize', '50')
188 | response = client.do_action_with_exception(request)
189 | response1 = str(response)
190 | response1 = json.loads(response1)
191 | for record in response1['RouterInterfaceSet']['RouterInterfaceType']:
192 | id_list.append({"l": record['OppositeInterfaceId'],
193 | "d": record['OppositeInterfaceId'],
194 | "BandWidth": record['Bandwidth']})
195 | return id_list
196 |
197 |
198 | def oss(ak, sk, region):
199 | id_list = []
200 | auth = oss2.Auth(ak, sk)
201 | service = oss2.Service(auth, 'http://oss-cn-hangzhou.aliyuncs.com')
202 | for b in oss2.BucketIterator(service):
203 | id_list.append({"l": "", "d": b.name})
204 | return id_list
205 |
--------------------------------------------------------------------------------
/AWS.py:
--------------------------------------------------------------------------------
1 | import boto3
2 | import datetime
3 | import time
4 | import pytz
5 | from cloud2falcon import PERIOD
6 |
7 |
8 | def get_metric_data(period, namespace, name, id_list,
9 | metricname, ak, sk, region):
10 | metric_data = []
11 | for instance_id in id_list:
12 | client = boto3.client('cloudwatch',
13 | region_name=region['name'],
14 | aws_access_key_id=ak,
15 | aws_secret_access_key=sk
16 | )
17 | response = client.get_metric_data(
18 | MetricDataQueries=[
19 | {
20 | 'Id': 'm1',
21 | 'MetricStat': {
22 | 'Metric': {
23 | 'Namespace': namespace,
24 | 'MetricName': metricname,
25 | 'Dimensions': [
26 | {
27 | 'Name': name,
28 | 'Value': instance_id['l']
29 | },
30 | ]
31 | },
32 | 'Period': period,
33 | 'Stat': 'SampleCount',
34 | 'Unit': 'Count'
35 | },
36 | 'ReturnData': True
37 | }
38 | ],
39 | StartTime=datetime.datetime.utcnow() - datetime.timedelta(minutes=PERIOD),
40 | EndTime=datetime.datetime.utcnow()
41 | )
42 | r = response['MetricDataResults'][0]
43 | for j in range(len(r['Values'])):
44 | t = r['Timestamps'][j].astimezone(pytz.timezone('Asia/Shanghai'))
45 | t = int(time.mktime(t.timetuple()))
46 | data = {"id": instance_id['l'], "ip": instance_id['d'], "region": region['site'], "metric": metricname,
47 | "time": t, "value": r['Values'][j]}
48 | metric_data.append(data)
49 |
50 | metric_data.sort(key=lambda x: x["time"])
51 | return metric_data
52 |
53 |
54 | def get_id(resource, ak, sk, region):
55 | if resource == "ELB":
56 | return elb(ak, sk, region)
57 | elif resource == "NATGateway":
58 | return nat(ak, sk, region)
59 | elif resource == "DX":
60 | return connect(ak, sk, region)
61 | elif resource == "S3":
62 | return s3(ak, sk, region)
63 |
64 |
65 | def elb(ak, sk, region):
66 | id_list = []
67 | client = boto3.client('elb',
68 | region_name=region,
69 | aws_access_key_id=ak,
70 | aws_secret_access_key=sk
71 | )
72 | response = client.describe_load_balancers()
73 | for record in response['LoadBalancerDescriptions']:
74 | id_list.append({"l": record['LoadBalancerName'], "d": record['DNSName']})
75 | return id_list
76 |
77 |
78 | def nat(ak, sk, region):
79 | id_list = []
80 | client = boto3.client('ec2',
81 | region_name=region,
82 | aws_access_key_id=ak,
83 | aws_secret_access_key=sk
84 | )
85 | response = client.describe_nat_gateways()
86 | for record in response['NatGateways']:
87 | id_list.append({"l": record['NatGatewayId'], "d": ''})
88 | return id_list
89 |
90 |
91 | def connect(ak, sk, region):
92 | id_list = []
93 | client = boto3.client('directconnect',
94 | region_name=region,
95 | aws_access_key_id=ak,
96 | aws_secret_access_key=sk
97 | )
98 | response = client.describe_connections()
99 | for record in response['connections']:
100 | id_list.append({"l": record['connectionId'], "d": record['bandwidth']})
101 | return id_list
102 |
103 |
104 | def s3(ak, sk, region):
105 | id_list = []
106 | client = boto3.client('s3',
107 | region_name=region,
108 | aws_access_key_id=ak,
109 | aws_secret_access_key=sk
110 | )
111 | response = client.list_buckets()
112 | for record in response['Buckets']:
113 | id_list.append({"l": record['Name'], "d": ''})
114 | return id_list
115 |
--------------------------------------------------------------------------------
/KSC.py:
--------------------------------------------------------------------------------
1 | from kscore.session import get_session
2 | import json
3 | import time
4 | import logging
5 | from datetime import datetime, timedelta
6 | from cloud2falcon import PERIOD
7 |
8 |
9 | def get_one_metric(namespace, region, metricname, period, id):
10 | s = get_session()
11 | client = s.create_client("monitor", region, use_ssl=True)
12 | now = datetime.now()
13 | start = datetime.now() - timedelta(minutes=PERIOD)
14 | ISOFORMAT = "%Y-%m-%dT%XZ"
15 | m = client.get_metric_statistics(
16 | InstanceID=id,
17 | Namespace=namespace,
18 | MetricName=metricname,
19 | StartTime=start.strftime(ISOFORMAT),
20 | EndTime=now.strftime(ISOFORMAT),
21 | Period='60',
22 | Aggregate='Average'
23 | )
24 | return json.dumps(m, sort_keys=True, indent=4)
25 |
26 |
27 | def get_metric_data(period, namespace, name, id_list,
28 | metricname, ak, sk, region):
29 | metric_data = []
30 | ISOFORMAT = "%Y-%m-%dT%XZ"
31 | for id in id_list:
32 | if metricname == 'BandWidth':
33 | ts = time.time()
34 | t = int(ts)
35 | v = id['BandWidth'] * 1000 * 1000
36 | data = {"id": id['l'], "ip": id['d'], "region": region['site'], "metric": metricname,
37 | "time": t, "value": v}
38 | metric_data.append(data)
39 | continue
40 | response = json.loads(
41 | get_one_metric(
42 | name,
43 | region['name'],
44 | metricname,
45 | period,
46 | id['l']))
47 | try:
48 | metric_list = response['getMetricStatisticsResult']['datapoints']['member']
49 | for metric in metric_list:
50 | ts = time.strptime(metric['timestamp'], ISOFORMAT)
51 | t = int(time.mktime(ts))
52 | data = {"id": id['l'], "ip": id['d'], "region": region['site'], "metric": metricname,
53 | "time": t, "value": metric['average']}
54 | metric_data.append(data)
55 | except BaseException:
56 | logging.error('responce from ksc error')
57 | metric_data.sort(key=lambda x: x["time"])
58 | return metric_data
59 |
60 |
61 | def get_id(resource, ak, sk, region):
62 | if resource == "elb":
63 | return elb(ak, sk, region)
64 | elif resource == "eip":
65 | return eip(ak, sk, region)
66 | elif resource == "nat":
67 | return nat(ak, sk, region)
68 | elif resource == "connect":
69 | return connect(ak, sk, region)
70 |
71 |
72 | def elb(ak, sk, region):
73 | id_list = []
74 | s = get_session()
75 | region = region
76 | eipClient = s.create_client("eip", region, use_ssl=True)
77 | allEips = eipClient.describe_addresses(
78 | **{'Filter.1.Name': 'instance-type', 'Filter.1.Value.1': 'Slb'})
79 | for item in allEips['AddressesSet']:
80 | id_list.append({"l": item['InstanceId'],
81 | "d": item['PublicIp'],
82 | "BandWidth": item['BandWidth']})
83 | return id_list
84 |
85 |
86 | def eip(ak, sk, region):
87 | id_list = []
88 | s = get_session()
89 | region = region
90 | eipClient = s.create_client("eip", region, use_ssl=True)
91 | allEips = eipClient.describe_addresses(
92 | **{'Filter.1.Name': 'instance-type', 'Filter.1.Value.1': 'Ipfwd'})
93 | for item in allEips['AddressesSet']:
94 | id_list.append({"l": item['AllocationId'],
95 | "d": item['PublicIp'],
96 | "BandWidth": item['BandWidth']})
97 | return id_list
98 |
99 |
100 | def nat(ak, sk, region):
101 | s = get_session()
102 | id_list = []
103 | region = region
104 | vpcClient = s.create_client("vpc", region, use_ssl=True)
105 | allVpcs = vpcClient.describe_nats()
106 | for item in allVpcs['NatSet']:
107 | id_list.append({"l": item['NatId'],
108 | "d": item['NatName'],
109 | "BandWidth": item['BandWidth']})
110 | return id_list
111 |
112 |
113 | def connect(ak, sk, region):
114 | s = get_session()
115 | id_list = []
116 | region = region
117 | vpcClient = s.create_client("vpc", region, use_ssl=True)
118 | allConnect = vpcClient.describe_direct_connect_gateways()
119 | for item in allConnect['DirectConnectGatewaySet']:
120 | id_list.append({"l": item['DirectConnectGatewayId'],
121 | "d": item['DirectConnectGatewayName'],
122 | "BandWidth": item['BandWidth']})
123 | return id_list
124 |
--------------------------------------------------------------------------------
/README-en.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 | The main purpose of this project is Getting public cloud monitor metric data (eg: ELB, EIP, NAT Gateway, connections, S3)
3 | to falcon. We can check the monitor metric data which can't get by monitor agent installed in the machine but avaiable on the cloud console at any time
4 |
5 | # Prerequisite
6 | * git >= 1.7.5
7 | * python2.X
8 | * develop in ubuntu16, test in centos7.3
9 |
10 |
11 | For getting KSC data, please read:
12 | https://github.com/KscSDK/ksc-sdk-python
13 |
14 | # Getting Started
15 | ```buildoutcfg
16 | 1. git clone http:https://github.com/open-falcon/cloud-mon
17 | 2. pip install -r requirements.txt
18 | 3. config your config.yml as following guide
19 | 4. run : 'python cloud2falcon.py'
20 | 5. You may encount user follow control when get lots of metric data, please connect to cloud provider solve it.
21 | ```
22 |
23 | ## Description:
24 | - It will get all metric data per minute in 10 minutes by default, change it by yourself
25 | - You can set linux cronjob for running it every 10 minutes
26 | - step and period of time according to demand and cloud user flow control. The example is my best practices
27 | - support: AWS, Alibaba cloud, kingsoft cloud
28 | - config.yml
29 |
30 | ## example:
31 |
32 | falcon_url: 'http://127.0.0.1:1988/v1/push'
33 | metric: 'cloud2falcon'
34 | step: 60
35 | period: 13
36 | cloud:
37 | - c_type: AWS
38 | resource: NATGateway
39 | name: 'NatGatewayId'
40 | to_falcon_template: 'aws-nat'
41 | ak: 'your ak'
42 | sk: 'your sk'
43 | region: [{"name": 'ap-southeast-1', "site": 'sgpaws'}]
44 | metric_list: ['ActiveConnectionCount', 'PacketsDropCount']
45 |
46 |
47 | ## adds on:
48 |
49 | | name | explanation |
50 | | ------ | ------ |
51 | |falcon_url |falcon url , set localhost url with falcon-agent installed |
52 | | metric | common config |
53 | | step | step of time |
54 | | period | period of time to get data once|
55 | | cloud |common config, required|
56 | | - c_type |cloud type(AWS, ALI, KSC)|
57 | | name | the name to get resouce instance id |
58 | | resource | resouce type, accrodding to cloud console |
59 | | to_falcon_template | the name in the templates folders files|
60 | | ak | access key |
61 | | sk | secrect key |
62 | | region | region json list。 name is console region name, site is named by yourself |
63 | | metric_list | metrics list provided by cloud provider's resouces list |
64 |
65 |
66 | ## cloud provider's resouces list
67 | - kingsoft cloud: https://docs.ksyun.com/documents/42
68 | - Alibaba cloud: https://help.aliyun.com/document_detail/28619.html?spm=a2c4g.11174283.6.672.3f5b8f4fcIKe96
69 | - AWS: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html
70 |
71 | # Architecture
72 |

73 |
74 | # Q&A
75 | Any issue or question is welcome, Please feel free to open github issues :)
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Introduction
2 | 该项目用于取出公有云的非机器级别的监控数据(ELB, EIP, NAT网关,专线,S3), 推送到falcon,有利于实时查看。
3 | 主要解决利用监控工具在机器上安装agent,取不到控制台上非机器级别的监控数据,但是大家又非常关心的一些资源类型的指标
4 |
5 |
6 | # Prerequisite
7 | * git >= 1.7.5
8 | * python2.X
9 | * 该代码在ubuntu16, centos7.3上面顺利运行没问题。其他平台没有测试,理论上只有对2.7的依赖
10 |
11 |
12 | 使用金山云的,请按照官网配置
13 | https://github.com/KscSDK/ksc-sdk-python
14 |
15 | # Getting Started
16 | ```buildoutcfg
17 | 1. git clone http:https://github.com/open-falcon/cloud-mon
18 | 2. pip install -r requirements.txt
19 | # 若还有其他的pip确实的情况,请自行手动安装
20 | 3. 编写配置文件config.yml , 编写说明见下. 代码里面的配置文件,可以之间添加上你自己的ak, sk就可以顺利运行。
21 | 4. python cloud2falcon.py 启动程序
22 | 5. 如果你们云控制台需要取的数据较多,可能遇到各家云厂商的流控问题,到时候请和各家云厂商沟通。
23 | ```
24 |
25 | ## 说明:
26 | - 代码默认跑一次取十分钟之内的数据,每分钟一个点,可以自行修改代码的配置
27 | - 定时启动可以利用linux cronjob配置每十分钟跑一次
28 | - 关于多久跑一次,每次取的时间段,和数据的颗粒度。需要自己根据需求和云厂商的流控限制来合理设置
29 | 目前例子给出的值是满足我们需求,并且经过云厂商提升流控的结果。实战推荐配置。
30 | - 目前支持的云: AWS 阿里云 金山云
31 | - 由于s3类型比较特殊,每天只有一个点的数据,代码单独在s3分支
32 | - config.yml
33 |
34 | ## example:
35 |
36 | falcon_url: 'http://127.0.0.1:1988/v1/push'
37 | metric: 'cloud2falcon'
38 | step: 60
39 | period: 13
40 | cloud:
41 | - c_type: AWS
42 | resource: NATGateway
43 | name: 'NatGatewayId'
44 | to_falcon_template: 'aws-nat'
45 | ak: 'your ak'
46 | sk: 'your sk'
47 | region: [{"name": 'ap-southeast-1', "site": 'sgpaws'}]
48 | metric_list: ['ActiveConnectionCount', 'PacketsDropCount']
49 |
50 |
51 | ## 解释:
52 |
53 | | 配置项 | 解释 |
54 | | ------ | ------ |
55 | |falcon_url |falcon地址,一般装了falcon agent, 就可以直接配置本地 |
56 | | metric | 通用配置 |
57 | | step | 每次取数的时间间隔,以秒为单位 |
58 | | period | 取当前时间多久之前的数据,分钟为单位|
59 | | cloud |通用配置, 下面的某块按照云的类型和资源类型可以随意追加|
60 | | - c_type |云类型(AWS, ALI, KSC) |
61 | | name | 获取资源id的时候的名字 |
62 | | resource | 资源类型(取决于控制台上面的名字) |
63 | | to_falcon_template | 推送到falcon时的模板(文件夹templates 下面的文件名字,可以自己定义)|
64 | | ak | 调用云资源时的ak|
65 | | sk | 调用云资源时的sk|
66 | | region | 所有的region json列表。 name是指的是控制台的region的名字, site是自己给那个区域取的名字|
67 | | metric_list | 想要取的指标列表,详细参照各家云厂商文档|
68 |
69 | ## 云厂商的资源列表
70 | - 金山云: https://docs.ksyun.com/documents/42
71 | - 阿里云: https://help.aliyun.com/document_detail/28619.html?spm=a2c4g.11174283.6.672.3f5b8f4fcIKe96
72 | - AWS: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CW_Support_For_AWS.html
73 |
74 | # Architecture
75 | 
76 |
77 | # Q&A
78 | Any issue or question is welcome, Please feel free to open github issues :)
--------------------------------------------------------------------------------
/cloud2falcon.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # -*- coding:utf-8 -*-
3 |
4 | import log
5 | import yaml
6 | import threading
7 | import jinja2
8 | import requests
9 | import json
10 | import logging
11 |
12 | from multiCloud import get_id_list, get_metric_data
13 |
14 |
15 | with open('config.yml', 'r') as ymlfile:
16 | # 考虑声明在start函数内?? 只在cloud2falcon中调用。
17 | cfg = yaml.load(ymlfile)
18 | PERIOD = cfg['period']
19 |
20 |
21 | def render_without_request(template_name, **context):
22 | """
23 | usage same as flask.render_template:
24 |
25 | render_without_request('template.html', var1='foo', var2='bar')
26 | """
27 | env = jinja2.Environment(
28 | loader=jinja2.PackageLoader('cloud2falcon', 'templates')
29 | )
30 | template = env.get_template(template_name)
31 | return template.render(**context)
32 |
33 |
34 | def send_to_falcon(json_model, template_name):
35 | payload = render_without_request(template_name, metrics=json_model)
36 | # print payload
37 | data1 = json.loads(payload)
38 | # add timeout time
39 | r = requests.post(cfg['falcon_url'], data=json.dumps(data1), timeout=3)
40 | if r.status_code != 200:
41 | logging.error("send to falcon failed", r.json())
42 |
43 |
44 | def peach_send_to_falcon(namespace, name, instance_id,
45 | metric, c_type, ak, sk, region, tempalte):
46 | metric_data = get_metric_data(
47 | cfg['step'],
48 | namespace,
49 | name,
50 | instance_id,
51 | metric,
52 | c_type,
53 | ak,
54 | sk,
55 | region)
56 | if metric_data:
57 | send_to_falcon(metric_data, tempalte)
58 |
59 |
60 | def get_metric_json(resource):
61 | sub_threads = []
62 | for region in resource['region']:
63 | instance_id = get_id_list(
64 | resource['c_type'],
65 | resource['resource'],
66 | resource['ak'],
67 | resource['sk'],
68 | region['name'])
69 | for metric in resource['metric_list']:
70 | logging.info(
71 | 'process start for ' +
72 | metric +
73 | " " +
74 | resource['c_type'])
75 | namespace = resource['c_type'] + "/" + resource['resource']
76 | t = threading.Thread(
77 | target=peach_send_to_falcon,
78 | args=(
79 | namespace,
80 | resource['name'],
81 | instance_id,
82 | metric,
83 | resource['c_type'],
84 | resource['ak'],
85 | resource['sk'],
86 | region,
87 | resource['to_falcon_template']
88 | ))
89 | sub_threads.append(t)
90 |
91 | for i in range(len(sub_threads)):
92 | sub_threads[i].setDaemon(True)
93 | sub_threads[i].start()
94 |
95 | for i in range(len(sub_threads)):
96 | sub_threads[i].join(600)
97 |
98 |
99 | if __name__ == "__main__":
100 | # 需要修改文件名,来配合falcon plugin的运行机制
101 | log.setup_logging("logging.yml")
102 | threads = []
103 | for res in cfg['cloud']:
104 | logging.info('start main process to get config')
105 | # multiple process
106 | t = threading.Thread(target=get_metric_json, args=(res, ))
107 | threads.append(t)
108 | for i in range(len(threads)):
109 | threads[i].start()
110 |
--------------------------------------------------------------------------------
/config.yml:
--------------------------------------------------------------------------------
1 | falcon_url: 'http://127.0.0.1:1988/v1/push'
2 | metric: 'cloud2falcon'
3 | step: 60
4 | period: 13
5 | cloud:
6 | - c_type: KSC
7 | resource: elb
8 | name: 'SLB'
9 | to_falcon_template: 'ksc-elb'
10 | ak: 'your access key'
11 | sk: 'your secret key'
12 | region: [{'name': 'cn-beijing-6', 'site': 'ksybj'}]
13 | metric_list: ['slb.bps.in','slb.bps.out']
14 |
15 | - c_type: KSC
16 | resource: elb
17 | name: 'SLB'
18 | to_falcon_template: 'ksc-elb-max'
19 | ak: 'your access key'
20 | sk: 'your secret key'
21 | region: [{'name': 'cn-beijing-6', 'site': 'ksybj'}]
22 | metric_list: ['BandWidth']
23 |
24 | - c_type: ALI
25 | resource: connect
26 | name: 'acs_express_connect'
27 | to_falcon_template: 'ali-connect'
28 | ak: 'your access key'
29 | sk: 'your secret key'
30 | region: [{"name": 'ap-southeast-5', "site": 'jktali'}]
31 | metric_list: ['IntranetRX','ReceiveBandwidth']
32 |
33 | - c_type: AWS
34 | resource: NATGateway
35 | name: 'NatGatewayId'
36 | to_falcon_template: 'aws-nat'
37 | ak: 'your access key'
38 | sk: 'your secret key'
39 | region: [{"name": 'ap-southeast-1', "site": 'sgpaws'}]
40 | metric_list: ['ActiveConnectionCount', 'PacketsDropCount', 'ErrorPortAllocation']
41 |
--------------------------------------------------------------------------------
/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/open-falcon/cloud-mon/1da4073a60a086d8c8552517f8d41238cc11dcdd/info.png
--------------------------------------------------------------------------------
/log.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python2
2 | # -*- coding: utf-8 -*-
3 | # by Laura 2018/05/31
4 |
5 | import yaml
6 | import logging.config
7 | import os
8 |
9 |
10 | def setup_logging(default_path="logging.yml",
11 | default_level=logging.INFO, env_key="LOG_CFG"):
12 | path = default_path
13 | value = os.getenv(env_key, None)
14 | if value:
15 | path = value
16 | if os.path.exists(path):
17 | with open(path, "r") as f:
18 | config = yaml.load(f)
19 | try:
20 | logging.config.dictConfig(config)
21 | except BaseException:
22 | os.makedirs('log/')
23 | logging.config.dictConfig(config)
24 | else:
25 | logging.basicConfig(level=default_level)
26 |
27 |
28 | def func():
29 | logging.info("start func")
30 | logging.info("exec func")
31 | logging.info("end func")
32 |
--------------------------------------------------------------------------------
/logging.yml:
--------------------------------------------------------------------------------
1 | version: 1
2 | disable_existing_loggers: False
3 | formatters:
4 | simple:
5 | format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
6 | handlers:
7 | console:
8 | class: logging.StreamHandler
9 | level: INFO
10 | formatter: simple
11 | stream: ext://sys.stdout
12 | info_file_handler:
13 | class: logging.handlers.RotatingFileHandler
14 | level: INFO
15 | formatter: simple
16 | filename: log/info.log
17 | maxBytes: 10485760
18 | backupCount: 20
19 | encoding: utf8
20 | error_file_handler:
21 | class: logging.handlers.RotatingFileHandler
22 | level: ERROR
23 | formatter: simple
24 | filename: log/errors.log
25 | maxBytes: 10485760
26 | backupCount: 20
27 | encoding: utf8
28 | loggers:
29 | my_module:
30 | level: INFO
31 | handlers: [console,info_file_handler,error_file_handler]
32 | propagate: no
33 | ## change for log level
34 | root:
35 | level: INFO
36 | handlers: [console,info_file_handler,error_file_handler]
--------------------------------------------------------------------------------
/multiCloud.py:
--------------------------------------------------------------------------------
1 | import importlib
2 |
3 |
4 | def get_id_list(c_type, resource, ak, sk, region):
5 | cloud_resource = importlib.import_module(c_type)
6 | return cloud_resource.get_id(resource, ak, sk, region)
7 |
8 |
9 | def get_metric_data(period, namespace, name, instance_id,
10 | metricname, c_type, ak, sk, region):
11 | cloud_resource = importlib.import_module(c_type)
12 | return cloud_resource.get_metric_data(
13 | period, namespace, name, instance_id, metricname, ak, sk, region)
14 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pyyaml
2 | flask
3 | requests
4 | xmljson
5 | thrift
6 | boto3
7 | pytz
8 | aliyun-python-sdk-core
9 | aliyun-python-sdk-slb
10 | httplib2
11 | aliyun-python-sdk-cms
12 | aliyun-python-sdk-vpc
13 | oss2
14 | jinja2
--------------------------------------------------------------------------------
/templates/ali-connect:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "connect-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ali-connect-max:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "connect-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}",
7 | "step": 600,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ali-eip:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "eip-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ali-eip-max:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "eip-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 600,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ali-nat:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "NAT-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, bandwidth={{ metric.ip }}, nat_id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ali-oss:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "s3-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/aws-connect:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "connect-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}, bandwith={{ metric.ip}}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/aws-lb:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "elb-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/aws-nat:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "NAT-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/aws-s3:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "s3-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, budketName={{ metric.id }}, size={{ metric.ip}}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-connect:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "connect-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}, bandwith={{ metric.ip}}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-connect-max:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "connect-{{ metric.region}}-{{ metric.id }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, id={{ metric.id }}, bandwith={{ metric.ip}}",
7 | "step": 600,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-eip:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "eip-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-eip-max:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "eip-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 600,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-elb:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "elb-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-elb-max:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "elb-{{ metric.region}}-{{ metric.ip }}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, vip={{ metric.ip }}, id={{ metric.id }}",
7 | "step": 600,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-nat:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "NAT-{{ metric.region}}-{{ metric.ip}}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, Nat_ip={{ metric.ip }}, nat_id={{ metric.id }}",
7 | "step": 60,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------
/templates/ksc-nat-max:
--------------------------------------------------------------------------------
1 | [{% for metric in metrics %}
2 | {
3 | "endpoint": "NAT-{{ metric.region}}-{{ metric.ip}}",
4 | "metric": "{{ metric.metric }}",
5 | "counterType": "GAUGE",
6 | "tags": "metric={{ metric.metric }}, Nat_ip={{ metric.ip }}, nat_id={{ metric.id }}",
7 | "step": 600,
8 | "timestamp": {{ metric.time }},
9 | "value": {{ metric.value }}
10 | }{% if not loop.last%},{% endif %}{% endfor %}
11 | ]
--------------------------------------------------------------------------------