1
0
Fork 0
telegraf/plugins/inputs/vsphere/vsphere.go

182 lines
7.3 KiB
Go
Raw Permalink Normal View History

//go:generate ../../../tools/readme_config_includer/generator
package vsphere
import (
"context"
_ "embed"
"errors"
"sync"
"time"
"github.com/vmware/govmomi/vim25/soap"
"github.com/influxdata/telegraf"
"github.com/influxdata/telegraf/config"
"github.com/influxdata/telegraf/plugins/common/proxy"
"github.com/influxdata/telegraf/plugins/common/tls"
"github.com/influxdata/telegraf/plugins/inputs"
)
//go:embed sample.conf
var sampleConfig string
type VSphere struct {
Vcenters []string `toml:"vcenters"`
Username config.Secret `toml:"username"`
Password config.Secret `toml:"password"`
DatacenterInstances bool `toml:"datacenter_instances"`
DatacenterMetricInclude []string `toml:"datacenter_metric_include"`
DatacenterMetricExclude []string `toml:"datacenter_metric_exclude"`
DatacenterInclude []string `toml:"datacenter_include"`
DatacenterExclude []string `toml:"datacenter_exclude"`
ClusterInstances bool `toml:"cluster_instances"`
ClusterMetricInclude []string `toml:"cluster_metric_include"`
ClusterMetricExclude []string `toml:"cluster_metric_exclude"`
ClusterInclude []string `toml:"cluster_include"`
ClusterExclude []string `toml:"cluster_exclude"`
ResourcePoolInstances bool `toml:"resource_pool_instances"`
ResourcePoolMetricInclude []string `toml:"resource_pool_metric_include"`
ResourcePoolMetricExclude []string `toml:"resource_pool_metric_exclude"`
ResourcePoolInclude []string `toml:"resource_pool_include"`
ResourcePoolExclude []string `toml:"resource_pool_exclude"`
HostInstances bool `toml:"host_instances"`
HostMetricInclude []string `toml:"host_metric_include"`
HostMetricExclude []string `toml:"host_metric_exclude"`
HostInclude []string `toml:"host_include"`
HostExclude []string `toml:"host_exclude"`
VMInstances bool `toml:"vm_instances"`
VMMetricInclude []string `toml:"vm_metric_include"`
VMMetricExclude []string `toml:"vm_metric_exclude"`
VMInclude []string `toml:"vm_include"`
VMExclude []string `toml:"vm_exclude"`
DatastoreInstances bool `toml:"datastore_instances"`
DatastoreMetricInclude []string `toml:"datastore_metric_include"`
DatastoreMetricExclude []string `toml:"datastore_metric_exclude"`
DatastoreInclude []string `toml:"datastore_include"`
DatastoreExclude []string `toml:"datastore_exclude"`
VSANMetricInclude []string `toml:"vsan_metric_include"`
VSANMetricExclude []string `toml:"vsan_metric_exclude"`
VSANMetricSkipVerify bool `toml:"vsan_metric_skip_verify"`
VSANClusterInclude []string `toml:"vsan_cluster_include"`
VSANInterval config.Duration `toml:"vsan_interval"`
Separator string `toml:"separator"`
CustomAttributeInclude []string `toml:"custom_attribute_include"`
CustomAttributeExclude []string `toml:"custom_attribute_exclude"`
UseIntSamples bool `toml:"use_int_samples"`
IPAddresses []string `toml:"ip_addresses"`
MetricLookback int `toml:"metric_lookback"`
DisconnectedServersBehavior string `toml:"disconnected_servers_behavior"`
MaxQueryObjects int `toml:"max_query_objects"`
MaxQueryMetrics int `toml:"max_query_metrics"`
CollectConcurrency int `toml:"collect_concurrency"`
DiscoverConcurrency int `toml:"discover_concurrency"`
ForceDiscoverOnInit bool `toml:"force_discover_on_init" deprecated:"1.14.0;1.35.0;option is ignored"`
ObjectDiscoveryInterval config.Duration `toml:"object_discovery_interval"`
Timeout config.Duration `toml:"timeout"`
HistoricalInterval config.Duration `toml:"historical_interval"`
Log telegraf.Logger `toml:"-"`
tls.ClientConfig // Mix in the TLS/SSL goodness from core
proxy.HTTPProxy
endpoints []*endpoint
cancel context.CancelFunc
}
func (*VSphere) SampleConfig() string {
return sampleConfig
}
func (v *VSphere) Start(_ telegraf.Accumulator) error {
v.Log.Info("Starting plugin")
ctx, cancel := context.WithCancel(context.Background())
v.cancel = cancel
// Create endpoints, one for each vCenter we're monitoring
v.endpoints = make([]*endpoint, 0, len(v.Vcenters))
for _, rawURL := range v.Vcenters {
u, err := soap.ParseURL(rawURL)
if err != nil {
return err
}
ep, err := newEndpoint(ctx, v, u, v.Log)
if err != nil {
return err
}
v.endpoints = append(v.endpoints, ep)
}
return nil
}
func (v *VSphere) Gather(acc telegraf.Accumulator) error {
var wg sync.WaitGroup
for _, ep := range v.endpoints {
wg.Add(1)
go func(endpoint *endpoint) {
defer wg.Done()
err := endpoint.collect(context.Background(), acc)
if errors.Is(err, context.Canceled) {
// No need to signal errors if we were merely canceled.
err = nil
}
if err != nil {
acc.AddError(err)
}
}(ep)
}
wg.Wait()
return nil
}
func (v *VSphere) Stop() {
v.Log.Info("Stopping plugin")
v.cancel()
// Wait for all endpoints to finish. No need to wait for
// Gather() to finish here, since it Stop() will only be called
// after the last Gather() has finished. We do, however, need to
// wait for any discovery to complete by trying to grab the
// "busy" mutex.
for _, ep := range v.endpoints {
v.Log.Debugf("Waiting for endpoint %q to finish", ep.url.Host)
func() {
ep.busy.Lock() // Wait until discovery is finished
defer ep.busy.Unlock()
ep.close()
}()
}
}
func init() {
inputs.Add("vsphere", func() telegraf.Input {
return &VSphere{
DatacenterInclude: []string{"/*"},
ClusterInclude: []string{"/*/host/**"},
HostInstances: true,
HostInclude: []string{"/*/host/**"},
ResourcePoolInclude: []string{"/*/host/**"},
VMInstances: true,
VMInclude: []string{"/*/vm/**"},
DatastoreInclude: []string{"/*/datastore/**"},
VSANMetricExclude: []string{"*"},
VSANClusterInclude: []string{"/*/host/**"},
Separator: "_",
CustomAttributeExclude: []string{"*"},
UseIntSamples: true,
MaxQueryObjects: 256,
MaxQueryMetrics: 256,
CollectConcurrency: 1,
DiscoverConcurrency: 1,
MetricLookback: 3,
ForceDiscoverOnInit: true,
ObjectDiscoveryInterval: config.Duration(time.Second * 300),
Timeout: config.Duration(time.Second * 60),
HistoricalInterval: config.Duration(time.Second * 300),
VSANInterval: config.Duration(time.Second * 300),
DisconnectedServersBehavior: "error",
HTTPProxy: proxy.HTTPProxy{UseSystemProxy: true},
}
})
}