From 30a1716d69f01c29e1e1c1e9273daab81d18328f Mon Sep 17 00:00:00 2001 From: zianazhao Date: Mon, 19 Sep 2022 16:21:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=9F=A5=E8=AF=A2=E7=A3=81?= =?UTF-8?q?=E7=9B=98=E5=88=86=E5=8C=BA=E4=BD=BF=E7=94=A8=E7=8E=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/collector/handler_cbs.go | 182 ++++++++++++++++++++++++++++++++- pkg/instance/repository_cbs.go | 52 ++++++++++ pkg/metric/label.go | 3 + 3 files changed, 236 insertions(+), 1 deletion(-) diff --git a/pkg/collector/handler_cbs.go b/pkg/collector/handler_cbs.go index 46e6495..1114e8c 100644 --- a/pkg/collector/handler_cbs.go +++ b/pkg/collector/handler_cbs.go @@ -1,9 +1,13 @@ 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 ( @@ -17,6 +21,7 @@ func init() { type cbsHandler struct { baseProductHandler + instanceInfosRepo instance.CbsTcInstanceInfosRepository } func (h *cbsHandler) IsMetricMetaVaild(meta *metric.TcmMeta) bool { @@ -31,13 +36,188 @@ func (h *cbsHandler) IsMetricVaild(m *metric.TcmMetric) bool { return true } +func (h *cbsHandler) 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 *cbsHandler) GetSeriesByOnly(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + var dimensions []string + for _, v := range m.Meta.SupportDimensions { + dimensions = append(dimensions, v) + } + if util.IsStrInList(dimensions, "unInstanceId") { + for _, insId := range m.Conf.OnlyIncludeInstances { + cvmIds, err := h.instanceInfosRepo.Get(insId) + if err != nil || len(cvmIds) == 0 { + level.Error(h.logger).Log("msg", "Instance not found", "id", insId) + continue + } + sl, err := h.getSeriesByMetricType(m, nil, cvmIds) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne", cvmIds) + continue + } + slist = append(slist, sl...) + } + } else { + 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, nil) + 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 *cbsHandler) GetSeriesByAll(m *metric.TcmMetric) ([]*metric.TcmSeries, error) { + var slist []*metric.TcmSeries + var dimensions []string + for _, v := range m.Meta.SupportDimensions { + dimensions = append(dimensions, v) + } + if util.IsStrInList(dimensions, "unInstanceId") { + sl, err := h.getSeriesByMetricType(m, nil, nil) + if err != nil { + level.Error(h.logger).Log("msg", "Create metric series fail", + "metric", m.Meta.MetricName, "instacne") + } + slist = append(slist, sl...) + } else { + insList, err := h.collector.InstanceRepo.ListByFilters(m.Conf.InstanceFilters) + // cvmIds, err := h.instanceInfosRepo.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, nil) + 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 *cbsHandler) 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, nil) + 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 *cbsHandler) getSeriesByMetricType(m *metric.TcmMetric, ins instance.TcInstance, ids []string) ([]*metric.TcmSeries, error) { + var dimensions []string + for _, v := range m.Meta.SupportDimensions { + dimensions = append(dimensions, v) + } + if util.IsStrInList(dimensions, "unInstanceId") { + return h.getInstanceSeries(m, ins, ids) + } else { + return h.getCbsSeries(m, ins) + } +} + +func (h *cbsHandler) getCbsSeries(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 *cbsHandler) getInstanceSeries(m *metric.TcmMetric, ins instance.TcInstance, ids []string) ([]*metric.TcmSeries, error) { + var series []*metric.TcmSeries + instanceInfos, err := h.instanceInfosRepo.GetInstanceInfosInfoByFilters(ids) + if err != nil { + return nil, err + } + for _, instanceInfo := range instanceInfos.Response.InstanceSet { + + ql := map[string]string{ + "InstanceId": *instanceInfo.InstanceId, + } + s, err := metric.NewTcmSeries(m, ql, ins) + if err != nil { + return nil, err + } + series = append(series, s) + } + + return series, nil +} + func NewCbsHandler(cred common.CredentialIface, c *TcProductCollector, logger log.Logger) (handler ProductHandler, err error) { + instanceInfosRepoCahe, err := instance.NewCbsTcInstanceInfosRepository(cred, c.Conf, logger) + if err != nil { + return nil, err + } + handler = &cbsHandler{ - baseProductHandler{ + baseProductHandler: baseProductHandler{ monitorQueryKey: CbsInstanceidKey, collector: c, logger: logger, }, + instanceInfosRepo: instanceInfosRepoCahe, } return diff --git a/pkg/instance/repository_cbs.go b/pkg/instance/repository_cbs.go index e427e0b..3904629 100644 --- a/pkg/instance/repository_cbs.go +++ b/pkg/instance/repository_cbs.go @@ -6,6 +6,7 @@ import ( "github.com/go-kit/log" "github.com/go-kit/log/level" sdk "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cbs/v20170312" + cvm "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/cvm/v20170312" "github.com/tencentyun/tencentcloud-exporter/pkg/client" "github.com/tencentyun/tencentcloud-exporter/pkg/common" "github.com/tencentyun/tencentcloud-exporter/pkg/config" @@ -94,3 +95,54 @@ func NewCbsTcInstanceRepository(cred common.CredentialIface, c *config.TencentCo } return } + +// cvm instance +type CbsTcInstanceInfosRepository interface { + Get(id string) ([]string, error) + GetInstanceInfosInfoByFilters([]string) (*cvm.DescribeInstancesResponse, error) +} + +type CbsTcInstanceInfosRepositoryImpl struct { + client *cvm.Client + logger log.Logger +} + +func (repo *CbsTcInstanceInfosRepositoryImpl) Get(id string) (instanceIds []string, err error) { + req := cvm.NewDescribeInstancesRequest() + req.InstanceIds = []*string{&id} + resp, err := repo.client.DescribeInstances(req) + if err != nil { + return + } + for _, instanceInfo := range resp.Response.InstanceSet { + instanceIds = append(instanceIds, *instanceInfo.InstanceId) + } + return +} + +func (repo *CbsTcInstanceInfosRepositoryImpl) GetInstanceInfosInfoByFilters(ids []string) (instances *cvm.DescribeInstancesResponse, err error) { + req := cvm.NewDescribeInstancesRequest() + var offset int64 = 0 + var limit int64 = 100 + + req.Offset = &offset + req.Limit = &limit + if ids!=nil{ + for _, id := range ids { + req.InstanceIds = []*string{&id} + } + } + return repo.client.DescribeInstances(req) +} + +func NewCbsTcInstanceInfosRepository(cred common.CredentialIface, c *config.TencentConfig, logger log.Logger) (CbsTcInstanceInfosRepository, error) { + cli, err := client.NewCvmClient(cred, c) + if err != nil { + return nil, err + } + repo := &CbsTcInstanceInfosRepositoryImpl{ + client: cli, + logger: logger, + } + return repo, nil +} diff --git a/pkg/metric/label.go b/pkg/metric/label.go index bb0926f..7b99ebc 100644 --- a/pkg/metric/label.go +++ b/pkg/metric/label.go @@ -44,6 +44,9 @@ func (l *TcmLabels) GetValues(filters map[string]string, ins instance.TcInstance } } for _, name := range l.instanceLabelNames { + if ins == nil { + continue + } vMap, e := ins.GetFieldValuesByName(name) if e == nil && vMap != nil { for vName, values := range vMap {