yunion.io/x/cloudmux@v0.3.10-0-alpha.1/pkg/multicloud/jdcloud/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 jdcloud
    16  
    17  import (
    18  	"fmt"
    19  	"strconv"
    20  	"time"
    21  
    22  	jc_apis "github.com/jdcloud-api/jdcloud-sdk-go/services/monitor/apis"
    23  	client "github.com/jdcloud-api/jdcloud-sdk-go/services/monitor/client"
    24  
    25  	"yunion.io/x/log"
    26  	"yunion.io/x/pkg/errors"
    27  	"yunion.io/x/pkg/util/timeutils"
    28  
    29  	api "yunion.io/x/cloudmux/pkg/apis/compute"
    30  	"yunion.io/x/cloudmux/pkg/cloudprovider"
    31  )
    32  
    33  func (self *SJDCloudClient) GetMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
    34  	switch opts.ResourceType {
    35  	case cloudprovider.METRIC_RESOURCE_TYPE_SERVER:
    36  		return self.GetEcsMetrics(opts)
    37  	case cloudprovider.METRIC_RESOURCE_TYPE_RDS:
    38  		return self.GetRdsMetrics(opts)
    39  	default:
    40  		return nil, errors.Wrapf(cloudprovider.ErrNotImplemented, "%s", opts.ResourceType)
    41  	}
    42  }
    43  
    44  func (self *SJDCloudClient) GetEcsMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
    45  	ret := []cloudprovider.MetricValues{}
    46  	for metricType, metricName := range map[cloudprovider.TMetricType]string{
    47  		cloudprovider.VM_METRIC_TYPE_CPU_USAGE:          "cpu_util",
    48  		cloudprovider.VM_METRIC_TYPE_MEM_USAGE:          "memory.usage",
    49  		cloudprovider.VM_METRIC_TYPE_DISK_USAGE:         "vm.disk.dev.used",
    50  		cloudprovider.VM_METRIC_TYPE_NET_BPS_RX:         "vm.network.dev.bytes.in",
    51  		cloudprovider.VM_METRIC_TYPE_NET_BPS_TX:         "vm.network.dev.bytes.out",
    52  		cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_BPS:   "vm.disk.dev.bytes.read",
    53  		cloudprovider.VM_METRIC_TYPE_DISK_IO_WRITE_BPS:  "vm.disk.dev.bytes.write",
    54  		cloudprovider.VM_METRIC_TYPE_DISK_IO_READ_IOPS:  "vm.disk.dev.io.read",
    55  		cloudprovider.VM_METRIC_TYPE_DISK_IO_WRITE_IOPS: "vm.disk.dev.io.write",
    56  	} {
    57  
    58  		aggrType, downSampleType, serviceCode := "avg", "avg", "vm"
    59  		startTime, endTime := opts.StartTime.Format(timeutils.FullIsoTimeFormat), opts.EndTime.Format(timeutils.FullIsoTimeFormat)
    60  		request := jc_apis.NewDescribeMetricDataRequestWithAllParams(opts.RegionExtId, metricName, &aggrType, &downSampleType, &startTime, &endTime, nil, nil, nil, nil, &serviceCode, nil, opts.ResourceId)
    61  		monitorClient := client.NewMonitorClient(self.getCredential())
    62  		monitorClient.Logger = Logger{debug: self.debug}
    63  		response, err := monitorClient.DescribeMetricData(request)
    64  		if err != nil {
    65  			return nil, err
    66  		}
    67  		metric := cloudprovider.MetricValues{}
    68  		metric.Id = opts.ResourceId
    69  		metric.MetricType = metricType
    70  		for _, data := range response.Result.MetricDatas {
    71  			for _, value := range data.Data {
    72  				metricValue := cloudprovider.MetricValue{}
    73  				metricValue.Timestamp = time.Unix(value.Timestamp/1000, 0)
    74  				if value.Value == nil {
    75  					continue
    76  				}
    77  				metricValue.Value, err = strconv.ParseFloat(fmt.Sprintf("%s", value.Value), 64)
    78  				if err != nil {
    79  					log.Errorf("parse value %v error: %v", value.Value, nil)
    80  					continue
    81  				}
    82  				metric.Values = append(metric.Values, metricValue)
    83  			}
    84  		}
    85  		ret = append(ret, metric)
    86  	}
    87  	return ret, nil
    88  }
    89  
    90  func (self *SJDCloudClient) GetRdsMetrics(opts *cloudprovider.MetricListOptions) ([]cloudprovider.MetricValues, error) {
    91  	metrics := map[cloudprovider.TMetricType]string{}
    92  	switch opts.Engine {
    93  	case api.DBINSTANCE_TYPE_MYSQL, api.DBINSTANCE_TYPE_SQLSERVER, api.DBINSTANCE_TYPE_PERCONA, api.DBINSTANCE_TYPE_MARIADB:
    94  		metrics = map[cloudprovider.TMetricType]string{
    95  			cloudprovider.RDS_METRIC_TYPE_CPU_USAGE:  "database.docker.cpu.util",
    96  			cloudprovider.RDS_METRIC_TYPE_MEM_USAGE:  "database.docker.memory.pused",
    97  			cloudprovider.RDS_METRIC_TYPE_DISK_USAGE: "database.docker.disk1.used",
    98  			cloudprovider.RDS_METRIC_TYPE_NET_BPS_RX: "database.docker.network.incoming",
    99  			cloudprovider.RDS_METRIC_TYPE_NET_BPS_TX: "database.docker.network.outgoing",
   100  		}
   101  	case api.DBINSTANCE_TYPE_POSTGRESQL:
   102  		metrics = map[cloudprovider.TMetricType]string{
   103  			cloudprovider.RDS_METRIC_TYPE_CPU_USAGE:  "database.docker.cpu.util",
   104  			cloudprovider.RDS_METRIC_TYPE_MEM_USAGE:  "database.docker.memory.pused",
   105  			cloudprovider.RDS_METRIC_TYPE_DISK_USAGE: "database.docker.disk1.used",
   106  			cloudprovider.RDS_METRIC_TYPE_NET_BPS_RX: "database.docker.network.incoming",
   107  			cloudprovider.RDS_METRIC_TYPE_NET_BPS_TX: "database.docker.network.outgoing",
   108  		}
   109  	default:
   110  		return nil, errors.Wrapf(cloudprovider.ErrNotSupported, "%s", opts.Engine)
   111  	}
   112  	ret := []cloudprovider.MetricValues{}
   113  	aggrType, downSampleType := "avg", "avg"
   114  	startTime, endTime := opts.StartTime.Format(timeutils.FullIsoTimeFormat), opts.EndTime.Format(timeutils.FullIsoTimeFormat)
   115  	serviceCode := map[string]string{
   116  		api.DBINSTANCE_TYPE_SQLSERVER:  "sqlserver",
   117  		api.DBINSTANCE_TYPE_MYSQL:      "database",
   118  		api.DBINSTANCE_TYPE_PERCONA:    "percona",
   119  		api.DBINSTANCE_TYPE_MARIADB:    "mariadb",
   120  		api.DBINSTANCE_TYPE_POSTGRESQL: "pag",
   121  	}[opts.Engine]
   122  	for metricType, metricName := range metrics {
   123  		request := jc_apis.NewDescribeMetricDataRequestWithAllParams(opts.RegionExtId, metricName, &aggrType, &downSampleType, &startTime, &endTime, nil, nil, nil, nil, &serviceCode, nil, opts.ResourceId)
   124  		monitorClient := client.NewMonitorClient(self.getCredential())
   125  		monitorClient.Logger = Logger{}
   126  		response, err := monitorClient.DescribeMetricData(request)
   127  		if err != nil {
   128  			return nil, err
   129  		}
   130  		metric := cloudprovider.MetricValues{}
   131  		metric.Id = opts.ResourceId
   132  		metric.MetricType = metricType
   133  		for _, data := range response.Result.MetricDatas {
   134  			for _, value := range data.Data {
   135  				metricValue := cloudprovider.MetricValue{}
   136  				metricValue.Timestamp = time.Unix(value.Timestamp/1000, 0)
   137  				if value.Value == nil {
   138  					continue
   139  				}
   140  				metricValue.Value, err = strconv.ParseFloat(fmt.Sprintf("%s", value.Value), 64)
   141  				if err != nil {
   142  					log.Errorf("parse value %v error: %v", value.Value, nil)
   143  					continue
   144  				}
   145  				// kbps -> byte
   146  				if opts.Engine != api.DBINSTANCE_TYPE_POSTGRESQL && (metricType == cloudprovider.RDS_METRIC_TYPE_NET_BPS_RX || metricType == cloudprovider.RDS_METRIC_TYPE_NET_BPS_TX) {
   147  					metricValue.Value = metricValue.Value / 1024.0
   148  				}
   149  				metric.Values = append(metric.Values, metricValue)
   150  			}
   151  		}
   152  		ret = append(ret, metric)
   153  	}
   154  	return ret, nil
   155  }