diff --git a/README.md b/README.md index 437f78f..f8fe6d3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # 腾讯云监控 Exporter v2 +腾讯云监控已于2022年09月01日开始对超出免费额度的 API 接口的请求进行计费,需要手动开通 API 付费,详见计费说明与开通指引。 +开通页面:https://buy.cloud.tencent.com/APIRequestBuy +资源消耗页:https://console.cloud.tencent.com/monitor/consumer/products +计费文档:https://cloud.tencent.com/document/product/248/77914 + 通过qcloud exporter将云监控支持的产品监控指标自动批量导出 (`兼容v1版本`) @@ -36,6 +41,9 @@ TDMQ RocketMQ 版|QCE/TDMQ|[指标详情](https://cloud.tencent.com/document/pro VPN 网关|QCE/VPNGW|[指标详情](https://cloud.tencent.com/document/product/248/45070) VPN 通道|QCE/VPNX|[指标详情](https://cloud.tencent.com/document/product/248/45071) CYNOSDB_MYSQL|QCE/CYNOSDB_MYSQL|[指标详情](https://cloud.tencent.com/document/product/248/45106) +云联网|QCE/VBC|[指标详情](https://cloud.tencent.com/document/product/248/75629) +数据传输 |QCE/DTS|指标详情说明文档(待上线) +专线网关 |QCE/DCG|指标详情说明文档(待上线) `后续会有更多的产品支持` diff --git a/go.mod b/go.mod index be60410..75b0c4f 100644 --- a/go.mod +++ b/go.mod @@ -15,11 +15,12 @@ require ( github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/ckafka v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/clb v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cmq v1.0.334 - github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.437 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.479 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.413 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.334 + github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts v1.0.479 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/es v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/lighthouse v1.0.334 github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mariadb v1.0.334 diff --git a/go.sum b/go.sum index ac0ab7b..d15025d 100644 --- a/go.sum +++ b/go.sum @@ -211,6 +211,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/tencentcloud/tencentcloud-sdk-go v1.0.485 h1:l1xeZUO2ddcouOpxO7dhkXcmcYembuCG5EZ6O+Cox/o= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.334 h1:GijOjoDBcWXtra6hmzpj4IXOahWmsTE3bwpOcp5VBDw= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs v1.0.334/go.mod h1:PTp058qpOV//RukBVdYQT962rZg71lIt6eHLK1zdvEc= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cdb v1.0.413 h1:6cQPfHc3I1pKUj23csRd9P/xxUPcnGRLRK2e5NGqtzc= @@ -228,6 +229,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.413/go.mod github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.430/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.437 h1:Qa0q6mhOkQ/0RoAqOheJAzPFksAf3jsjOZVt4FGcvyQ= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.437/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.479 h1:3kwDb6p1J3LxmwnNgSSEheemPffo+vMewoDzKysYdig= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.479/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.334 h1:ulfSODMy8rpKa8MfnTIPbe5HyOArnlB4RJ1qmpj09to= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm v1.0.334/go.mod h1:AqyM/ZZMD7q5mHBqNY9YImbSpEpoEe7E/vrTbUWX+po= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb v1.0.413 h1:MomwSkFrSLB16s51Yu1h4JO+p3Pzc1yesIj+oNwAVM0= @@ -236,6 +239,8 @@ github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.334 h1:inkOmQwx github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc v1.0.334/go.mod h1:5WGSrlIZJOhwIqPjjafb6vzrPEZieSHPhPMjjGPXOSU= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.334 h1:Xxe889sr1FVhUPPFdZC4Z5IyJObgnGh0ELe+MJH17Mo= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb v1.0.334/go.mod h1:uvcrduqH3pPyyZoZyEX0WXlXIR554ys3ctSsKoeJp64= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts v1.0.479 h1:Tuo8zLhHaO+AxHlk7WOYGs6j/3bfD3FMNB3fWAgIxWM= +github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts v1.0.479/go.mod h1:CNPxkXeOC/vOmu9a/yaxp+2immIjDL/WsGC/H2rcWQA= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/es v1.0.334 h1:oXOMQ2EmNjqMfpShQeCrWS5QH2MwrAhJfd0rLJOxccE= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/es v1.0.334/go.mod h1:UegCt4vv9jAlzpgDu31ZJTuRP5T2BTV8w+jZBTsZIzg= github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/kms v1.0.194/go.mod h1:yrBKWhChnDqNz1xuXdSbWXG56XawEq0G5j1lg4VwBD4= diff --git a/pkg/client/client.go b/pkg/client/client.go index e2620d3..c2bc2d3 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -15,6 +15,7 @@ import ( cynosdb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cynosdb/v20190107" dc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dc/v20180410" dcdb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dcdb/v20180411" + dts "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts/v20180330" es "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/es/v20180416" lh "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/lighthouse/v20200324" mariadb "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/mariadb/v20170312" @@ -270,5 +271,16 @@ func NewCosClient(cred common.CredentialIface, conf *config.TencentConfig) (*cos Transport: common.NewCredentialTransport(cred.GetRole()), }) } + return client, nil } + +func NewDTSClient(cred common.CredentialIface, conf *config.TencentConfig) (*dts.Client, error) { + cpf := profile.NewClientProfile() + if conf.Credential.IsInternal == true { + cpf.HttpProfile.Endpoint = "dts.internal.tencentcloudapi.com" + } else { + cpf.HttpProfile.Endpoint = "dts.tencentcloudapi.com" + } + return dts.NewClient(cred, conf.Credential.Region, cpf) +} diff --git a/pkg/collector/handler_dcg.go b/pkg/collector/handler_dcg.go new file mode 100644 index 0000000..c0d645c --- /dev/null +++ b/pkg/collector/handler_dcg.go @@ -0,0 +1,55 @@ +package collector + +import ( + "github.com/go-kit/log" + "github.com/tencentyun/tencentcloud-exporter/pkg/common" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" +) + +const ( + DcgNamespace = "QCE/DCG" + DcgInstanceidKey = "directConnectGatewayId" +) + +func init() { + registerHandler(DcgNamespace, defaultHandlerEnabled, NewDcgHandler) +} + +type DcgHandler struct { + baseProductHandler +} + +func (h *DcgHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *DcgHandler) GetNamespace() string { + return DcgNamespace +} + +func (h *DcgHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func NewDcgHandler(cred common.CredentialIface, c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &tdmqHandler{ + baseProductHandler: baseProductHandler{ + monitorQueryKey: DcgInstanceidKey, + collector: c, + logger: logger, + }, + } + return + +} diff --git a/pkg/collector/handler_dts.go b/pkg/collector/handler_dts.go new file mode 100644 index 0000000..8eab6b0 --- /dev/null +++ b/pkg/collector/handler_dts.go @@ -0,0 +1,219 @@ +package collector + +import ( + "fmt" + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/tencentyun/tencentcloud-exporter/pkg/common" + "github.com/tencentyun/tencentcloud-exporter/pkg/instance" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" + "github.com/tencentyun/tencentcloud-exporter/pkg/util" +) + +const ( + DTSNamespace = "QCE/DTS" + DTSInstanceidKey = "SubscribeId" +) + +func init() { + registerHandler(DTSNamespace, defaultHandlerEnabled, NewDTSHandler) +} + +type dtsHandler struct { + baseProductHandler + // replicationRepo instance.DtsTcInstanceReplicationsRepository + migrateInfosRepo instance.DtsTcInstanceMigrateInfosRepository +} + +func (h *dtsHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *dtsHandler) GetNamespace() string { + return DTSNamespace +} + +func (h *dtsHandler) IsMetricVaild(m *metric.TcmMetric) bool { + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func (h *dtsHandler) GetSeries(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + if m.Conf.IsIncludeOnlyInstance() { + return h.GetSeriesByOnly(m) + } + + if m.Conf.IsIncludeAllInstance() { + return h.GetSeriesByAll(m) + } + + if m.Conf.IsCustomQueryDimensions() { + return h.GetSeriesByCustom(m) + } + + return nil, fmt.Errorf("must config all_instances or only_include_instances or custom_query_dimensions") +} + +func (h *dtsHandler) GetSeriesByOnly(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, insId := range m.Conf.OnlyIncludeInstances { + ins, err := h.collector.InstanceRepo.Get(insId) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "id", insId) + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *dtsHandler) GetSeriesByAll(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + insList, err := h.collector.InstanceRepo.ListByFilters(m.Conf.InstanceFilters) + if err != nil { + return nil, err + } + for _, ins := range insList { + if len(m.Conf.ExcludeInstances) != 0 && util.IsStrInList(m.Conf.ExcludeInstances, ins.GetInstanceId()) { + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *dtsHandler) GetSeriesByCustom(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, ql := range m.Conf.CustomQueryDimensions { + v, ok := ql[h.monitorQueryKey] + if !ok { + level.Error(h.logger).Log( + "msg", fmt.Sprintf("not found %s in queryDimensions", h.monitorQueryKey), + "ql", fmt.Sprintf("%v", ql)) + continue + } + ins, err := h.collector.InstanceRepo.Get(v) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "err", err, "id", v) + continue + } + + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *dtsHandler) getSeriesByMetricType(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var dimensions []string + for _, v := range m.Meta.SupportDimensions { + dimensions = append(dimensions, v) + } + if util.IsStrInList(dimensions, "replicationjobid") { + return h.getReplicationSeries(m, ins) + } else if util.IsStrInList(dimensions, "migratejobid") { + return h.getMigrateInfoSeries(m, ins) + } else { + return h.getInstanceSeries(m, ins) + } +} + +func (h *dtsHandler) getInstanceSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + + ql := map[string]string{ + h.monitorQueryKey: ins.GetMonitorQueryKey(), + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + + return series, nil +} + +func (h *dtsHandler) getReplicationSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + // replications, err := h.replicationsRepo.GetReplicationInfo() + // if err != nil { + // return nil, err + // } + // for _, replication := range replications.Response.JobList { + // ql := map[string]string{ + // "replicationjobid": *replication.JobId, + // } + // s, err := metric.NewTcmSeries(m, ql, ins) + // if err != nil { + // return nil, err + // } + // series = append(series, s) + // } + return series, nil +} +func (h *dtsHandler) getMigrateInfoSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + migrateInfos, err := h.migrateInfosRepo.GetMigrateInfosInfo() + if err != nil { + return nil, err + } + for _, migrateInfo := range migrateInfos.Response.JobList { + ql := map[string]string{ + "migratejob_id": *migrateInfo.JobId, + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + } + + return series, nil +} + +func NewDTSHandler(cred common.CredentialIface, c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + migrateInfosRepoCahe, err := instance.NewDtsTcInstanceMigrateInfosRepository(cred, c.Conf, logger) + if err != nil { + return nil, err + } + // relodInterval := time.Duration(c.ProductConf.RelodIntervalMinutes * int64(time.Minute)) + // migrateInfosRepoCahe := instance.NewDtsTcInstanceMigrateInfosCache(migrateInfoRepo, relodInterval, logger) + + handler = &dtsHandler{ + baseProductHandler: baseProductHandler{ + monitorQueryKey: DTSInstanceidKey, + collector: c, + logger: logger, + }, + migrateInfosRepo: migrateInfosRepoCahe, + } + return + +} diff --git a/pkg/collector/handler_vbc.go b/pkg/collector/handler_vbc.go new file mode 100644 index 0000000..fd9d120 --- /dev/null +++ b/pkg/collector/handler_vbc.go @@ -0,0 +1,192 @@ +package collector + +import ( + "fmt" + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/tencentyun/tencentcloud-exporter/pkg/common" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" + "github.com/tencentyun/tencentcloud-exporter/pkg/instance" + "github.com/tencentyun/tencentcloud-exporter/pkg/metric" + "github.com/tencentyun/tencentcloud-exporter/pkg/util" +) + +const ( + VbcNamespace = "QCE/VBC" + VbcInstanceidKey = "CcnId" +) + +var ( + // BetweenRegionMetricNames = []string{ + // "OutDropBandwidth", "InBandwidthRate", "OutBandwidthRate", "OutDropPkg", "OutDropPkgRate", "InBandwidth", "InPkg", "OutPkg", "OutBandwidth", + // } + SingleRegionMetricNames = []string{ + "Regioninbandwidthbm", "Regionoutbandwidthbm", "Regionoutdropbandwidthbm", "Regioninpkgbm", "Regionoutbandwidthbmrate", "Regionoutdroppkgbmrate", "Regionoutpkgbm", "Regionoutdroppkgbm", + } +) +var conf *config.TencentConfig + +func init() { + registerHandler(VbcNamespace, defaultHandlerEnabled, NewVbcHandler) +} + +type VbcHandler struct { + baseProductHandler +} + +func (h *VbcHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { + return true +} + +func (h *VbcHandler) GetNamespace() string { + return VbcNamespace +} + +func (h *VbcHandler) IsMetricVaild(m *metric.TcmMetric) bool { + + _, ok := excludeMetricName[m.Meta.MetricName] + if ok { + return false + } + p, err := m.Meta.GetPeriod(m.Conf.StatPeriodSeconds) + if err != nil { + return false + } + if p != m.Conf.StatPeriodSeconds { + return false + } + return true +} + +func (h *VbcHandler) GetSeries(m *metric.TcmMetric) (slist []*metric.TcmSeries, err error) { + + if m.Conf.IsIncludeOnlyInstance() { + return h.GetSeriesByOnly(m) + } + + if m.Conf.IsIncludeAllInstance() { + return h.GetSeriesByAll(m) + } + + if m.Conf.IsCustomQueryDimensions() { + return h.GetSeriesByCustom(m) + } + + return nil, fmt.Errorf("must config all_instances or only_include_instances or custom_query_dimensions") +} +func (h *VbcHandler) GetSeriesByOnly(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, insId := range m.Conf.OnlyIncludeInstances { + ins, err := h.collector.InstanceRepo.Get(insId) + if err != nil { + level.Error(h.logger).Log("msg", "Instance not found", "id", insId) + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *VbcHandler) GetSeriesByAll(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + insList, err := h.collector.InstanceRepo.ListByFilters(m.Conf.InstanceFilters) + if err != nil { + return nil, err + } + for _, ins := range insList { + if len(m.Conf.ExcludeInstances) != 0 && util.IsStrInList(m.Conf.ExcludeInstances, ins.GetInstanceId()) { + continue + } + sl, err := h.getSeriesByMetricType(m, ins) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", ins.GetInstanceId()) + continue + } + slist = append(slist, sl...) + } + return slist, nil +} + +func (h *VbcHandler) GetSeriesByCustom(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + for _, ql := range m.Conf.CustomQueryDimensions { + if !h.checkMonitorQueryKeys(m, ql) { + continue + } + + s, err := metric.NewTcmSeries(m, ql, nil) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", "metric", m.Meta.MetricName, + "ql", fmt.Sprintf("%v", ql)) + continue + } + slist = append(slist, s) + } + return slist, nil +} +func (h *VbcHandler) getSeriesByMetricType(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + // var dimensions []string + // for _, v := range m.Meta.SupportDimensions { + // dimensions = append(dimensions, v) + // } + // if util.IsStrInList(dimensions, "DRegion") { + // return h.getSingleRegionSeries(m, ins) + // } else { + // return h.getSingleRegionSeries(m, ins) + // } + if util.IsStrInList(SingleRegionMetricNames, m.Meta.MetricName) { + return h.getSingleRegionSeries(m, ins) + } else { + return h.getBetweenRegionSeries(m, ins) + } +} + +func (h *VbcHandler) getSingleRegionSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + ql := map[string]string{ + h.monitorQueryKey: ins.GetMonitorQueryKey(), + "SRegion": h.collector.Conf.Credential.Region, + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + + return series, nil +} + +func (h *VbcHandler) getBetweenRegionSeries(m *metric.TcmMetric, ins instance.TcInstance) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + + return series, nil +} +func (h *VbcHandler) checkMonitorQueryKeys(m *metric.TcmMetric, ql map[string]string) bool { + for k := range ql { + if !util.IsStrInList(m.Meta.SupportDimensions, k) { + level.Error(h.logger).Log("msg", fmt.Sprintf("not found %s in supportQueryDimensions", k), + "ql", fmt.Sprintf("%v", ql)) + return false + } + } + return true +} + +func NewVbcHandler(cred common.CredentialIface, c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + handler = &VbcHandler{ + baseProductHandler: baseProductHandler{ + monitorQueryKey: VbcInstanceidKey, + collector: c, + logger: logger, + }, + } + return + +} diff --git a/pkg/config/config.go b/pkg/config/config.go index a22c8af..0badafb 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -63,6 +63,9 @@ var ( "vpngw": "QCE/VPNGW", // for vpngw "vpnx": "QCE/VPNX", // for vpnx "cynosdb_mysql": "QCE/CYNOSDB_MYSQL", // for cynosdb_mysql + "dts": "QCE/DTS", // for dts + "dcg": "QCE/DCG", // for dcg + "vbc": "QCE/VBC", // for vbc } SupportStatisticsTypes = map[string]bool{ diff --git a/pkg/instance/cache.go b/pkg/instance/cache.go index 516fa16..9f5ca81 100644 --- a/pkg/instance/cache.go +++ b/pkg/instance/cache.go @@ -401,3 +401,5 @@ func NewTcNacosInstanceInterfaceCache(repo NacosTcInstanceInterfaceRepository, r } return cache } + + diff --git a/pkg/instance/instance_dcg.go b/pkg/instance/instance_dcg.go new file mode 100644 index 0000000..96fe966 --- /dev/null +++ b/pkg/instance/instance_dcg.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type DcgTcInstance struct { + baseTcInstance + meta *sdk.DirectConnectGateway +} + +func (ins *DcgTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewDcgTcInstance(instanceId string, meta *sdk.DirectConnectGateway) (ins *DcgTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &DcgTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/instance_dts.go b/pkg/instance/instance_dts.go new file mode 100644 index 0000000..bd32651 --- /dev/null +++ b/pkg/instance/instance_dts.go @@ -0,0 +1,36 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts/v20180330" +) + +type DtsTcInstance struct { + baseTcInstance + meta *sdk.SubscribeInfo + subscribeMeta *sdk.SubscribeInfo + migrateInfoMeta *sdk.MigrateJobInfo +} + +func (ins *DtsTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewDtsTcInstance(instanceId string, meta *sdk.SubscribeInfo) (ins *DtsTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &DtsTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/instance_vbc.go b/pkg/instance/instance_vbc.go new file mode 100644 index 0000000..cebf09b --- /dev/null +++ b/pkg/instance/instance_vbc.go @@ -0,0 +1,34 @@ +package instance + +import ( + "fmt" + "reflect" + + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" +) + +type VbcTcInstance struct { + baseTcInstance + meta *sdk.CCN +} + +func (ins *VbcTcInstance) GetMeta() interface{} { + return ins.meta +} + +func NewVbcTcInstance(instanceId string, meta *sdk.CCN) (ins *VbcTcInstance, err error) { + if instanceId == "" { + return nil, fmt.Errorf("instanceId is empty ") + } + if meta == nil { + return nil, fmt.Errorf("meta is empty ") + } + ins = &VbcTcInstance{ + baseTcInstance: baseTcInstance{ + instanceId: instanceId, + value: reflect.ValueOf(*meta), + }, + meta: meta, + } + return +} diff --git a/pkg/instance/repository_dcg.go b/pkg/instance/repository_dcg.go new file mode 100644 index 0000000..ddb304d --- /dev/null +++ b/pkg/instance/repository_dcg.go @@ -0,0 +1,94 @@ +package instance + +import ( + "fmt" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/common" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("QCE/DCG", NewDcgTcInstanceRepository) +} + +type DcgTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *DcgTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *DcgTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeDirectConnectGatewaysRequest() + // req.Filters.Name = []*string{&id} + resp, err := repo.client.DescribeDirectConnectGateways(req) + if err != nil { + return + } + if len(resp.Response.DirectConnectGatewaySet) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.DirectConnectGatewaySet[0] + instance, err = NewDcgTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *DcgTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *DcgTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeDirectConnectGatewaysRequest() + var offset uint64 = 0 + var limit uint64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeDirectConnectGateways(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.DirectConnectGatewaySet { + ins, e := NewDcgTcInstance(*meta.DirectConnectGatewayId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create Dcg instance fail", "id", *meta.DirectConnectGatewayId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < uint64(total) { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +func NewDcgTcInstanceRepository(cred common.CredentialIface, c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewVpvClient(cred, c) + if err != nil { + return + } + repo = &DcgTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/instance/repository_dts.go b/pkg/instance/repository_dts.go new file mode 100644 index 0000000..22c598a --- /dev/null +++ b/pkg/instance/repository_dts.go @@ -0,0 +1,159 @@ +package instance + +import ( + "fmt" + + "github.com/tencentyun/tencentcloud-exporter/pkg/config" + + selfcommon "github.com/tencentyun/tencentcloud-exporter/pkg/common" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dts/v20180330" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" +) + +func init() { + registerRepository("QCE/DTS", NewDTSTcInstanceRepository) +} + +type DTSTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *DTSTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *DTSTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeSubscribesRequest() + req.InstanceId = &id + resp, err := repo.client.DescribeSubscribes(req) + if err != nil { + return + } + if len(resp.Response.Items) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.Items[0] + instance, err = NewDtsTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *DTSTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *DTSTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeSubscribesRequest() + var offset int64 = 0 + var limit int64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeSubscribes(req) + if err != nil { + return + } + if total == -1 { + total = *resp.Response.TotalCount + } + for _, meta := range resp.Response.Items { + ins, e := NewDtsTcInstance(*meta.SubscribeId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create Dts instance fail", "id", *meta.SubscribeId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < total { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +// Replications +// type DtsTcInstanceReplicationsRepository interface { +// GetReplicationsInfo(instanceId string) (*sdk.DescribeRocketMQNamespacesResponse, error) +// } +// +// type DtsTcInstanceReplicationsRepositoryImpl struct { +// client *sdk.Client +// logger log.Logger +// } +// +// func (repo *DtsTcInstanceReplicationsRepositoryImpl) GetReplicationsInfo(instanceId string) (*sdk.DescribeRocketMQNamespacesResponse, error) { +// req := sdk.NewDescribeRocketMQNamespacesRequest() +// var offset uint64 = 0 +// var limit uint64 = 100 +// req.Limit = &limit +// req.Offset = &offset +// req.ClusterId = common.StringPtr(instanceId) +// return repo.client.DescribeRocketMQNamespaces(req) +// } +// +// func NewDtsTcInstanceReplicationsRepository(cred selfcommon.CredentialIface, c *config.TencentConfig, logger log.Logger) (TdmqTcInstanceRocketMQNameSpacesRepository, error) { +// cli, err := client.NewTDMQClient(cred, c) +// if err != nil { +// return nil, err +// } +// repo := &TdmqTcInstanceRocketMQNameSpacesRepositoryImpl{ +// client: cli, +// logger: logger, +// } +// return repo, nil +// } + +// MigrateInfos +type DtsTcInstanceMigrateInfosRepository interface { + GetMigrateInfosInfo() (*sdk.DescribeMigrateJobsResponse, error) +} + +type DtsTcInstanceMigrateInfosRepositoryImpl struct { + client *sdk.Client + logger log.Logger +} + +func (repo *DtsTcInstanceMigrateInfosRepositoryImpl) GetMigrateInfosInfo() (*sdk.DescribeMigrateJobsResponse, error) { + req := sdk.NewDescribeMigrateJobsRequest() + var offset uint64 = 0 + var limit uint64 = 100 + req.Limit = &limit + req.Offset = &offset + return repo.client.DescribeMigrateJobs(req) +} + +func NewDtsTcInstanceMigrateInfosRepository(cred selfcommon.CredentialIface, c *config.TencentConfig, logger log.Logger) (DtsTcInstanceMigrateInfosRepository, error) { + cli, err := client.NewDTSClient(cred, c) + if err != nil { + return nil, err + } + repo := &DtsTcInstanceMigrateInfosRepositoryImpl{ + client: cli, + logger: logger, + } + return repo, nil +} + +func NewDTSTcInstanceRepository(cred selfcommon.CredentialIface, c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewDTSClient(cred, c) + if err != nil { + return + } + repo = &DTSTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/instance/repository_vbc.go b/pkg/instance/repository_vbc.go new file mode 100644 index 0000000..8cf04bd --- /dev/null +++ b/pkg/instance/repository_vbc.go @@ -0,0 +1,94 @@ +package instance + +import ( + "fmt" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc/v20170312" + + "github.com/tencentyun/tencentcloud-exporter/pkg/client" + "github.com/tencentyun/tencentcloud-exporter/pkg/common" + "github.com/tencentyun/tencentcloud-exporter/pkg/config" +) + +func init() { + registerRepository("QCE/VBC", NewVbcTcInstanceRepository) +} + +type VbcTcInstanceRepository struct { + client *sdk.Client + logger log.Logger +} + +func (repo *VbcTcInstanceRepository) GetInstanceKey() string { + return "InstanceId" +} + +func (repo *VbcTcInstanceRepository) Get(id string) (instance TcInstance, err error) { + req := sdk.NewDescribeCcnsRequest() + // req. + resp, err := repo.client.DescribeCcns(req) + if err != nil { + return + } + if len(resp.Response.CcnSet) != 1 { + return nil, fmt.Errorf("Response instanceDetails size != 1, id=%s ", id) + } + meta := resp.Response.CcnSet[0] + instance, err = NewVbcTcInstance(id, meta) + if err != nil { + return + } + return +} + +func (repo *VbcTcInstanceRepository) ListByIds(id []string) (instances []TcInstance, err error) { + return +} + +func (repo *VbcTcInstanceRepository) ListByFilters(filters map[string]string) (instances []TcInstance, err error) { + req := sdk.NewDescribeCcnsRequest() + var offset uint64 = 0 + var limit uint64 = 100 + var total int64 = -1 + + req.Offset = &offset + req.Limit = &limit + +getMoreInstances: + resp, err := repo.client.DescribeCcns(req) + if err != nil { + return + } + if total == -1 { + total = int64(*resp.Response.TotalCount) + } + for _, meta := range resp.Response.CcnSet { + ins, e := NewVbcTcInstance(*meta.CcnId, meta) + if e != nil { + level.Error(repo.logger).Log("msg", "Create Vbc instance fail", "id", *meta.CcnId) + continue + } + instances = append(instances, ins) + } + offset += limit + if offset < uint64(total) { + req.Offset = &offset + goto getMoreInstances + } + + return +} + +func NewVbcTcInstanceRepository(cred common.CredentialIface, c *config.TencentConfig, logger log.Logger) (repo TcInstanceRepository, err error) { + cli, err := client.NewVpvClient(cred, c) + if err != nil { + return + } + repo = &VbcTcInstanceRepository{ + client: cli, + logger: logger, + } + return +} diff --git a/pkg/metric/metric.go b/pkg/metric/metric.go index 43b7eae..a120e4f 100644 --- a/pkg/metric/metric.go +++ b/pkg/metric/metric.go @@ -160,7 +160,6 @@ func (m *TcmMetric) GetSeriesSplitByBatch(batch int) (steps [][]*TcmSeries) { // 创建TcmMetric func NewTcmMetric(meta *TcmMeta, conf *TcmMetricConfig) (*TcmMetric, error) { id := fmt.Sprintf("%s-%s", meta.Namespace, meta.MetricName) - labels, err := NewTcmLabels(meta.SupportDimensions, conf.InstanceLabelNames, conf.ConstLabels) if err != nil { return nil, err