|
|
@ -1,4 +1,4 @@
|
|
|
|
/* Copyright 2016 Adrian Todorov, Oxalide ato@oxalide.com
|
|
|
|
/* Copyright 2016-2018 Adrian Todorov, Oxalide ato@oxalide.com
|
|
|
|
Original project author: https://github.com/cblomart
|
|
|
|
Original project author: https://github.com/cblomart
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
@ -51,6 +51,7 @@ type Configuration struct {
|
|
|
|
Metrics []Metric
|
|
|
|
Metrics []Metric
|
|
|
|
Interval int
|
|
|
|
Interval int
|
|
|
|
Domain string
|
|
|
|
Domain string
|
|
|
|
|
|
|
|
RemoveHostDomainName bool
|
|
|
|
InfluxDB InfluxDB
|
|
|
|
InfluxDB InfluxDB
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -60,6 +61,7 @@ type InfluxDB struct {
|
|
|
|
Username string
|
|
|
|
Username string
|
|
|
|
Password string
|
|
|
|
Password string
|
|
|
|
Database string
|
|
|
|
Database string
|
|
|
|
|
|
|
|
Prefix string
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// VCenter for VMware vCenter connections
|
|
|
|
// VCenter for VMware vCenter connections
|
|
|
@ -98,16 +100,18 @@ type EntityQuery struct {
|
|
|
|
Metrics []int32
|
|
|
|
Metrics []int32
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var debug bool
|
|
|
|
var getversion, debug, test bool
|
|
|
|
var stdlog, errlog *log.Logger
|
|
|
|
var stdlog, errlog *log.Logger
|
|
|
|
|
|
|
|
var version = "master"
|
|
|
|
|
|
|
|
|
|
|
|
// Connect to the actual vCenter connection used to query data
|
|
|
|
// Connect to the actual vCenter connection used to query data
|
|
|
|
func (vcenter *VCenter) Connect() error {
|
|
|
|
func (vcenter *VCenter) Connect() error {
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
|
|
defer cancel()
|
|
|
|
defer cancel()
|
|
|
|
|
|
|
|
|
|
|
|
stdlog.Println("connecting to vcenter: " + vcenter.Hostname)
|
|
|
|
stdlog.Println("Connecting to vcenter:", vcenter.Hostname)
|
|
|
|
u, err := url.Parse("https://" + vcenter.Username + ":" + vcenter.Password + "@" + vcenter.Hostname + "/sdk")
|
|
|
|
u, err := url.Parse("https://" + vcenter.Hostname + "/sdk")
|
|
|
|
|
|
|
|
u.User = url.UserPassword(vcenter.Username, vcenter.Password)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not parse vcenter url:", vcenter.Hostname)
|
|
|
|
errlog.Println("Could not parse vcenter url:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
@ -133,7 +137,7 @@ func (vcenter *VCenter) Disconnect() error {
|
|
|
|
|
|
|
|
|
|
|
|
if vcenter.client != nil {
|
|
|
|
if vcenter.client != nil {
|
|
|
|
if err := vcenter.client.Logout(ctx); err != nil {
|
|
|
|
if err := vcenter.client.Logout(ctx); err != nil {
|
|
|
|
errlog.Println("Could not disconnect properly from vcenter", vcenter.Hostname, err)
|
|
|
|
errlog.Println("Could not disconnect properly from vcenter:", vcenter.Hostname, err)
|
|
|
|
return err
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -148,6 +152,12 @@ func (vcenter *VCenter) Init(config Configuration) error {
|
|
|
|
|
|
|
|
|
|
|
|
client := vcenter.client
|
|
|
|
client := vcenter.client
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Print version
|
|
|
|
|
|
|
|
if debug {
|
|
|
|
|
|
|
|
aboutInfo := client.Client.ServiceContent.About
|
|
|
|
|
|
|
|
stdlog.Println("Version:", aboutInfo.FullName)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var perfmanager mo.PerformanceManager
|
|
|
|
var perfmanager mo.PerformanceManager
|
|
|
|
err := client.RetrieveOne(ctx, *client.ServiceContent.PerfManager, nil, &perfmanager)
|
|
|
|
err := client.RetrieveOne(ctx, *client.ServiceContent.PerfManager, nil, &perfmanager)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -156,6 +166,12 @@ func (vcenter *VCenter) Init(config Configuration) error {
|
|
|
|
return err
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Print PerformanceManager interval collection level
|
|
|
|
|
|
|
|
if debug {
|
|
|
|
|
|
|
|
stdlog.Println("PerformanceManager interval collection level")
|
|
|
|
|
|
|
|
spew.Dump(perfmanager.HistoricalInterval)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for _, perf := range perfmanager.PerfCounter {
|
|
|
|
for _, perf := range perfmanager.PerfCounter {
|
|
|
|
groupinfo := perf.GroupInfo.GetElementDescription()
|
|
|
|
groupinfo := perf.GroupInfo.GetElementDescription()
|
|
|
|
nameinfo := perf.NameInfo.GetElementDescription()
|
|
|
|
nameinfo := perf.NameInfo.GetElementDescription()
|
|
|
@ -200,7 +216,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
var viewManager mo.ViewManager
|
|
|
|
var viewManager mo.ViewManager
|
|
|
|
err := client.RetrieveOne(ctx, *client.ServiceContent.ViewManager, nil, &viewManager)
|
|
|
|
err := client.RetrieveOne(ctx, *client.ServiceContent.ViewManager, nil, &viewManager)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not get view manager from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not get view manager from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error: ", err)
|
|
|
|
errlog.Println("Error: ", err)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -209,16 +225,16 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
var rootFolder mo.Folder
|
|
|
|
var rootFolder mo.Folder
|
|
|
|
err = client.RetrieveOne(ctx, client.ServiceContent.RootFolder, nil, &rootFolder)
|
|
|
|
err = client.RetrieveOne(ctx, client.ServiceContent.RootFolder, nil, &rootFolder)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not get root folder from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not get root folder from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
datacenters := []types.ManagedObjectReference{}
|
|
|
|
datacenters := []types.ManagedObjectReference{}
|
|
|
|
for _, child := range rootFolder.ChildEntity {
|
|
|
|
for _, child := range rootFolder.ChildEntity {
|
|
|
|
if child.Type == "Datacenter" {
|
|
|
|
//if child.Type == "Datacenter" {
|
|
|
|
datacenters = append(datacenters, child)
|
|
|
|
datacenters = append(datacenters, child)
|
|
|
|
}
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Get intresting object types from specified queries
|
|
|
|
// Get intresting object types from specified queries
|
|
|
|
objectTypes := []string{}
|
|
|
|
objectTypes := []string{}
|
|
|
@ -236,7 +252,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
req := types.CreateContainerView{This: viewManager.Reference(), Container: datacenter, Type: objectTypes, Recursive: true}
|
|
|
|
req := types.CreateContainerView{This: viewManager.Reference(), Container: datacenter, Type: objectTypes, Recursive: true}
|
|
|
|
res, err := methods.CreateContainerView(ctx, client.RoundTripper, &req)
|
|
|
|
res, err := methods.CreateContainerView(ctx, client.RoundTripper, &req)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not create container view from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not create container view from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -244,7 +260,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
var containerView mo.ContainerView
|
|
|
|
var containerView mo.ContainerView
|
|
|
|
err = client.RetrieveOne(ctx, res.Returnval, nil, &containerView)
|
|
|
|
err = client.RetrieveOne(ctx, res.Returnval, nil, &containerView)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not get container view from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not get container view from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -344,7 +360,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
// Retrieve properties for ResourcePools
|
|
|
|
// Retrieve properties for ResourcePools
|
|
|
|
if len(respoolRefs) > 0 {
|
|
|
|
if len(respoolRefs) > 0 {
|
|
|
|
if debug {
|
|
|
|
if debug {
|
|
|
|
stdlog.Println("going inside ResourcePools")
|
|
|
|
stdlog.Println("Going inside ResourcePools")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
err = pc.Retrieve(ctx, respoolRefs, []string{"name", "config", "vm"}, &respool)
|
|
|
|
err = pc.Retrieve(ctx, respoolRefs, []string{"name", "config", "vm"}, &respool)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
@ -352,11 +368,11 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, pool := range respool {
|
|
|
|
for _, pool := range respool {
|
|
|
|
stdlog.Println(pool.Config.MemoryAllocation.GetResourceAllocationInfo().Limit)
|
|
|
|
|
|
|
|
stdlog.Println(pool.Config.CpuAllocation.GetResourceAllocationInfo().Limit)
|
|
|
|
|
|
|
|
if debug {
|
|
|
|
if debug {
|
|
|
|
stdlog.Println("---resourcepool name - you should see every resourcepool here (+VMs inside)----")
|
|
|
|
stdlog.Println("---resourcepool name - you should see every resourcepool here (+VMs inside)----")
|
|
|
|
stdlog.Println(pool.Name)
|
|
|
|
stdlog.Println(pool.Name)
|
|
|
|
|
|
|
|
stdlog.Println(pool.Config.MemoryAllocation.GetResourceAllocationInfo().Limit)
|
|
|
|
|
|
|
|
stdlog.Println(pool.Config.CpuAllocation.GetResourceAllocationInfo().Limit)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, vm := range pool.Vm {
|
|
|
|
for _, vm := range pool.Vm {
|
|
|
|
if debug {
|
|
|
|
if debug {
|
|
|
@ -374,10 +390,13 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
// Initialize the map that will hold the host MOR to cluster reference
|
|
|
|
// Initialize the map that will hold the host MOR to cluster reference
|
|
|
|
hostToCluster := make(map[types.ManagedObjectReference]string)
|
|
|
|
hostToCluster := make(map[types.ManagedObjectReference]string)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize the map that will hold the vDisk UUID per VM MOR to datastore reference
|
|
|
|
|
|
|
|
// vDiskToDatastore := make(map[types.ManagedObjectReference]map[string]string)
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieve properties for clusters, if any
|
|
|
|
// Retrieve properties for clusters, if any
|
|
|
|
if len(clusterRefs) > 0 {
|
|
|
|
if len(clusterRefs) > 0 {
|
|
|
|
if debug {
|
|
|
|
if debug {
|
|
|
|
stdlog.Println("going inside clusters")
|
|
|
|
stdlog.Println("Going inside clusters")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Step 1 : Get ObjectContents and Host info for VM
|
|
|
|
// Step 1 : Get ObjectContents and Host info for VM
|
|
|
@ -418,24 +437,34 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
respoolSummary[pools.Self]["name"] = pools.Summary.GetResourcePoolSummary().Name
|
|
|
|
respoolSummary[pools.Self]["name"] = pools.Summary.GetResourcePoolSummary().Name
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Retrieve properties for the hosts
|
|
|
|
// Initialize the maps that will hold the extra tags and metrics for VMs
|
|
|
|
hostSummary := make(map[types.ManagedObjectReference]map[string]string)
|
|
|
|
hostSummary := make(map[types.ManagedObjectReference]map[string]string)
|
|
|
|
hostExtraMetrics := make(map[types.ManagedObjectReference]map[string]int64)
|
|
|
|
hostExtraMetrics := make(map[types.ManagedObjectReference]map[string]int64)
|
|
|
|
|
|
|
|
|
|
|
|
for _, host := range hsmo {
|
|
|
|
for _, host := range hsmo {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Extra tags per host
|
|
|
|
hostSummary[host.Self] = make(map[string]string)
|
|
|
|
hostSummary[host.Self] = make(map[string]string)
|
|
|
|
hostSummary[host.Self]["name"] = host.Summary.Config.Name
|
|
|
|
hostSummary[host.Self]["name"] = host.Summary.Config.Name
|
|
|
|
|
|
|
|
// Remove Domain Name from Host
|
|
|
|
|
|
|
|
if config.RemoveHostDomainName {
|
|
|
|
|
|
|
|
hostSummary[host.Self]["name"] = strings.Replace(host.Summary.Config.Name, config.Domain, "", -1)
|
|
|
|
|
|
|
|
}
|
|
|
|
hostSummary[host.Self]["cluster"] = hostToCluster[host.Self]
|
|
|
|
hostSummary[host.Self]["cluster"] = hostToCluster[host.Self]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Extra metrics per host
|
|
|
|
hostExtraMetrics[host.Self] = make(map[string]int64)
|
|
|
|
hostExtraMetrics[host.Self] = make(map[string]int64)
|
|
|
|
|
|
|
|
hostExtraMetrics[host.Self]["uptime"] = int64(host.Summary.QuickStats.Uptime)
|
|
|
|
hostExtraMetrics[host.Self]["cpu_corecount_total"] = int64(host.Summary.Hardware.NumCpuThreads)
|
|
|
|
hostExtraMetrics[host.Self]["cpu_corecount_total"] = int64(host.Summary.Hardware.NumCpuThreads)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize the map that will hold all extra tags
|
|
|
|
// Initialize the maps that will hold the extra tags and metrics for VMs
|
|
|
|
vmSummary := make(map[types.ManagedObjectReference]map[string]string)
|
|
|
|
vmSummary := make(map[types.ManagedObjectReference]map[string]string)
|
|
|
|
|
|
|
|
vmExtraMetrics := make(map[types.ManagedObjectReference]map[string]int64)
|
|
|
|
|
|
|
|
|
|
|
|
// Assign extra details per VM in vmSummary
|
|
|
|
// Assign extra details per VM in vmSummary
|
|
|
|
for _, vm := range vmmo {
|
|
|
|
for _, vm := range vmmo {
|
|
|
|
|
|
|
|
// extra tags per VM
|
|
|
|
vmSummary[vm.Self] = make(map[string]string)
|
|
|
|
vmSummary[vm.Self] = make(map[string]string)
|
|
|
|
// Ugly way to extract datastore value
|
|
|
|
// Ugly way to extract datastore value
|
|
|
|
re, err := regexp.Compile(`\[(.*?)\]`)
|
|
|
|
re, err := regexp.Compile(`\[(.*?)\]`)
|
|
|
@ -443,15 +472,34 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
fmt.Println(err)
|
|
|
|
fmt.Println(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
vmSummary[vm.Self]["datastore"] = strings.Replace(strings.Replace(re.FindString(fmt.Sprintln(vm.Summary.Config)), "[", "", -1), "]", "", -1)
|
|
|
|
vmSummary[vm.Self]["datastore"] = strings.Replace(strings.Replace(re.FindString(fmt.Sprintln(vm.Summary.Config)), "[", "", -1), "]", "", -1)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// List all devices to get vDisks
|
|
|
|
|
|
|
|
// for _, device := range vm.Config.Hardware.Device {
|
|
|
|
|
|
|
|
// // Hacky way to check if it's a vDisk and if it's datastore is different than the main one for VM
|
|
|
|
|
|
|
|
// if device.Backing.FileName != nil && device.Backing.Datastore.Name != vmSummary[vm.Self]["datastore"] {
|
|
|
|
|
|
|
|
// if vDiskToDatastore[vm.Self] == nil {
|
|
|
|
|
|
|
|
// vDiskToDatastore[vm.Self] = make(map[string]string)
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// vDiskToDatastore[vm.Self][device.diskObjectId] = device.Backing.Datastore.Name
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
if vmToCluster[vm.Self] != "" {
|
|
|
|
if vmToCluster[vm.Self] != "" {
|
|
|
|
vmSummary[vm.Self]["cluster"] = vmToCluster[vm.Self]
|
|
|
|
vmSummary[vm.Self]["cluster"] = vmToCluster[vm.Self]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if vmToPool[vm.Self] != "" {
|
|
|
|
if vmToPool[vm.Self] != "" {
|
|
|
|
vmSummary[vm.Self]["respool"] = vmToPool[vm.Self]
|
|
|
|
vmSummary[vm.Self]["respool"] = vmToPool[vm.Self]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if vm.Summary.Runtime.Host != nil {
|
|
|
|
vmSummary[vm.Self]["esx"] = hostSummary[*vm.Summary.Runtime.Host]["name"]
|
|
|
|
vmSummary[vm.Self]["esx"] = hostSummary[*vm.Summary.Runtime.Host]["name"]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Extra metrics per VM
|
|
|
|
|
|
|
|
vmExtraMetrics[vm.Self] = make(map[string]int64)
|
|
|
|
|
|
|
|
vmExtraMetrics[vm.Self]["uptime"] = int64(vm.Summary.QuickStats.UptimeSeconds)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// fmt.Println("vDiskDatastore:")
|
|
|
|
|
|
|
|
// spew.Dump(vDiskToDatastore)
|
|
|
|
// get object names
|
|
|
|
// get object names
|
|
|
|
objects := []mo.ManagedEntity{}
|
|
|
|
objects := []mo.ManagedEntity{}
|
|
|
|
|
|
|
|
|
|
|
@ -466,7 +514,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
propreq := types.RetrieveProperties{SpecSet: []types.PropertyFilterSpec{{ObjectSet: objectSet, PropSet: []types.PropertySpec{*propSpec}}}}
|
|
|
|
propreq := types.RetrieveProperties{SpecSet: []types.PropertyFilterSpec{{ObjectSet: objectSet, PropSet: []types.PropertySpec{*propSpec}}}}
|
|
|
|
propres, err := client.PropertyCollector().RetrieveProperties(ctx, propreq)
|
|
|
|
propres, err := client.PropertyCollector().RetrieveProperties(ctx, propreq)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not retrieve object names from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not retrieve object names from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -474,7 +522,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
//load retrieved properties
|
|
|
|
//load retrieved properties
|
|
|
|
err = mo.LoadRetrievePropertiesResponse(propres, &objects)
|
|
|
|
err = mo.LoadRetrievePropertiesResponse(propres, &objects)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not retrieve object names from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not retrieve object names from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -522,7 +570,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
perfreq := types.QueryPerf{This: *client.ServiceContent.PerfManager, QuerySpec: queries}
|
|
|
|
perfreq := types.QueryPerf{This: *client.ServiceContent.PerfManager, QuerySpec: queries}
|
|
|
|
perfres, err := methods.QueryPerf(ctx, client.RoundTripper, &perfreq)
|
|
|
|
perfres, err := methods.QueryPerf(ctx, client.RoundTripper, &perfreq)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println("Could not request perfs from vcenter: " + vcenter.Hostname)
|
|
|
|
errlog.Println("Could not request perfs from vcenter:", vcenter.Hostname)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
errlog.Println("Error:", err)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -625,15 +673,21 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
specialTags[measurementName][tags["name"]][instanceName]["instance"] = instanceName
|
|
|
|
specialTags[measurementName][tags["name"]][instanceName]["instance"] = instanceName
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the fields for the hostExtraMetrics
|
|
|
|
if metrics, ok := hostExtraMetrics[pem.Entity]; ok {
|
|
|
|
if metrics, ok := hostExtraMetrics[pem.Entity]; ok {
|
|
|
|
for key, value := range metrics {
|
|
|
|
for key, value := range metrics {
|
|
|
|
fields[key] = value
|
|
|
|
fields[key] = value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the fields for the vmExtraMetrics
|
|
|
|
|
|
|
|
if metrics, ok := vmExtraMetrics[pem.Entity]; ok {
|
|
|
|
|
|
|
|
for key, value := range metrics {
|
|
|
|
|
|
|
|
fields[key] = value
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//create InfluxDB points
|
|
|
|
//create InfluxDB points
|
|
|
|
pt, err := influxclient.NewPoint(entityName, tags, fields, nowTime)
|
|
|
|
pt, err := influxclient.NewPoint(config.InfluxDB.Prefix+entityName, tags, fields, nowTime)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println(err)
|
|
|
|
errlog.Println(err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
@ -643,7 +697,7 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
for measurement, v := range specialFields {
|
|
|
|
for measurement, v := range specialFields {
|
|
|
|
for name, metric := range v {
|
|
|
|
for name, metric := range v {
|
|
|
|
for instance, value := range metric {
|
|
|
|
for instance, value := range metric {
|
|
|
|
pt2, err := influxclient.NewPoint(measurement, specialTags[measurement][name][instance], value, time.Now())
|
|
|
|
pt2, err := influxclient.NewPoint(config.InfluxDB.Prefix+measurement, specialTags[measurement][name][instance], value, time.Now())
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println(err)
|
|
|
|
errlog.Println(err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
@ -653,20 +707,13 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// var respool []mo.ResourcePool
|
|
|
|
|
|
|
|
// err = pc.Retrieve(ctx, respoolRefs, []string{"name", "config", "vm"}, &respool)
|
|
|
|
|
|
|
|
// if err != nil {
|
|
|
|
|
|
|
|
// errlog.Println(err)
|
|
|
|
|
|
|
|
// continue
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for _, pool := range respool {
|
|
|
|
for _, pool := range respool {
|
|
|
|
respoolFields := map[string]interface{}{
|
|
|
|
respoolFields := map[string]interface{}{
|
|
|
|
"cpu_limit": pool.Config.CpuAllocation.GetResourceAllocationInfo().Limit,
|
|
|
|
"cpu_limit": pool.Config.CpuAllocation.GetResourceAllocationInfo().Limit,
|
|
|
|
"memory_limit": pool.Config.MemoryAllocation.GetResourceAllocationInfo().Limit,
|
|
|
|
"memory_limit": pool.Config.MemoryAllocation.GetResourceAllocationInfo().Limit,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
respoolTags := map[string]string{"pool_name": pool.Name}
|
|
|
|
respoolTags := map[string]string{"pool_name": pool.Name}
|
|
|
|
pt3, err := influxclient.NewPoint("resourcepool", respoolTags, respoolFields, time.Now())
|
|
|
|
pt3, err := influxclient.NewPoint(config.InfluxDB.Prefix+"resourcepool", respoolTags, respoolFields, time.Now())
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println(err)
|
|
|
|
errlog.Println(err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
@ -678,9 +725,10 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
datastoreFields := map[string]interface{}{
|
|
|
|
datastoreFields := map[string]interface{}{
|
|
|
|
"capacity": datastore.Summary.Capacity,
|
|
|
|
"capacity": datastore.Summary.Capacity,
|
|
|
|
"free_space": datastore.Summary.FreeSpace,
|
|
|
|
"free_space": datastore.Summary.FreeSpace,
|
|
|
|
|
|
|
|
"usage": 1.0 - (float64(datastore.Summary.FreeSpace) / float64(datastore.Summary.Capacity)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
datastoreTags := map[string]string{"ds_name": datastore.Summary.Name, "host": vcName}
|
|
|
|
datastoreTags := map[string]string{"ds_name": datastore.Summary.Name, "host": vcName}
|
|
|
|
pt4, err := influxclient.NewPoint("datastore", datastoreTags, datastoreFields, time.Now())
|
|
|
|
pt4, err := influxclient.NewPoint(config.InfluxDB.Prefix+"datastore", datastoreTags, datastoreFields, time.Now())
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println(err)
|
|
|
|
errlog.Println(err)
|
|
|
|
continue
|
|
|
|
continue
|
|
|
@ -690,14 +738,17 @@ func (vcenter *VCenter) Query(config Configuration, InfluxDBClient influxclient.
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//InfluxDB send
|
|
|
|
//InfluxDB send if not in test mode
|
|
|
|
|
|
|
|
if test != true {
|
|
|
|
err = InfluxDBClient.Write(bp)
|
|
|
|
err = InfluxDBClient.Write(bp)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
errlog.Println(err)
|
|
|
|
errlog.Println(err)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stdlog.Println("Sent data to Influxdb from:", vcenter.Hostname)
|
|
|
|
stdlog.Println("sent data to Influxdb")
|
|
|
|
} else {
|
|
|
|
|
|
|
|
spew.Dump(bp)
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func min(n ...int64) int64 {
|
|
|
|
func min(n ...int64) int64 {
|
|
|
@ -715,7 +766,6 @@ func min(n ...int64) int64 {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return min
|
|
|
|
return min
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func max(n ...int64) int64 {
|
|
|
|
func max(n ...int64) int64 {
|
|
|
|
var max int64 = -1
|
|
|
|
var max int64 = -1
|
|
|
|
for _, i := range n {
|
|
|
|
for _, i := range n {
|
|
|
@ -766,7 +816,6 @@ func worker(id int, config Configuration, influxDBClient influxclient.Client, no
|
|
|
|
results <- true
|
|
|
|
results <- true
|
|
|
|
continue
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if err := vcenter.Init(config); err == nil {
|
|
|
|
if err := vcenter.Init(config); err == nil {
|
|
|
|
vcenter.Query(config, influxDBClient, nowTime)
|
|
|
|
vcenter.Query(config, influxDBClient, nowTime)
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -782,10 +831,17 @@ func main() {
|
|
|
|
errlog = log.New(os.Stderr, "", log.Ldate|log.Ltime)
|
|
|
|
errlog = log.New(os.Stderr, "", log.Ldate|log.Ltime)
|
|
|
|
|
|
|
|
|
|
|
|
flag.BoolVar(&debug, "debug", false, "Debug mode")
|
|
|
|
flag.BoolVar(&debug, "debug", false, "Debug mode")
|
|
|
|
|
|
|
|
flag.BoolVar(&test, "test", false, "Test mode, data will be collected from vCenters, but nothing will be written to InfluxDB, only printed to stdout")
|
|
|
|
|
|
|
|
flag.BoolVar(&getversion, "version", false, "Get version and exit")
|
|
|
|
workerCount := flag.Int("workers", 4, "Number of concurrent workers to query vcenters")
|
|
|
|
workerCount := flag.Int("workers", 4, "Number of concurrent workers to query vcenters")
|
|
|
|
cfgFile := flag.String("config", "/etc/"+baseName+".json", "Config file to use. Default is /etc/"+baseName+".json")
|
|
|
|
cfgFile := flag.String("config", "/etc/"+baseName+".json", "Config file to use")
|
|
|
|
flag.Parse()
|
|
|
|
flag.Parse()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if getversion {
|
|
|
|
|
|
|
|
fmt.Println("Version:", version)
|
|
|
|
|
|
|
|
os.Exit(0)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
stdlog.Println("Starting", baseName, "with config file", *cfgFile)
|
|
|
|
stdlog.Println("Starting", baseName, "with config file", *cfgFile)
|
|
|
|
|
|
|
|
|
|
|
|
// read the configuration
|
|
|
|
// read the configuration
|
|
|
@ -810,7 +866,6 @@ func main() {
|
|
|
|
config.InfluxDB.Password = os.Getenv("INFLUX_PASSWORD")
|
|
|
|
config.InfluxDB.Password = os.Getenv("INFLUX_PASSWORD")
|
|
|
|
config.InfluxDB.Database = os.Getenv("INFLUX_DATABASE")
|
|
|
|
config.InfluxDB.Database = os.Getenv("INFLUX_DATABASE")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Support environment variables for VSphere
|
|
|
|
// Support environment variables for VSphere
|
|
|
|
// Currently ony one server is supported and added to the list of vSphere servers
|
|
|
|
// Currently ony one server is supported and added to the list of vSphere servers
|
|
|
|
if vhostname := os.Getenv("VSPHERE_HOSTNAME"); vhostname != "" {
|
|
|
|
if vhostname := os.Getenv("VSPHERE_HOSTNAME"); vhostname != "" {
|
|
|
|