redis接入完成。

pull/46/head
starsliao 2022-11-25 03:09:57 +08:00
parent 40c4e86364
commit 0ca6fa764e
21 changed files with 105 additions and 40 deletions

View File

@ -24,9 +24,10 @@ alibabacloud_rds20140815==2.1.2
alibabacloud_r_kvstore20150101==2.20.7
alibabacloud_bssopenapi20171214==2.0.6
aliyun-python-sdk-cms==7.0.32
tencentcloud-sdk-python-common==3.0.770
tencentcloud-sdk-python-cvm==3.0.770
tencentcloud-sdk-python-cdb==3.0.770
tencentcloud-sdk-python-dcdb==3.0.770
tencentcloud-sdk-python-billing==3.0.770
tencentcloud-sdk-python-monitor==3.0.770
tencentcloud-sdk-python-common==3.0.779
tencentcloud-sdk-python-cvm==3.0.779
tencentcloud-sdk-python-cdb==3.0.779
tencentcloud-sdk-python-dcdb==3.0.779
tencentcloud-sdk-python-billing==3.0.779
tencentcloud-sdk-python-monitor==3.0.779
tencentcloud-sdk-python-redis==3.0.779

View File

@ -25,7 +25,7 @@ def w2consul(vendor,account,region,rds_dict):
for k,v in rds_dict.items():
iid = k
#对consul中关机的rds做标记。
if v['status'] in ['SHUTDOWN']:
if v['status'] in ['SHUTDOWN','非运行中']:
off = off + 1
tags = ['OFF',v['itype'],v['ver'], region]
stat = 'off'

View File

@ -25,7 +25,7 @@ def w2consul(vendor,account,region,redis_dict):
for k,v in redis_dict.items():
iid = k
#对consul中关机的redis做标记。
if v['status'] in ['SHUTDOWN','Unavailable','Inactive','Released']:
if v['status'] in ['SHUTDOWN','Unavailable','Inactive','Released','非运行中']:
off = off + 1
tags = ['OFF', v['itype'], v['ver'], region]
stat = 'off'

View File

@ -10,6 +10,7 @@ import sys,datetime,hashlib
from units import consul_kv
from units.cloud import sync_ecs
from units.cloud import sync_rds
from units.cloud import sync_redis
from units.cloud import notify
def exp(account,collect_days,notify_days,notify_amount):
@ -214,3 +215,52 @@ def rds(account,region):
except Exception as e:
data = {'count':'','update':f'失败','status':50000,'msg':str(e)}
consul_kv.put_kv(f'ConsulManager/record/jobs/tencent_cloud/{account}/rds/{region}', data)
def redis(account,region):
from tencentcloud.redis.v20180412 import redis_client, models
ak,sk = consul_kv.get_aksk('tencent_cloud',account)
now = datetime.datetime.now().strftime('%m.%d/%H:%M')
group_dict = consul_kv.get_value(f'ConsulManager/assets/tencent_cloud/group/{account}')
try:
cred = credential.Credential(ak, sk)
httpProfile = HttpProfile()
httpProfile.endpoint = "redis.tencentcloudapi.com"
clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = redis_client.RedisClient(cred, region, clientProfile)
req = models.DescribeInstancesRequest()
params = {"Limit": 1000}
req.from_json_string(json.dumps(params))
resp = client.DescribeInstances(req)
redis_list = resp.InstanceSet
total = resp.TotalCount
redis_dict = {i.InstanceId:{'name':i.InstanceName,
'domain':i.WanIp,
'ip':i.WanIp,
'port':i.Port,
'region':region,
'group':group_dict.get(str(i.ProjectId),''),
'status': '运行中' if i.Status == 2 else '非运行中',
'itype':{6:'主从',7:'集群',8:'主从',9:'集群'}.get(i.Type,i.Type),
'ver':i.CurrentRedisVersion,
'exp': '按量' if i.DeadlineTime == "0000-00-00 00:00:00" else i.DeadlineTime.split(' ')[0],
'mem':f"{i.Size}MB",
} for i in redis_list}
count = len(redis_dict)
off,on = sync_redis.w2consul('tencent_cloud',account,region,redis_dict)
data = {'count':count,'update':now,'status':20000,'on':on,'off':off,'msg':f'redis同步成功总数{count},开机:{on},关机:{off}'}
consul_kv.put_kv(f'ConsulManager/record/jobs/tencent_cloud/{account}/redis/{region}', data)
print('【JOB】===>', 'tencent_cloud_redis', account,region, data, flush=True)
except TencentCloudSDKException as err:
print(err, flush=True)
data = consul_kv.get_value(f'ConsulManager/record/jobs/tencent_cloud/{account}/redis/{region}')
if data == {}:
data = {'count':'','update':f'失败','status':50000,'msg':str(err)}
else:
data['update'] = f'失败'
data['msg'] = str(err)
consul_kv.put_kv(f'ConsulManager/record/jobs/tencent_cloud/{account}/redis/{region}', data)
except Exception as e:
data = {'count':'','update':f'失败','status':50000,'msg':str(e)}
consul_kv.put_kv(f'ConsulManager/record/jobs/tencent_cloud/{account}/redis/{region}', data)

View File

@ -81,7 +81,7 @@ def get_services_meta(services_name):
return {'code': 50000, 'data': f'{response.status_code}:{response.text}'}
def get_services_list_by_region(services_name,region):
region = f'and "{region}" in Tags'
region = f'and "{region}" in Tags and "ON" in Tags'
url = f'{consul_url}/agent/services?filter=Service == "{services_name}" {region}'
response = requests.get(url, headers=headers)
if response.status_code == 200:

View File

@ -27,17 +27,20 @@ def exporter(vendor,account,region):
for i in metric_name_dict.keys():
for rediss in redis_list_10:
starttime = (datetime.now() + timedelta(minutes=-1)).strftime('%Y-%m-%dT%H:%M:%S+08:00')
ins_list = [{"Dimensions":[{"Name":"InstanceId","Value":x}]} for x in rediss]
ins_list = [{"Dimensions":[{"Name":"instanceid","Value":x}]} for x in rediss]
params = {"Namespace":"QCE/REDIS_MEM","MetricName":i,"Period":60,"StartTime":starttime,"Instances":ins_list}
req.from_json_string(json.dumps(params))
resp = client.GetMonitorData(req)
metric_list = resp.DataPoints
for metrics in metric_list:
iid = metrics.Dimensions[0].Value
value = metrics.Values[-1]
ts = metrics.Timestamps[-1]*1000
prom_metric_name = metric_name_dict[i][0].split()[2]
metric_name_dict[i].append(f'{prom_metric_name}{{iid="{iid}"}} {float(value)} {ts}')
try:
iid = metrics.Dimensions[0].Value
value = metrics.Values[-1]
ts = metrics.Timestamps[-1]*1000
prom_metric_name = metric_name_dict[i][0].split()[2]
metric_name_dict[i].append(f'{prom_metric_name}{{iid="{iid}"}} {float(value)} {ts}')
except Exception as e:
print("【redis_tencentprom-metrics-ERROR】",str(e),flush=True)
prom_metric_list = []
for x in metric_name_dict.values():
prom_metric_list = prom_metric_list + x

View File

@ -2,7 +2,7 @@ from flask import Blueprint,Response
from flask_restful import reqparse, Resource, Api
from config import vendors,regions
from units import token_auth,consul_kv
from units.prom import mysql_huawei,mysql_ali,mysql_tencent,redis_huawei,redis_ali
from units.prom import mysql_huawei,mysql_ali,mysql_tencent,redis_huawei,redis_ali,redis_tencent
import json
blueprint = Blueprint('cloud_metrics',__name__)
api = Api(blueprint)
@ -23,8 +23,8 @@ class RedisExporter(Resource):
prom_metric_list = redis_huawei.exporter(vendor,account,region)
elif vendor == 'alicloud':
prom_metric_list = redis_ali.exporter(vendor,account,region)
#elif vendor == 'tencent_cloud':
#prom_metric_list = mysql_tencent.exporter(vendor,account,region)
elif vendor == 'tencent_cloud':
prom_metric_list = redis_tencent.exporter(vendor,account,region)
return Response('\n'.join(prom_metric_list).encode('utf-8'),mimetype="text/plain")
api.add_resource(RdsExporter, '/api/cloud_mysql_metrics/<vendor>/<account>/<region>')
api.add_resource(RedisExporter, '/api/cloud_redis_metrics/<vendor>/<account>/<region>')

View File

@ -46,7 +46,7 @@ Object.keys(filters).forEach(key => {
})
Vue.config.productionTip = false
Vue.prototype.VER = 'v0.11.0-alpha'
Vue.prototype.VER = 'v0.11.0'
new Vue({
el: '#app',

View File

@ -16,7 +16,7 @@
<el-select v-model="listQuery.env" filterable placeholder="环境" clearable style="width: 120px" class="filter-item">
<el-option v-for="item in env_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="点击清空查询条件" placement="top">
<el-tooltip effect="light" content="点击清空查询条件" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="handleReset" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">
@ -37,7 +37,7 @@
:show-file-list="false"
:multiple="false"
>
<el-tooltip class="item" effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-tooltip effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-button v-waves style="margin-left: 10px;margin-top: 0px;" :loading="downloadLoading" class="filter-item" type="warning" icon="el-icon-upload2">
导入
</el-button>

View File

@ -5,7 +5,7 @@
<el-select v-model="services_name" placeholder="请选择 Services" filterable collapse-tags style="width: 250px" class="filter-item" @change="fetchData(services_name)">
<el-option v-for="item in services_name_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="刷新当前Services" placement="top">
<el-tooltip effect="light" content="刷新当前Services" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="fetchData(services_name)" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">

View File

@ -41,20 +41,20 @@
</el-table-column>
<el-table-column prop="ChecksPassing" label="健康实例" sortable align="center" width="120">
<template slot-scope="{row}">
<el-tooltip class="item" effect="dark" content="健康检查成功的实例数" placement="top">
<el-tooltip effect="dark" content="健康检查成功的实例数" placement="top">
<el-button size="mini" type="success" icon="el-icon-check" circle>{{ row.ChecksPassing - 1 }}</el-button>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="ChecksCritical" label="实例状态" sortable align="center" width="120">
<template slot-scope="{row}">
<el-tooltip v-if="row.ChecksCritical != 0" class="item" effect="dark" content="健康检查失败的实例数" placement="top">
<el-tooltip v-if="row.ChecksCritical != 0" effect="dark" content="健康检查失败的实例数" placement="top">
<el-button size="mini" type="danger" icon="el-icon-close" circle>{{ row.ChecksCritical }}</el-button>
</el-tooltip>
<el-tooltip v-else-if="row.ChecksPassing == 1" class="item" effect="dark" content="所有实例都没有配置健康检查" placement="top">
<el-tooltip v-else-if="row.ChecksPassing == 1" effect="dark" content="所有实例都没有配置健康检查" placement="top">
<el-button size="mini" type="info" icon="el-icon-minus" circle />
</el-tooltip>
<el-tooltip v-else class="item" effect="dark" content="已配置的健康检查都通过" placement="top">
<el-tooltip v-else effect="dark" content="已配置的健康检查都通过" placement="top">
<el-button size="mini" type="success" icon="el-icon-check" circle />
</el-tooltip>
</template>

View File

@ -4,6 +4,17 @@
<el-link :underline="false" type="primary" icon="el-icon-star-on" href="https://github.com/starsliao/ConsulManager" target="_blank" class="dashboard-text">StarsL.cn</el-link>
</el-badge>
<el-timeline>
<el-timeline-item timestamp="2022/11/25" placement="top">
<el-card>
<h4>v0.11.0</h4>
<p><el-button type="primary" size="mini" icon="el-icon-star-off" circle />新增Redis监控接入支持同步华为云阿里云腾讯云的Redis信息到Consul并接入到Prometheus监控(支持自定义IP端口)</p>
<p><el-button type="warning" size="mini" icon="el-icon-star-off" circle />新增自建Redis管理界面支持增删改查批量导入导出自动同步到Consul并接入到Prometheus监控</p>
<p><el-button type="success" size="mini" icon="el-icon-star-off" circle />新增由于Redis_Exporter无法监控到云REDIS的CPU内存等信息的使用情况<strong>所以ConsulManager开发了Exporter功能配置到Prometheus即可直接从云厂商采集到这些指标</strong>直接在Prometheus配置菜单即可生成配置</p>
<p>新增从Consul同步RDS到Prometheus的配置生成界面可生成Prometheus的配置</p>
<p>优化了开关机资源写入consul的标签及Prometheus同步的逻辑您需要重新生成ECS的Prometheus配置</p>
<p>修复导入按钮上移的BUG</p>
</el-card>
</el-timeline-item>
<el-timeline-item timestamp="2022/11/18" placement="top">
<el-card>
<h4>v0.10.2</h4>

View File

@ -9,7 +9,7 @@
<el-select v-model="query.account" placeholder="账户" clearable style="width: 150px" class="filter-item" @change="fetchData(query)">
<el-option v-for="item in account_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="查询所有" placement="top">
<el-tooltip effect="light" content="查询所有" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="success" icon="el-icon-magic-stick" circle @click="resetData" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">JumpServer</el-button>

View File

@ -7,11 +7,11 @@
<el-select v-model="query.account" placeholder="账户" clearable style="width: 150px" class="filter-item" @change="fetchData(query)">
<el-option v-for="item in account_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="查询所有" placement="top">
<el-tooltip effect="light" content="查询所有" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="success" icon="el-icon-magic-stick" circle @click="resetData" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate"></el-button>
<el-tooltip class="item" effect="light" content="根据菜单选择查询对应账户余额,菜单为空时,查询所有账户。" placement="top">
<el-tooltip effect="light" content="根据菜单选择查询对应账户余额,菜单为空时,查询所有账户。" placement="top">
<el-button class="filter-item" type="warning" icon="el-icon-data-line" @click="handleamount"></el-button>
</el-tooltip>
<el-dialog title="配置余额与到期通知" :visible.sync="dialogFormVisible" width="45%">

View File

@ -14,7 +14,7 @@
<el-option v-for="item in itype_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="清空查询条件" placement="top">
<el-tooltip effect="light" content="清空查询条件" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="info" icon="el-icon-delete" circle @click="resetData" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-s-promotion" @click="handleCreate">
@ -24,7 +24,7 @@
编辑云资源
</el-button>
<div style="float: right;">
<el-tooltip class="item" effect="light" content="刷新当前页面" placement="top">
<el-tooltip effect="light" content="刷新当前页面" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="fetchData" />
</el-tooltip>
</div>

View File

@ -4,7 +4,7 @@
<el-option v-for="item in jobecs_list" :key="item" :label="item" :value="item" />
</el-select>
<el-checkbox v-model="checked" style="margin-left: 10px;" label="仅显示修改过的" border @change="cstEcsList(jobecs_name,checked)" />
<el-tooltip class="item" effect="light" content="刷新当前ECS列表" placement="top">
<el-tooltip effect="light" content="刷新当前ECS列表" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="fetchEcs(jobecs_name)" />
</el-tooltip>
<div style="float: right;margin-left: 10px;">

View File

@ -13,7 +13,7 @@
<el-select v-model="listQuery.group" filterable placeholder="分组/环境" clearable style="width: 120px" class="filter-item">
<el-option v-for="item in group_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="点击清空查询条件" placement="top">
<el-tooltip effect="light" content="点击清空查询条件" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="handleReset" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">
@ -34,7 +34,7 @@
:show-file-list="false"
:multiple="false"
>
<el-tooltip class="item" effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-tooltip effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-button v-waves style="margin-left: 9px;margin-top: 0px;" :loading="downloadLoading" class="filter-item" type="warning" icon="el-icon-upload2">
导入
</el-button>

View File

@ -4,7 +4,7 @@
<el-option v-for="item in jobrds_list" :key="item" :label="item" :value="item" />
</el-select>
<el-checkbox v-model="checked" style="margin-left: 10px;" label="仅显示修改过的" border @change="cstRdsList(jobrds_name,checked)" />
<el-tooltip class="item" effect="light" content="刷新当前RDS列表" placement="top">
<el-tooltip effect="light" content="刷新当前RDS列表" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="fetchEcs(jobrds_name)" />
</el-tooltip>
<div style="float: right;margin-left: 10px;">

View File

@ -13,7 +13,7 @@
<el-select v-model="listQuery.group" filterable placeholder="分组/环境" clearable style="width: 120px" class="filter-item">
<el-option v-for="item in group_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="点击清空查询条件" placement="top">
<el-tooltip effect="light" content="点击清空查询条件" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="handleReset" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">
@ -34,7 +34,7 @@
:show-file-list="false"
:multiple="false"
>
<el-tooltip class="item" effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-tooltip effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-button v-waves style="margin-left: 9px;margin-top: 0px;" :loading="downloadLoading" class="filter-item" type="warning" icon="el-icon-upload2">
导入
</el-button>

View File

@ -4,7 +4,7 @@
<el-option v-for="item in jobredis_list" :key="item" :label="item" :value="item" />
</el-select>
<el-checkbox v-model="checked" style="margin-left: 10px;" label="仅显示修改过的" border @change="cstRedisList(jobredis_name,checked)" />
<el-tooltip class="item" effect="light" content="刷新当前REDIS列表" placement="top">
<el-tooltip effect="light" content="刷新当前REDIS列表" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="fetchEcs(jobredis_name)" />
</el-tooltip>
<div style="float: right;margin-left: 10px;">

View File

@ -13,7 +13,7 @@
<el-select v-model="listQuery.group" filterable placeholder="分组/环境" clearable style="width: 120px" class="filter-item">
<el-option v-for="item in group_list" :key="item" :label="item" :value="item" />
</el-select>
<el-tooltip class="item" effect="light" content="点击清空查询条件" placement="top">
<el-tooltip effect="light" content="点击清空查询条件" placement="top">
<el-button class="filter-item" style="margin-left: 10px;" type="primary" icon="el-icon-refresh" circle @click="handleReset" />
</el-tooltip>
<el-button class="filter-item" type="primary" icon="el-icon-edit" @click="handleCreate">
@ -34,7 +34,7 @@
:show-file-list="false"
:multiple="false"
>
<el-tooltip class="item" effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-tooltip effect="light" content="点击【导出】可获取导入模板" placement="top">
<el-button v-waves style="margin-left: 9px;margin-top: 0px;" :loading="downloadLoading" class="filter-item" type="warning" icon="el-icon-upload2">
导入
</el-button>