esxi.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. package providerdriver
  15. import (
  16. "context"
  17. "strconv"
  18. "sync"
  19. "time"
  20. "yunion.io/x/cloudmux/pkg/cloudprovider"
  21. "yunion.io/x/log"
  22. "yunion.io/x/pkg/errors"
  23. api "yunion.io/x/onecloud/pkg/apis/compute"
  24. "yunion.io/x/onecloud/pkg/util/influxdb"
  25. )
  26. type EsxiCollect struct {
  27. SCollectByMetricTypeDriver
  28. }
  29. func (self *EsxiCollect) GetProvider() string {
  30. return api.CLOUD_PROVIDER_VMWARE
  31. }
  32. func (self *EsxiCollect) IsSupportMetrics() bool {
  33. return true
  34. }
  35. func (self *EsxiCollect) GetDelayDuration() time.Duration {
  36. return time.Minute * 4
  37. }
  38. func init() {
  39. Register(&EsxiCollect{})
  40. }
  41. func (self *EsxiCollect) CollectServerMetrics(ctx context.Context, manager api.CloudproviderDetails, provider cloudprovider.ICloudProvider, res map[string]api.ServerDetails, start, end time.Time) error {
  42. metrics := []influxdb.SMetricData{}
  43. var wg sync.WaitGroup
  44. var mu sync.Mutex
  45. for _, _metricType := range cloudprovider.ALL_VM_METRIC_TYPES {
  46. wg.Add(1)
  47. go func(metricType cloudprovider.TMetricType) {
  48. defer func() {
  49. wg.Done()
  50. }()
  51. opts := &cloudprovider.MetricListOptions{
  52. ResourceType: cloudprovider.METRIC_RESOURCE_TYPE_SERVER,
  53. MetricType: metricType,
  54. StartTime: start,
  55. EndTime: end,
  56. }
  57. // 磁盘使用率esxi每半小时才有一次数据, 采集时间得提前半小时,否则采集不到数据
  58. if metricType == cloudprovider.VM_METRIC_TYPE_DISK_USAGE {
  59. opts.StartTime = opts.StartTime.Add(time.Minute * -30)
  60. opts.EndTime = opts.EndTime.Add(time.Minute * -30)
  61. }
  62. data, err := provider.GetMetrics(opts)
  63. if err != nil {
  64. if errors.Cause(err) != cloudprovider.ErrNotImplemented && errors.Cause(err) != cloudprovider.ErrNotSupported {
  65. log.Errorf("get server metric %s for %s(%s) error: %v", metricType, manager.Name, manager.Id, err)
  66. return
  67. }
  68. return
  69. }
  70. for _, value := range data {
  71. vm, ok := res[value.Id]
  72. if !ok {
  73. continue
  74. }
  75. tags := []influxdb.SKeyValue{}
  76. for k, v := range vm.GetMetricTags() {
  77. tags = append(tags, influxdb.SKeyValue{
  78. Key: k,
  79. Value: v,
  80. })
  81. }
  82. pairs := []influxdb.SKeyValue{}
  83. for k, v := range vm.GetMetricPairs() {
  84. pairs = append(pairs, influxdb.SKeyValue{
  85. Key: k,
  86. Value: v,
  87. })
  88. }
  89. for _, v := range value.Values {
  90. if value.MetricType == cloudprovider.VM_METRIC_TYPE_DISK_USAGE {
  91. if vm.DiskSizeMb == 0 { // avoid div zero
  92. vm.DiskSizeMb = 1
  93. v.Value = 0
  94. }
  95. v.Value = v.Value / 1024 / 1024 / float64(vm.DiskSizeMb) * 100
  96. }
  97. metric := influxdb.SMetricData{
  98. Name: value.MetricType.Name(),
  99. Timestamp: v.Timestamp,
  100. Tags: []influxdb.SKeyValue{},
  101. Metrics: []influxdb.SKeyValue{
  102. {
  103. Key: value.MetricType.Key(),
  104. Value: strconv.FormatFloat(v.Value, 'E', -1, 64),
  105. },
  106. },
  107. }
  108. for k, v := range v.Tags {
  109. metric.Tags = append(metric.Tags, influxdb.SKeyValue{
  110. Key: k,
  111. Value: v,
  112. })
  113. }
  114. metric.Metrics = append(metric.Metrics, pairs...)
  115. metric.Tags = append(metric.Tags, tags...)
  116. mu.Lock()
  117. metrics = append(metrics, metric)
  118. mu.Unlock()
  119. }
  120. }
  121. }(_metricType)
  122. }
  123. wg.Wait()
  124. return self.sendMetrics(ctx, manager, "server", len(res), metrics)
  125. }