Files
cloudpods/pkg/multicloud/esxi/monitor.go
2020-03-13 15:02:13 +08:00

173 lines
5.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package esxi
import (
"fmt"
"strings"
"time"
"github.com/vmware/govmomi/performance"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
)
var (
metricIdTable = map[int32]types.PerfCounterInfo{}
metricNameTable = map[string]types.PerfCounterInfo{}
metricIdNameTable = map[int32]string{}
metricSpecsMap map[string][]string
)
func (client *SESXiClient) GetMonitorData(serverOrHost jsonutils.JSONObject,
monType string, metricSpecs map[string][]string,
since time.Time, until time.Time) (perfEntityMetricList []*types.PerfEntityMetric, IdNameTable map[int32]string, err error) {
metricSpecsMap = metricSpecs
managedEntity, err := client.getManagerEntiry(serverOrHost, monType)
if err != nil {
return nil, IdNameTable, err
}
performanceManager := performance.NewManager(client.client.Client)
perfCounters, err := performanceManager.CounterInfo(client.context)
if err != nil {
return nil, IdNameTable, err
}
loadMap(perfCounters)
perfProviderSummary, err := performanceManager.ProviderSummary(client.context, managedEntity.Self)
if err != nil {
return nil, IdNameTable, err
}
refreshInterval := perfProviderSummary.RefreshRate
perfMetricList, err := performanceManager.AvailableMetric(client.context, managedEntity.Self, refreshInterval)
pmiList := buildPerfMetricIds(perfMetricList)
perfQuerySpec := types.PerfQuerySpec{
Entity: managedEntity.Reference(),
MaxSample: int32(5),
MetricId: pmiList,
Format: "normal",
IntervalId: refreshInterval,
StartTime: &since,
EndTime: &until,
}
perfEntityMetrics, err := performanceManager.Query(client.context, []types.PerfQuerySpec{perfQuerySpec})
if err != nil {
return nil, IdNameTable, err
}
for _, perfEntityMetricBase := range perfEntityMetrics {
if perfEntityMetric, ok := perfEntityMetricBase.(*types.PerfEntityMetric); ok {
perfEntityMetricList = append(perfEntityMetricList, perfEntityMetric)
}
}
return perfEntityMetricList, metricIdNameTable, nil
}
func (cli *SESXiClient) getVirtualMachines() ([]mo.VirtualMachine, error) {
var virtualMachines []mo.VirtualMachine
err := cli.scanAllMObjects(VIRTUAL_MACHINE_PROPS, &virtualMachines)
if err != nil {
return virtualMachines, errors.Wrap(err, "cli.scanAllMObjects host")
}
return virtualMachines, nil
}
func (cli *SESXiClient) GetHostSystem() ([]mo.HostSystem, error) {
var hostSystems []mo.HostSystem
err := cli.scanAllMObjects(HOST_SYSTEM_PROPS, &hostSystems)
if err != nil {
return hostSystems, errors.Wrap(err, "cli.scanAllMObjects host")
}
return hostSystems, nil
}
func (cli *SESXiClient) getManagerEntiry(serverOrHost jsonutils.JSONObject, monType string) (*mo.ManagedEntity, error) {
switch monType {
case "VirtualMachine":
return cli.getManagerEntityofVm(serverOrHost)
case "HostSystem":
return cli.getManagerEntityofHost(serverOrHost)
}
return nil, fmt.Errorf("monType error")
}
func (cli *SESXiClient) getManagerEntityofVm(server jsonutils.JSONObject) (*mo.ManagedEntity, error) {
name, _ := server.GetString("name")
virtualMachines, err := cli.getVirtualMachines()
if err != nil {
return nil, err
}
for _, virtualMachine := range virtualMachines {
if virtualMachine.Name == name {
return virtualMachine.Entity(), nil
}
}
return nil, fmt.Errorf("No ManagerEntiry for %s vm", name)
}
func (cli *SESXiClient) getManagerEntityofHost(host jsonutils.JSONObject) (*mo.ManagedEntity, error) {
name, _ := host.GetString("name")
hostSystems, err := cli.GetHostSystem()
if err != nil {
return nil, err
}
for _, hostSystem := range hostSystems {
if strings.Contains(hostSystem.Name, name) || strings.Contains(name, hostSystem.Name) {
return hostSystem.Entity(), nil
}
}
return nil, fmt.Errorf("No ManagerEntiry for %s host", name)
}
//根据perfCounterInfos装载metricIdTable、metricNameTable、metricIdNameTable
func loadMap(perfCounterInfos []types.PerfCounterInfo) {
for _, perfCounterInfo := range perfCounterInfos {
metricId := perfCounterInfo.Key
metricIdTable[metricId] = perfCounterInfo
if perfCounterInfo.GroupInfo.GetElementDescription() != nil && perfCounterInfo.GroupInfo.
GetElementDescription().Key != "" {
var builder strings.Builder
builder.WriteString(perfCounterInfo.GroupInfo.GetElementDescription().Key)
if perfCounterInfo.NameInfo.GetElementDescription() != nil && perfCounterInfo.NameInfo.
GetElementDescription().Key != "" {
builder.WriteString("_")
builder.WriteString(perfCounterInfo.NameInfo.GetElementDescription().Key)
}
if len(perfCounterInfo.AssociatedCounterId) == 0 && perfCounterInfo.RollupType == types.
PerfSummaryTypeAverage {
metricNameTable[builder.String()] = perfCounterInfo
metricIdNameTable[metricId] = builder.String()
}
}
}
}
//根据传入的metricSpecsMap的进行过滤只取相关的指标metricName
func buildPerfMetricIds(pmis []types.PerfMetricId) (pmiList []types.PerfMetricId) {
for _, perfMetricId := range pmis {
metricId := perfMetricId.CounterId
if metricName, ok := metricIdNameTable[metricId]; ok && metricName != "" {
if _, ok := metricSpecsMap[metricName]; ok {
pmiList = append(pmiList, perfMetricId)
}
}
}
return pmiList
}