yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/huawei/monitor.go (about)

     1  // Copyright 2019 Yunion
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package huawei
    16  
    17  import (
    18  	"fmt"
    19  	"time"
    20  
    21  	"yunion.io/x/log"
    22  	"yunion.io/x/pkg/errors"
    23  
    24  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    25  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    26  	"yunion.io/x/cloudmux/pkg/multicloud/huawei/client/modules"
    27  )
    28  
    29  func (r *SRegion) GetMetrics() ([]modules.SMetricMeta, error) {
    30  	return r.ecsClient.CloudEye.ListMetrics()
    31  }
    32  
    33  func (r *SRegion) GetMetricsData(metrics []modules.SMetricMeta, since time.Time, until time.Time) ([]modules.SMetricData, error) {
    34  	return r.ecsClient.CloudEye.GetMetricsData(metrics, since, until)
    35  }
    36  
    37  type MetricData struct {
    38  	Namespace  string
    39  	MetricName string
    40  	Dimensions []struct {
    41  		Name  string
    42  		Value string
    43  	}
    44  	Datapoints []struct {
    45  		Average   float64
    46  		Timestamp int64
    47  	}
    48  	Unit string
    49  }
    50  
    51  func (self *SHuaweiClient) getServerMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
    52  	params := map[string]interface{}{
    53  		"from":   fmt.Sprintf("%d", opts.StartTime.UnixMilli()),
    54  		"to":     fmt.Sprintf("%d", opts.EndTime.UnixMilli()),
    55  		"period": "1",
    56  		"filter": "average",
    57  	}
    58  	metrics := []interface{}{}
    59  	namespace, dimesionName, metricNames := "SYS.ECS", "instance_id", []string{
    60  		"cpu_util",
    61  		"network_incoming_bytes_aggregate_rate",
    62  		"network_outgoing_bytes_aggregate_rate",
    63  		"disk_read_bytes_rate",
    64  		"disk_write_bytes_rate",
    65  		"disk_read_requests_rate",
    66  		"disk_write_requests_rate",
    67  	}
    68  	for _, metricName := range metricNames {
    69  		metrics = append(metrics, map[string]interface{}{
    70  			"namespace":   namespace,
    71  			"metric_name": metricName,
    72  			"dimensions": []map[string]string{
    73  				{
    74  					"name":  dimesionName,
    75  					"value": opts.ResourceId,
    76  				},
    77  			},
    78  		})
    79  	}
    80  	params["metrics"] = metrics
    81  	resp, err := self.monitorPost("batch-query-metric-data", params)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	metricData := []MetricData{}
    86  	err = resp.Unmarshal(&metricData, "metrics")
    87  	if err != nil {
    88  		return nil, errors.Wrapf(err, "resp.Unmarshal")
    89  	}
    90  	result := []cloudprovider.MetricValues{}
    91  	for i := range metricData {
    92  		ret := cloudprovider.MetricValues{
    93  			Id:     opts.ResourceId,
    94  			Unit:   metricData[i].Unit,
    95  			Values: []cloudprovider.MetricValue{},
    96  		}
    97  		tags := map[string]string{}
    98  		switch metricData[i].MetricName {
    99  		case "cpu_util":
   100  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_CPU_USAGE
   101  		case "network_incoming_bytes_aggregate_rate":
   102  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_NET_BPS_RX
   103  			tags = map[string]string{"net_type": "internet"}
   104  		case "network_outgoing_bytes_aggregate_rate":
   105  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_NET_BPS_TX
   106  			tags = map[string]string{"net_type": "internet"}
   107  		case "disk_read_bytes_rate":
   108  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_BPS
   109  		case "disk_write_bytes_rate":
   110  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_DISK_IO_WRITE_BPS
   111  		case "disk_read_requests_rate":
   112  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_IOPS
   113  		case "disk_write_requests_rate":
   114  			ret.MetricType = cloudprovider.VM_METRIC_TYPE_DISK_IO_WRITE_IOPS
   115  		default:
   116  			log.Warningf("invalid metricName %s for %s %s", metricData[i].MetricName, opts.ResourceType, opts.ResourceId)
   117  			continue
   118  		}
   119  		for _, value := range metricData[i].Datapoints {
   120  			metricValue := cloudprovider.MetricValue{
   121  				Value:     value.Average,
   122  				Timestamp: time.UnixMilli(value.Timestamp),
   123  				Tags:      tags,
   124  			}
   125  			ret.Values = append(ret.Values, metricValue)
   126  		}
   127  		result = append(result, ret)
   128  	}
   129  	return result, nil
   130  }
   131  
   132  func (self *SHuaweiClient) getRedisMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   133  	params := map[string]interface{}{
   134  		"from":   fmt.Sprintf("%d", opts.StartTime.UnixMilli()),
   135  		"to":     fmt.Sprintf("%d", opts.EndTime.UnixMilli()),
   136  		"period": "1",
   137  		"filter": "average",
   138  	}
   139  	metrics := []interface{}{}
   140  	namespace, dimesionName, metricNames := "SYS.DCS", "dcs_instance_id", []string{
   141  		"cpu_usage",
   142  		"memory_usage",
   143  		"instantaneous_input_kbps",
   144  		"instantaneous_output_kbps",
   145  		"connected_clients",
   146  		"instantaneous_ops",
   147  		"keys",
   148  		"expires",
   149  		"used_memory_dataset",
   150  	}
   151  	for _, metricName := range metricNames {
   152  		metrics = append(metrics, map[string]interface{}{
   153  			"namespace":   namespace,
   154  			"metric_name": metricName,
   155  			"dimensions": []map[string]string{
   156  				{
   157  					"name":  dimesionName,
   158  					"value": opts.ResourceId,
   159  				},
   160  			},
   161  		})
   162  	}
   163  	params["metrics"] = metrics
   164  	resp, err := self.monitorPost("batch-query-metric-data", params)
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	metricData := []MetricData{}
   169  	err = resp.Unmarshal(&metricData, "metrics")
   170  	if err != nil {
   171  		return nil, errors.Wrapf(err, "resp.Unmarshal")
   172  	}
   173  	result := []cloudprovider.MetricValues{}
   174  	for i := range metricData {
   175  		ret := cloudprovider.MetricValues{
   176  			Id:     opts.ResourceId,
   177  			Unit:   metricData[i].Unit,
   178  			Values: []cloudprovider.MetricValue{},
   179  		}
   180  		tags := map[string]string{}
   181  		switch metricData[i].MetricName {
   182  		case "cpu_usage":
   183  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_CPU_USAGE
   184  		case "memory_usage":
   185  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_MEM_USAGE
   186  		case "instantaneous_input_kbps":
   187  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_NET_BPS_RX
   188  		case "instantaneous_output_kbps":
   189  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_NET_BPS_TX
   190  		case "connected_clients":
   191  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_USED_CONN
   192  		case "instantaneous_ops":
   193  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_OPT_SES
   194  		case "keys":
   195  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_CACHE_KEYS
   196  		case "expires":
   197  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_CACHE_EXP_KEYS
   198  		case "used_memory_dataset":
   199  			ret.MetricType = cloudprovider.REDIS_METRIC_TYPE_DATA_MEM_USAGE
   200  		default:
   201  			log.Warningf("invalid metricName %s for %s %s", metricData[i].MetricName, opts.ResourceType, opts.ResourceId)
   202  			continue
   203  		}
   204  		for _, value := range metricData[i].Datapoints {
   205  			metricValue := cloudprovider.MetricValue{
   206  				Value:     value.Average,
   207  				Timestamp: time.UnixMilli(value.Timestamp),
   208  				Tags:      tags,
   209  			}
   210  			ret.Values = append(ret.Values, metricValue)
   211  		}
   212  		result = append(result, ret)
   213  	}
   214  	return result, nil
   215  }
   216  
   217  func (self *SHuaweiClient) getRdsMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   218  	params := map[string]interface{}{
   219  		"from":   fmt.Sprintf("%d", opts.StartTime.UnixMilli()),
   220  		"to":     fmt.Sprintf("%d", opts.EndTime.UnixMilli()),
   221  		"period": "1",
   222  		"filter": "average",
   223  	}
   224  	metrics := []interface{}{}
   225  	namespace, dimesionName, metricNames := "SYS.RDS", "rds_cluster_id", []string{
   226  		"rds001_cpu_util",
   227  		"rds002_mem_util",
   228  		"rds004_bytes_in",
   229  		"rds004_bytes_in",
   230  		"rds005_bytes_out",
   231  		"rds039_disk_util",
   232  		"rds049_disk_read_throughput",
   233  		"rds050_disk_write_throughput",
   234  		"rds006_conn_count",
   235  		"rds008_qps",
   236  		"rds009_tps",
   237  		"rds013_innodb_reads",
   238  		"rds014_innodb_writes",
   239  	}
   240  	switch opts.Engine {
   241  	case api.DBINSTANCE_TYPE_POSTGRESQL:
   242  		dimesionName = "postgresql_cluster_id"
   243  	case api.DBINSTANCE_TYPE_SQLSERVER:
   244  		dimesionName = "rds_cluster_sqlserver_id"
   245  	}
   246  
   247  	for _, metricName := range metricNames {
   248  		metrics = append(metrics, map[string]interface{}{
   249  			"namespace":   namespace,
   250  			"metric_name": metricName,
   251  			"dimensions": []map[string]string{
   252  				{
   253  					"name":  dimesionName,
   254  					"value": opts.ResourceId,
   255  				},
   256  			},
   257  		})
   258  	}
   259  	params["metrics"] = metrics
   260  	resp, err := self.monitorPost("batch-query-metric-data", params)
   261  	if err != nil {
   262  		return nil, err
   263  	}
   264  	metricData := []MetricData{}
   265  	err = resp.Unmarshal(&metricData, "metrics")
   266  	if err != nil {
   267  		return nil, errors.Wrapf(err, "resp.Unmarshal")
   268  	}
   269  	result := []cloudprovider.MetricValues{}
   270  	for i := range metricData {
   271  		ret := cloudprovider.MetricValues{
   272  			Id:     opts.ResourceId,
   273  			Unit:   metricData[i].Unit,
   274  			Values: []cloudprovider.MetricValue{},
   275  		}
   276  		tags := map[string]string{}
   277  		switch metricData[i].MetricName {
   278  		case "rds001_cpu_util":
   279  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_CPU_USAGE
   280  		case "rds002_mem_util":
   281  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_MEM_USAGE
   282  		case "rds004_bytes_in":
   283  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_NET_BPS_RX
   284  		case "rds005_bytes_out":
   285  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_NET_BPS_TX
   286  		case "rds039_disk_util":
   287  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_DISK_USAGE
   288  		case "rds049_disk_read_throughput":
   289  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_DISK_READ_BPS
   290  		case "rds050_disk_write_throughput":
   291  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_DISK_WRITE_BPS
   292  		case "rds006_conn_count":
   293  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_CONN_COUNT
   294  		case "rds008_qps":
   295  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_QPS
   296  		case "rds009_tps":
   297  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_TPS
   298  		case "rds013_innodb_reads":
   299  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_INNODB_READ_BPS
   300  		case "rds014_innodb_writes":
   301  			ret.MetricType = cloudprovider.RDS_METRIC_TYPE_INNODB_WRITE_BPS
   302  		default:
   303  			log.Warningf("invalid metricName %s for %s %s", metricData[i].MetricName, opts.ResourceType, opts.ResourceId)
   304  			continue
   305  		}
   306  		for _, value := range metricData[i].Datapoints {
   307  			metricValue := cloudprovider.MetricValue{
   308  				Value:     value.Average,
   309  				Timestamp: time.UnixMilli(value.Timestamp),
   310  				Tags:      tags,
   311  			}
   312  			ret.Values = append(ret.Values, metricValue)
   313  		}
   314  		result = append(result, ret)
   315  	}
   316  	return result, nil
   317  }
   318  
   319  func (self *SHuaweiClient) getBucketMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   320  	params := map[string]interface{}{
   321  		"from":   opts.StartTime.UnixMilli(),
   322  		"to":     opts.EndTime.UnixMilli(),
   323  		"period": "1",
   324  		"filter": "average",
   325  	}
   326  	metrics := []interface{}{}
   327  	namespace, dimesionName, metricNames := "SYS.OBS", "bucket_name", []string{
   328  		"download_bytes",
   329  		"upload_bytes",
   330  		"first_byte_latency",
   331  		"get_request_count",
   332  		"request_count_4xx",
   333  		"request_count_5xx",
   334  	}
   335  
   336  	for _, metricName := range metricNames {
   337  		metrics = append(metrics, map[string]interface{}{
   338  			"namespace":   namespace,
   339  			"metric_name": metricName,
   340  			"dimensions": []map[string]string{
   341  				{
   342  					"name":  dimesionName,
   343  					"value": opts.ResourceId,
   344  				},
   345  			},
   346  		})
   347  	}
   348  	params["metrics"] = metrics
   349  	resp, err := self.monitorPost("batch-query-metric-data", params)
   350  	if err != nil {
   351  		return nil, err
   352  	}
   353  	metricData := []MetricData{}
   354  	err = resp.Unmarshal(&metricData, "metrics")
   355  	if err != nil {
   356  		return nil, errors.Wrapf(err, "resp.Unmarshal")
   357  	}
   358  	result := []cloudprovider.MetricValues{}
   359  	for i := range metricData {
   360  		ret := cloudprovider.MetricValues{
   361  			Id:     opts.ResourceId,
   362  			Unit:   metricData[i].Unit,
   363  			Values: []cloudprovider.MetricValue{},
   364  		}
   365  		tags := map[string]string{}
   366  		switch metricData[i].MetricName {
   367  		case "download_bytes":
   368  			ret.MetricType = cloudprovider.BUCKET_METRIC_TYPE_NET_BPS_TX
   369  		case "upload_bytes":
   370  			ret.MetricType = cloudprovider.BUCKET_METRIC_TYPE_NET_BPS_RX
   371  		case "first_byte_latency":
   372  			ret.MetricType = cloudprovider.BUCKET_METRIC_TYPE_LATECY
   373  			tags = map[string]string{"request": "get"}
   374  		case "get_request_count":
   375  			ret.MetricType = cloudprovider.BUCKET_METRYC_TYPE_REQ_COUNT
   376  			tags = map[string]string{"request": "get"}
   377  		case "request_count_4xx":
   378  			ret.MetricType = cloudprovider.BUCKET_METRYC_TYPE_REQ_COUNT
   379  			tags = map[string]string{"request": "4xx"}
   380  		case "request_count_5xx":
   381  			ret.MetricType = cloudprovider.BUCKET_METRYC_TYPE_REQ_COUNT
   382  			tags = map[string]string{"request": "5xx"}
   383  		default:
   384  			log.Warningf("invalid metricName %s for %s %s", metricData[i].MetricName, opts.ResourceType, opts.ResourceId)
   385  			continue
   386  		}
   387  		for _, value := range metricData[i].Datapoints {
   388  			metricValue := cloudprovider.MetricValue{
   389  				Value:     value.Average,
   390  				Timestamp: time.UnixMilli(value.Timestamp),
   391  				Tags:      tags,
   392  			}
   393  			ret.Values = append(ret.Values, metricValue)
   394  		}
   395  		result = append(result, ret)
   396  	}
   397  	return result, nil
   398  }
   399  
   400  func (self *SHuaweiClient) getLoadbalancerMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   401  	params := map[string]interface{}{
   402  		"from":   fmt.Sprintf("%d", opts.StartTime.UnixMilli()),
   403  		"to":     fmt.Sprintf("%d", opts.EndTime.UnixMilli()),
   404  		"period": "1",
   405  		"filter": "average",
   406  	}
   407  	metrics := []interface{}{}
   408  	namespace, dimesionName, metricNames := "SYS.ELB", "lb_instance_id", []string{
   409  		"m7_in_Bps",
   410  		"m8_out_Bps",
   411  		"mc_l7_http_2xx",
   412  		"md_l7_http_3xx",
   413  		"me_l7_http_4xx",
   414  		"mf_l7_http_5xx",
   415  	}
   416  
   417  	for _, metricName := range metricNames {
   418  		metrics = append(metrics, map[string]interface{}{
   419  			"namespace":   namespace,
   420  			"metric_name": metricName,
   421  			"dimensions": []map[string]string{
   422  				{
   423  					"name":  dimesionName,
   424  					"value": opts.ResourceId,
   425  				},
   426  			},
   427  		})
   428  	}
   429  	params["metrics"] = metrics
   430  	resp, err := self.monitorPost("batch-query-metric-data", params)
   431  	if err != nil {
   432  		return nil, err
   433  	}
   434  	metricData := []MetricData{}
   435  	err = resp.Unmarshal(&metricData, "metrics")
   436  	if err != nil {
   437  		return nil, errors.Wrapf(err, "resp.Unmarshal")
   438  	}
   439  	result := []cloudprovider.MetricValues{}
   440  	for i := range metricData {
   441  		ret := cloudprovider.MetricValues{
   442  			Id:     opts.ResourceId,
   443  			Unit:   metricData[i].Unit,
   444  			Values: []cloudprovider.MetricValue{},
   445  		}
   446  		tags := map[string]string{}
   447  		switch metricData[i].MetricName {
   448  		case "m7_in_Bps":
   449  			ret.MetricType = cloudprovider.LB_METRIC_TYPE_NET_BPS_RX
   450  		case "m8_out_Bps":
   451  			ret.MetricType = cloudprovider.LB_METRIC_TYPE_NET_BPS_TX
   452  		case "mc_l7_http_2xx":
   453  			ret.MetricType = cloudprovider.LB_METRIC_TYPE_HRSP_COUNT
   454  			tags = map[string]string{"request": "2xx"}
   455  		case "md_l7_http_3xx":
   456  			ret.MetricType = cloudprovider.LB_METRIC_TYPE_HRSP_COUNT
   457  			tags = map[string]string{"request": "3xx"}
   458  		case "md_l7_http_4xx":
   459  			ret.MetricType = cloudprovider.LB_METRIC_TYPE_HRSP_COUNT
   460  			tags = map[string]string{"request": "4xx"}
   461  		case "md_l7_http_5xx":
   462  			ret.MetricType = cloudprovider.LB_METRIC_TYPE_HRSP_COUNT
   463  			tags = map[string]string{"request": "5xx"}
   464  		default:
   465  			log.Warningf("invalid metricName %s for %s %s", metricData[i].MetricName, opts.ResourceType, opts.ResourceId)
   466  			continue
   467  		}
   468  		for _, value := range metricData[i].Datapoints {
   469  			metricValue := cloudprovider.MetricValue{
   470  				Value:     value.Average,
   471  				Timestamp: time.UnixMilli(value.Timestamp),
   472  				Tags:      tags,
   473  			}
   474  			ret.Values = append(ret.Values, metricValue)
   475  		}
   476  		result = append(result, ret)
   477  	}
   478  	return result, nil
   479  }
   480  
   481  func (self *SHuaweiClient) getModelartsPoolMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   482  	resp, err := self.modelartsPoolMonitor(opts.ResourceId, nil)
   483  	if err != nil {
   484  		return nil, err
   485  	}
   486  	metricData := []SModelartsMetric{}
   487  	err = resp.Unmarshal(&metricData, "metrics")
   488  	if err != nil {
   489  		return nil, errors.Wrapf(err, "resp.Unmarshal")
   490  	}
   491  	result := []cloudprovider.MetricValues{}
   492  	for i := range metricData {
   493  		isMB := false
   494  		if metricData[i].Datapoints[0].Unit == "Megabytes" {
   495  			isMB = true
   496  			metricData[i].Datapoints[0].Unit = "Bytes"
   497  		}
   498  		ret := cloudprovider.MetricValues{
   499  			Id:     opts.ResourceId,
   500  			Unit:   metricData[i].Datapoints[0].Unit,
   501  			Values: []cloudprovider.MetricValue{},
   502  		}
   503  		tags := map[string]string{}
   504  		switch metricData[i].Metric.MetricName {
   505  		case "cpuUsage":
   506  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_CPU_USAGE
   507  		case "memUsedRate":
   508  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_MEM_USAGE
   509  		case "gpuUtil":
   510  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_GPU_UTIL
   511  		case "gpuMemUsage":
   512  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_GPU_MEM_USAGE
   513  		case "npuUtil":
   514  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_NPU_UTIL
   515  		case "npuMemUsage":
   516  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_NPU_MEM_USAGE
   517  		case "diskAvailableCapacity":
   518  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_DISK_AVAILABLE_CAPACITY
   519  		case "diskCapacity":
   520  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_DISK_CAPACITY
   521  		case "diskUsedRate":
   522  			ret.MetricType = cloudprovider.MODELARTS_POOL_METRIC_TYPE_DISK_USAGE
   523  		default:
   524  			log.Warningf("invalid metricName %s for %s %s", metricData[i].Metric.MetricName, opts.ResourceType, opts.ResourceId)
   525  			continue
   526  		}
   527  		for _, value := range metricData[i].Datapoints {
   528  			if isMB {
   529  				value.Statistics[0].Value *= 1024
   530  			}
   531  			if value.Statistics[0].Value == -1 {
   532  				value.Statistics[0].Value = 0
   533  			}
   534  			metricValue := cloudprovider.MetricValue{
   535  				Value:     value.Statistics[0].Value,
   536  				Timestamp: time.UnixMilli(value.Timestamp),
   537  				Tags:      tags,
   538  			}
   539  			ret.Values = append(ret.Values, metricValue)
   540  		}
   541  		result = append(result, ret)
   542  	}
   543  	return result, nil
   544  }
   545  
   546  func (self *SHuaweiClient) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
   547  	switch opts.ResourceType {
   548  	case cloudprovider.METRIC_RESOURCE_TYPE_SERVER:
   549  		return self.getServerMetrics(opts)
   550  	case cloudprovider.METRIC_RESOURCE_TYPE_REDIS:
   551  		return self.getRedisMetrics(opts)
   552  	case cloudprovider.METRIC_RESOURCE_TYPE_RDS:
   553  		return self.getRdsMetrics(opts)
   554  	case cloudprovider.METRIC_RESOURCE_TYPE_BUCKET:
   555  		return self.getBucketMetrics(opts)
   556  	case cloudprovider.METRIC_RESOURCE_TYPE_LB:
   557  		return self.getLoadbalancerMetrics(opts)
   558  	case cloudprovider.METRIC_RESOURCE_TYPE_MODELARTS_POOL:
   559  		return self.getModelartsPoolMetrics(opts)
   560  	default:
   561  		return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "%s", opts.ResourceType)
   562  	}
   563  }