diff --git a/.chloggen/add_vcenter_datacenter_metrics.yaml b/.chloggen/add_vcenter_datacenter_metrics.yaml new file mode 100644 index 000000000000..079bb8b21744 --- /dev/null +++ b/.chloggen/add_vcenter_datacenter_metrics.yaml @@ -0,0 +1,28 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: enhancement + +# The name of the component, or a single word describing the area of concern, (e.g. filelogreceiver) +component: vcenterreceiver + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Adds vCenter metrics at the datacenter level." + +# Mandatory: One or more tracking issues related to the change. You can use the PR number here if no issue exists. +issues: [33607] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + Introduces various datacenter metrics which work by aggregating stats from datastores, clusters, hosts, and VM's. + +# If your change doesn't affect end users or the exported elements of any package, +# you should instead start your pull request title with [chore] or use the "Skip Changelog" label. +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [user] diff --git a/receiver/vcenterreceiver/client.go b/receiver/vcenterreceiver/client.go index 105a5ba29676..3a5dfd4b1cf9 100644 --- a/receiver/vcenterreceiver/client.go +++ b/receiver/vcenterreceiver/client.go @@ -154,11 +154,13 @@ func (vc *vcenterClient) HostSystems(ctx context.Context, containerMoRef vt.Mana var hosts []mo.HostSystem err = v.Retrieve(ctx, []string{"HostSystem"}, []string{ "name", + "runtime.powerState", "summary.hardware.memorySize", "summary.hardware.numCpuCores", "summary.hardware.cpuMhz", "summary.quickStats.overallMemoryUsage", "summary.quickStats.overallCpuUsage", + "summary.overallStatus", "vm", "parent", }, &hosts) @@ -210,6 +212,7 @@ func (vc *vcenterClient) VMs(ctx context.Context, containerMoRef vt.ManagedObjec "summary.quickStats.swappedMemory", "summary.quickStats.ssdSwappedMemory", "summary.quickStats.overallCpuUsage", + "summary.overallStatus", "summary.config.memorySizeMB", "summary.storage.committed", "summary.storage.uncommitted", diff --git a/receiver/vcenterreceiver/documentation.md b/receiver/vcenterreceiver/documentation.md index 56796cd3f800..87717326cbe8 100644 --- a/receiver/vcenterreceiver/documentation.md +++ b/receiver/vcenterreceiver/documentation.md @@ -72,7 +72,7 @@ The number of virtual machines in the cluster. | Name | Description | Values | | ---- | ----------- | ------ | -| power_state | The current power state of the virtual machine. | Str: ``on``, ``off``, ``suspended`` | +| power_state | The current power state of the virtual machine. | Str: ``on``, ``off``, ``suspended``, ``unknown`` | ### vcenter.cluster.vm_template.count @@ -493,6 +493,88 @@ metrics: enabled: true ``` +### vcenter.datacenter.cluster.count + +The number of clusters in the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {clusters} | Sum | Int | Cumulative | false | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| status | The current status of the managed entity. | Str: ``red``, ``yellow``, ``green``, ``gray`` | + +### vcenter.datacenter.cpu.limit + +The total amount of CPU available to the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {MHz} | Sum | Int | Cumulative | false | + +### vcenter.datacenter.datastore.count + +The number of datastores in the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {datastores} | Sum | Int | Cumulative | false | + +### vcenter.datacenter.disk.space + +The amount of available and used disk space in the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| By | Sum | Int | Cumulative | false | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| disk_state | The state of storage and whether it is already allocated or free. | Str: ``available``, ``used`` | + +### vcenter.datacenter.host.count + +The number of hosts in the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {hosts} | Sum | Int | Cumulative | false | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| status | The current status of the managed entity. | Str: ``red``, ``yellow``, ``green``, ``gray`` | +| power_state | The current power state of the host. | Str: ``on``, ``off``, ``standby``, ``unknown`` | + +### vcenter.datacenter.memory.limit + +The total amount of memory available to the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| By | Sum | Int | Cumulative | false | + +### vcenter.datacenter.vm.count + +The number of VM's in the datacenter. + +| Unit | Metric Type | Value Type | Aggregation Temporality | Monotonic | +| ---- | ----------- | ---------- | ----------------------- | --------- | +| {virtual_machines} | Sum | Int | Cumulative | false | + +#### Attributes + +| Name | Description | Values | +| ---- | ----------- | ------ | +| status | The current status of the managed entity. | Str: ``red``, ``yellow``, ``green``, ``gray`` | +| power_state | The current power state of the virtual machine. | Str: ``on``, ``off``, ``suspended``, ``unknown`` | + ### vcenter.host.cpu.capacity Total CPU capacity of the host system. diff --git a/receiver/vcenterreceiver/internal/metadata/generated_config.go b/receiver/vcenterreceiver/internal/metadata/generated_config.go index 7267d89e15f0..92ed3650ad50 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_config.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_config.go @@ -35,6 +35,13 @@ type MetricsConfig struct { VcenterClusterMemoryLimit MetricConfig `mapstructure:"vcenter.cluster.memory.limit"` VcenterClusterVMCount MetricConfig `mapstructure:"vcenter.cluster.vm.count"` VcenterClusterVMTemplateCount MetricConfig `mapstructure:"vcenter.cluster.vm_template.count"` + VcenterDatacenterClusterCount MetricConfig `mapstructure:"vcenter.datacenter.cluster.count"` + VcenterDatacenterCPULimit MetricConfig `mapstructure:"vcenter.datacenter.cpu.limit"` + VcenterDatacenterDatastoreCount MetricConfig `mapstructure:"vcenter.datacenter.datastore.count"` + VcenterDatacenterDiskSpace MetricConfig `mapstructure:"vcenter.datacenter.disk.space"` + VcenterDatacenterHostCount MetricConfig `mapstructure:"vcenter.datacenter.host.count"` + VcenterDatacenterMemoryLimit MetricConfig `mapstructure:"vcenter.datacenter.memory.limit"` + VcenterDatacenterVMCount MetricConfig `mapstructure:"vcenter.datacenter.vm.count"` VcenterDatastoreDiskUsage MetricConfig `mapstructure:"vcenter.datastore.disk.usage"` VcenterDatastoreDiskUtilization MetricConfig `mapstructure:"vcenter.datastore.disk.utilization"` VcenterHostCPUCapacity MetricConfig `mapstructure:"vcenter.host.cpu.capacity"` @@ -100,6 +107,27 @@ func DefaultMetricsConfig() MetricsConfig { VcenterClusterVMTemplateCount: MetricConfig{ Enabled: true, }, + VcenterDatacenterClusterCount: MetricConfig{ + Enabled: false, + }, + VcenterDatacenterCPULimit: MetricConfig{ + Enabled: false, + }, + VcenterDatacenterDatastoreCount: MetricConfig{ + Enabled: false, + }, + VcenterDatacenterDiskSpace: MetricConfig{ + Enabled: false, + }, + VcenterDatacenterHostCount: MetricConfig{ + Enabled: false, + }, + VcenterDatacenterMemoryLimit: MetricConfig{ + Enabled: false, + }, + VcenterDatacenterVMCount: MetricConfig{ + Enabled: false, + }, VcenterDatastoreDiskUsage: MetricConfig{ Enabled: true, }, diff --git a/receiver/vcenterreceiver/internal/metadata/generated_config_test.go b/receiver/vcenterreceiver/internal/metadata/generated_config_test.go index 69327b3fffee..33b8803cca26 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_config_test.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_config_test.go @@ -32,6 +32,13 @@ func TestMetricsBuilderConfig(t *testing.T) { VcenterClusterMemoryLimit: MetricConfig{Enabled: true}, VcenterClusterVMCount: MetricConfig{Enabled: true}, VcenterClusterVMTemplateCount: MetricConfig{Enabled: true}, + VcenterDatacenterClusterCount: MetricConfig{Enabled: true}, + VcenterDatacenterCPULimit: MetricConfig{Enabled: true}, + VcenterDatacenterDatastoreCount: MetricConfig{Enabled: true}, + VcenterDatacenterDiskSpace: MetricConfig{Enabled: true}, + VcenterDatacenterHostCount: MetricConfig{Enabled: true}, + VcenterDatacenterMemoryLimit: MetricConfig{Enabled: true}, + VcenterDatacenterVMCount: MetricConfig{Enabled: true}, VcenterDatastoreDiskUsage: MetricConfig{Enabled: true}, VcenterDatastoreDiskUtilization: MetricConfig{Enabled: true}, VcenterHostCPUCapacity: MetricConfig{Enabled: true}, @@ -100,6 +107,13 @@ func TestMetricsBuilderConfig(t *testing.T) { VcenterClusterMemoryLimit: MetricConfig{Enabled: false}, VcenterClusterVMCount: MetricConfig{Enabled: false}, VcenterClusterVMTemplateCount: MetricConfig{Enabled: false}, + VcenterDatacenterClusterCount: MetricConfig{Enabled: false}, + VcenterDatacenterCPULimit: MetricConfig{Enabled: false}, + VcenterDatacenterDatastoreCount: MetricConfig{Enabled: false}, + VcenterDatacenterDiskSpace: MetricConfig{Enabled: false}, + VcenterDatacenterHostCount: MetricConfig{Enabled: false}, + VcenterDatacenterMemoryLimit: MetricConfig{Enabled: false}, + VcenterDatacenterVMCount: MetricConfig{Enabled: false}, VcenterDatastoreDiskUsage: MetricConfig{Enabled: false}, VcenterDatastoreDiskUtilization: MetricConfig{Enabled: false}, VcenterHostCPUCapacity: MetricConfig{Enabled: false}, diff --git a/receiver/vcenterreceiver/internal/metadata/generated_metrics.go b/receiver/vcenterreceiver/internal/metadata/generated_metrics.go index 509e59e13dff..0409067cf341 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_metrics.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_metrics.go @@ -116,6 +116,74 @@ var MapAttributeDiskType = map[string]AttributeDiskType{ "physical": AttributeDiskTypePhysical, } +// AttributeEntityStatus specifies the a value entity_status attribute. +type AttributeEntityStatus int + +const ( + _ AttributeEntityStatus = iota + AttributeEntityStatusRed + AttributeEntityStatusYellow + AttributeEntityStatusGreen + AttributeEntityStatusGray +) + +// String returns the string representation of the AttributeEntityStatus. +func (av AttributeEntityStatus) String() string { + switch av { + case AttributeEntityStatusRed: + return "red" + case AttributeEntityStatusYellow: + return "yellow" + case AttributeEntityStatusGreen: + return "green" + case AttributeEntityStatusGray: + return "gray" + } + return "" +} + +// MapAttributeEntityStatus is a helper map of string to AttributeEntityStatus attribute value. +var MapAttributeEntityStatus = map[string]AttributeEntityStatus{ + "red": AttributeEntityStatusRed, + "yellow": AttributeEntityStatusYellow, + "green": AttributeEntityStatusGreen, + "gray": AttributeEntityStatusGray, +} + +// AttributeHostPowerState specifies the a value host_power_state attribute. +type AttributeHostPowerState int + +const ( + _ AttributeHostPowerState = iota + AttributeHostPowerStateOn + AttributeHostPowerStateOff + AttributeHostPowerStateStandby + AttributeHostPowerStateUnknown +) + +// String returns the string representation of the AttributeHostPowerState. +func (av AttributeHostPowerState) String() string { + switch av { + case AttributeHostPowerStateOn: + return "on" + case AttributeHostPowerStateOff: + return "off" + case AttributeHostPowerStateStandby: + return "standby" + case AttributeHostPowerStateUnknown: + return "unknown" + } + return "" +} + +// MapAttributeHostPowerState is a helper map of string to AttributeHostPowerState attribute value. +var MapAttributeHostPowerState = map[string]AttributeHostPowerState{ + "on": AttributeHostPowerStateOn, + "off": AttributeHostPowerStateOff, + "standby": AttributeHostPowerStateStandby, + "unknown": AttributeHostPowerStateUnknown, +} + // AttributeMemoryGrantedType specifies the a value memory_granted_type attribute. type AttributeMemoryGrantedType int @@ -206,6 +274,7 @@ const ( AttributeVMCountPowerStateOn AttributeVMCountPowerStateOff AttributeVMCountPowerStateSuspended + AttributeVMCountPowerStateUnknown ) // String returns the string representation of the AttributeVMCountPowerState. @@ -217,6 +286,8 @@ func (av AttributeVMCountPowerState) String() string { return "off" case AttributeVMCountPowerStateSuspended: return "suspended" + case AttributeVMCountPowerStateUnknown: + return "unknown" } return "" } @@ -226,6 +297,7 @@ var MapAttributeVMCountPowerState = map[string]AttributeVMCountPowerState{ "on": AttributeVMCountPowerStateOn, "off": AttributeVMCountPowerStateOff, "suspended": AttributeVMCountPowerStateSuspended, + "unknown": AttributeVMCountPowerStateUnknown, } type metricVcenterClusterCPUEffective struct { @@ -589,6 +661,373 @@ func newMetricVcenterClusterVMTemplateCount(cfg MetricConfig) metricVcenterClust return m } +type metricVcenterDatacenterClusterCount struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.cluster.count metric with initial data. +func (m *metricVcenterDatacenterClusterCount) init() { + m.data.SetName("vcenter.datacenter.cluster.count") + m.data.SetDescription("The number of clusters in the datacenter.") + m.data.SetUnit("{clusters}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricVcenterDatacenterClusterCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, entityStatusAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("status", entityStatusAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterClusterCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterClusterCount) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterClusterCount(cfg MetricConfig) metricVcenterDatacenterClusterCount { + m := metricVcenterDatacenterClusterCount{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricVcenterDatacenterCPULimit struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.cpu.limit metric with initial data. +func (m *metricVcenterDatacenterCPULimit) init() { + m.data.SetName("vcenter.datacenter.cpu.limit") + m.data.SetDescription("The total amount of CPU available to the datacenter.") + m.data.SetUnit("{MHz}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) +} + +func (m *metricVcenterDatacenterCPULimit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterCPULimit) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterCPULimit) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterCPULimit(cfg MetricConfig) metricVcenterDatacenterCPULimit { + m := metricVcenterDatacenterCPULimit{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricVcenterDatacenterDatastoreCount struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.datastore.count metric with initial data. +func (m *metricVcenterDatacenterDatastoreCount) init() { + m.data.SetName("vcenter.datacenter.datastore.count") + m.data.SetDescription("The number of datastores in the datacenter.") + m.data.SetUnit("{datastores}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) +} + +func (m *metricVcenterDatacenterDatastoreCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterDatastoreCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterDatastoreCount) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterDatastoreCount(cfg MetricConfig) metricVcenterDatacenterDatastoreCount { + m := metricVcenterDatacenterDatastoreCount{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricVcenterDatacenterDiskSpace struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.disk.space metric with initial data. +func (m *metricVcenterDatacenterDiskSpace) init() { + m.data.SetName("vcenter.datacenter.disk.space") + m.data.SetDescription("The amount of available and used disk space in the datacenter.") + m.data.SetUnit("By") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricVcenterDatacenterDiskSpace) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, diskStateAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("disk_state", diskStateAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterDiskSpace) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterDiskSpace) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterDiskSpace(cfg MetricConfig) metricVcenterDatacenterDiskSpace { + m := metricVcenterDatacenterDiskSpace{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricVcenterDatacenterHostCount struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.host.count metric with initial data. +func (m *metricVcenterDatacenterHostCount) init() { + m.data.SetName("vcenter.datacenter.host.count") + m.data.SetDescription("The number of hosts in the datacenter.") + m.data.SetUnit("{hosts}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricVcenterDatacenterHostCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, entityStatusAttributeValue string, hostPowerStateAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("status", entityStatusAttributeValue) + dp.Attributes().PutStr("power_state", hostPowerStateAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterHostCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterHostCount) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterHostCount(cfg MetricConfig) metricVcenterDatacenterHostCount { + m := metricVcenterDatacenterHostCount{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricVcenterDatacenterMemoryLimit struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.memory.limit metric with initial data. +func (m *metricVcenterDatacenterMemoryLimit) init() { + m.data.SetName("vcenter.datacenter.memory.limit") + m.data.SetDescription("The total amount of memory available to the datacenter.") + m.data.SetUnit("By") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) +} + +func (m *metricVcenterDatacenterMemoryLimit) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterMemoryLimit) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterMemoryLimit) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterMemoryLimit(cfg MetricConfig) metricVcenterDatacenterMemoryLimit { + m := metricVcenterDatacenterMemoryLimit{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + +type metricVcenterDatacenterVMCount struct { + data pmetric.Metric // data buffer for generated metric. + config MetricConfig // metric config provided by user. + capacity int // max observed number of data points added to the metric. +} + +// init fills vcenter.datacenter.vm.count metric with initial data. +func (m *metricVcenterDatacenterVMCount) init() { + m.data.SetName("vcenter.datacenter.vm.count") + m.data.SetDescription("The number of VM's in the datacenter.") + m.data.SetUnit("{virtual_machines}") + m.data.SetEmptySum() + m.data.Sum().SetIsMonotonic(false) + m.data.Sum().SetAggregationTemporality(pmetric.AggregationTemporalityCumulative) + m.data.Sum().DataPoints().EnsureCapacity(m.capacity) +} + +func (m *metricVcenterDatacenterVMCount) recordDataPoint(start pcommon.Timestamp, ts pcommon.Timestamp, val int64, entityStatusAttributeValue string, vmCountPowerStateAttributeValue string) { + if !m.config.Enabled { + return + } + dp := m.data.Sum().DataPoints().AppendEmpty() + dp.SetStartTimestamp(start) + dp.SetTimestamp(ts) + dp.SetIntValue(val) + dp.Attributes().PutStr("status", entityStatusAttributeValue) + dp.Attributes().PutStr("power_state", vmCountPowerStateAttributeValue) +} + +// updateCapacity saves max length of data point slices that will be used for the slice capacity. +func (m *metricVcenterDatacenterVMCount) updateCapacity() { + if m.data.Sum().DataPoints().Len() > m.capacity { + m.capacity = m.data.Sum().DataPoints().Len() + } +} + +// emit appends recorded metric data to a metrics slice and prepares it for recording another set of data points. +func (m *metricVcenterDatacenterVMCount) emit(metrics pmetric.MetricSlice) { + if m.config.Enabled && m.data.Sum().DataPoints().Len() > 0 { + m.updateCapacity() + m.data.MoveTo(metrics.AppendEmpty()) + m.init() + } +} + +func newMetricVcenterDatacenterVMCount(cfg MetricConfig) metricVcenterDatacenterVMCount { + m := metricVcenterDatacenterVMCount{config: cfg} + if cfg.Enabled { + m.data = pmetric.NewMetric() + m.init() + } + return m +} + type metricVcenterDatastoreDiskUsage struct { data pmetric.Metric // data buffer for generated metric. config MetricConfig // metric config provided by user. @@ -2664,6 +3103,13 @@ type MetricsBuilder struct { metricVcenterClusterMemoryLimit metricVcenterClusterMemoryLimit metricVcenterClusterVMCount metricVcenterClusterVMCount metricVcenterClusterVMTemplateCount metricVcenterClusterVMTemplateCount + metricVcenterDatacenterClusterCount metricVcenterDatacenterClusterCount + metricVcenterDatacenterCPULimit metricVcenterDatacenterCPULimit + metricVcenterDatacenterDatastoreCount metricVcenterDatacenterDatastoreCount + metricVcenterDatacenterDiskSpace metricVcenterDatacenterDiskSpace + metricVcenterDatacenterHostCount metricVcenterDatacenterHostCount + metricVcenterDatacenterMemoryLimit metricVcenterDatacenterMemoryLimit + metricVcenterDatacenterVMCount metricVcenterDatacenterVMCount metricVcenterDatastoreDiskUsage metricVcenterDatastoreDiskUsage metricVcenterDatastoreDiskUtilization metricVcenterDatastoreDiskUtilization metricVcenterHostCPUCapacity metricVcenterHostCPUCapacity @@ -2717,6 +3163,27 @@ func WithStartTime(startTime pcommon.Timestamp) metricBuilderOption { } func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, options ...metricBuilderOption) *MetricsBuilder { + if !mbc.Metrics.VcenterDatacenterClusterCount.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.cluster.count`: this metric will be enabled by default starting in release v0.106.0") + } + if !mbc.Metrics.VcenterDatacenterCPULimit.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.cpu.limit`: this metric will be enabled by default starting in release v0.106.0") + } + if !mbc.Metrics.VcenterDatacenterDatastoreCount.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.datastore.count`: this metric will be enabled by default starting in release v0.106.0") + } + if !mbc.Metrics.VcenterDatacenterDiskSpace.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.disk.space`: this metric will be enabled by default starting in release v0.106.0") + } + if !mbc.Metrics.VcenterDatacenterHostCount.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.host.count`: this metric will be enabled by default starting in release v0.106.0") + } + if !mbc.Metrics.VcenterDatacenterMemoryLimit.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.memory.limit`: this metric will be enabled by default starting in release v0.106.0") + } + if !mbc.Metrics.VcenterDatacenterVMCount.enabledSetByUser { + settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.vm.count`: this metric will be enabled by default starting in release v0.106.0") + } if !mbc.Metrics.VcenterHostCPUCapacity.enabledSetByUser { settings.Logger.Warn("[WARNING] Please set `enabled` field explicitly for `vcenter.host.cpu.capacity`: this metric will be enabled by default starting in release v0.105.0") } @@ -2750,6 +3217,13 @@ func NewMetricsBuilder(mbc MetricsBuilderConfig, settings receiver.Settings, opt metricVcenterClusterMemoryLimit: newMetricVcenterClusterMemoryLimit(mbc.Metrics.VcenterClusterMemoryLimit), metricVcenterClusterVMCount: newMetricVcenterClusterVMCount(mbc.Metrics.VcenterClusterVMCount), metricVcenterClusterVMTemplateCount: newMetricVcenterClusterVMTemplateCount(mbc.Metrics.VcenterClusterVMTemplateCount), + metricVcenterDatacenterClusterCount: newMetricVcenterDatacenterClusterCount(mbc.Metrics.VcenterDatacenterClusterCount), + metricVcenterDatacenterCPULimit: newMetricVcenterDatacenterCPULimit(mbc.Metrics.VcenterDatacenterCPULimit), + metricVcenterDatacenterDatastoreCount: newMetricVcenterDatacenterDatastoreCount(mbc.Metrics.VcenterDatacenterDatastoreCount), + metricVcenterDatacenterDiskSpace: newMetricVcenterDatacenterDiskSpace(mbc.Metrics.VcenterDatacenterDiskSpace), + metricVcenterDatacenterHostCount: newMetricVcenterDatacenterHostCount(mbc.Metrics.VcenterDatacenterHostCount), + metricVcenterDatacenterMemoryLimit: newMetricVcenterDatacenterMemoryLimit(mbc.Metrics.VcenterDatacenterMemoryLimit), + metricVcenterDatacenterVMCount: newMetricVcenterDatacenterVMCount(mbc.Metrics.VcenterDatacenterVMCount), metricVcenterDatastoreDiskUsage: newMetricVcenterDatastoreDiskUsage(mbc.Metrics.VcenterDatastoreDiskUsage), metricVcenterDatastoreDiskUtilization: newMetricVcenterDatastoreDiskUtilization(mbc.Metrics.VcenterDatastoreDiskUtilization), metricVcenterHostCPUCapacity: newMetricVcenterHostCPUCapacity(mbc.Metrics.VcenterHostCPUCapacity), @@ -2933,6 +3407,13 @@ func (mb *MetricsBuilder) EmitForResource(rmo ...ResourceMetricsOption) { mb.metricVcenterClusterMemoryLimit.emit(ils.Metrics()) mb.metricVcenterClusterVMCount.emit(ils.Metrics()) mb.metricVcenterClusterVMTemplateCount.emit(ils.Metrics()) + mb.metricVcenterDatacenterClusterCount.emit(ils.Metrics()) + mb.metricVcenterDatacenterCPULimit.emit(ils.Metrics()) + mb.metricVcenterDatacenterDatastoreCount.emit(ils.Metrics()) + mb.metricVcenterDatacenterDiskSpace.emit(ils.Metrics()) + mb.metricVcenterDatacenterHostCount.emit(ils.Metrics()) + mb.metricVcenterDatacenterMemoryLimit.emit(ils.Metrics()) + mb.metricVcenterDatacenterVMCount.emit(ils.Metrics()) mb.metricVcenterDatastoreDiskUsage.emit(ils.Metrics()) mb.metricVcenterDatastoreDiskUtilization.emit(ils.Metrics()) mb.metricVcenterHostCPUCapacity.emit(ils.Metrics()) @@ -3039,6 +3520,41 @@ func (mb *MetricsBuilder) RecordVcenterClusterVMTemplateCountDataPoint(ts pcommo mb.metricVcenterClusterVMTemplateCount.recordDataPoint(mb.startTime, ts, val) } +// RecordVcenterDatacenterClusterCountDataPoint adds a data point to vcenter.datacenter.cluster.count metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterClusterCountDataPoint(ts pcommon.Timestamp, val int64, entityStatusAttributeValue AttributeEntityStatus) { + mb.metricVcenterDatacenterClusterCount.recordDataPoint(mb.startTime, ts, val, entityStatusAttributeValue.String()) +} + +// RecordVcenterDatacenterCPULimitDataPoint adds a data point to vcenter.datacenter.cpu.limit metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterCPULimitDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricVcenterDatacenterCPULimit.recordDataPoint(mb.startTime, ts, val) +} + +// RecordVcenterDatacenterDatastoreCountDataPoint adds a data point to vcenter.datacenter.datastore.count metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterDatastoreCountDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricVcenterDatacenterDatastoreCount.recordDataPoint(mb.startTime, ts, val) +} + +// RecordVcenterDatacenterDiskSpaceDataPoint adds a data point to vcenter.datacenter.disk.space metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterDiskSpaceDataPoint(ts pcommon.Timestamp, val int64, diskStateAttributeValue AttributeDiskState) { + mb.metricVcenterDatacenterDiskSpace.recordDataPoint(mb.startTime, ts, val, diskStateAttributeValue.String()) +} + +// RecordVcenterDatacenterHostCountDataPoint adds a data point to vcenter.datacenter.host.count metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterHostCountDataPoint(ts pcommon.Timestamp, val int64, entityStatusAttributeValue AttributeEntityStatus, hostPowerStateAttributeValue AttributeHostPowerState) { + mb.metricVcenterDatacenterHostCount.recordDataPoint(mb.startTime, ts, val, entityStatusAttributeValue.String(), hostPowerStateAttributeValue.String()) +} + +// RecordVcenterDatacenterMemoryLimitDataPoint adds a data point to vcenter.datacenter.memory.limit metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterMemoryLimitDataPoint(ts pcommon.Timestamp, val int64) { + mb.metricVcenterDatacenterMemoryLimit.recordDataPoint(mb.startTime, ts, val) +} + +// RecordVcenterDatacenterVMCountDataPoint adds a data point to vcenter.datacenter.vm.count metric. +func (mb *MetricsBuilder) RecordVcenterDatacenterVMCountDataPoint(ts pcommon.Timestamp, val int64, entityStatusAttributeValue AttributeEntityStatus, vmCountPowerStateAttributeValue AttributeVMCountPowerState) { + mb.metricVcenterDatacenterVMCount.recordDataPoint(mb.startTime, ts, val, entityStatusAttributeValue.String(), vmCountPowerStateAttributeValue.String()) +} + // RecordVcenterDatastoreDiskUsageDataPoint adds a data point to vcenter.datastore.disk.usage metric. func (mb *MetricsBuilder) RecordVcenterDatastoreDiskUsageDataPoint(ts pcommon.Timestamp, val int64, diskStateAttributeValue AttributeDiskState) { mb.metricVcenterDatastoreDiskUsage.recordDataPoint(mb.startTime, ts, val, diskStateAttributeValue.String()) diff --git a/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go b/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go index 35265cd370f6..4934aaa6d594 100644 --- a/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go +++ b/receiver/vcenterreceiver/internal/metadata/generated_metrics_test.go @@ -62,6 +62,34 @@ func TestMetricsBuilder(t *testing.T) { mb := NewMetricsBuilder(loadMetricsBuilderConfig(t, test.name), settings, WithStartTime(start)) expectedWarnings := 0 + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.cluster.count`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.cpu.limit`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.datastore.count`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.disk.space`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.host.count`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.memory.limit`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } + if test.metricsSet == testDataSetDefault { + assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.datacenter.vm.count`: this metric will be enabled by default starting in release v0.106.0", observedLogs.All()[expectedWarnings].Message) + expectedWarnings++ + } if test.metricsSet == testDataSetDefault { assert.Equal(t, "[WARNING] Please set `enabled` field explicitly for `vcenter.host.cpu.capacity`: this metric will be enabled by default starting in release v0.105.0", observedLogs.All()[expectedWarnings].Message) expectedWarnings++ @@ -124,6 +152,27 @@ func TestMetricsBuilder(t *testing.T) { allMetricsCount++ mb.RecordVcenterClusterVMTemplateCountDataPoint(ts, 1) + allMetricsCount++ + mb.RecordVcenterDatacenterClusterCountDataPoint(ts, 1, AttributeEntityStatusRed) + + allMetricsCount++ + mb.RecordVcenterDatacenterCPULimitDataPoint(ts, 1) + + allMetricsCount++ + mb.RecordVcenterDatacenterDatastoreCountDataPoint(ts, 1) + + allMetricsCount++ + mb.RecordVcenterDatacenterDiskSpaceDataPoint(ts, 1, AttributeDiskStateAvailable) + + allMetricsCount++ + mb.RecordVcenterDatacenterHostCountDataPoint(ts, 1, AttributeEntityStatusRed, AttributeHostPowerStateOn) + + allMetricsCount++ + mb.RecordVcenterDatacenterMemoryLimitDataPoint(ts, 1) + + allMetricsCount++ + mb.RecordVcenterDatacenterVMCountDataPoint(ts, 1, AttributeEntityStatusRed, AttributeVMCountPowerStateOn) + defaultMetricsCount++ allMetricsCount++ mb.RecordVcenterDatastoreDiskUsageDataPoint(ts, 1, AttributeDiskStateAvailable) @@ -416,6 +465,122 @@ func TestMetricsBuilder(t *testing.T) { assert.Equal(t, ts, dp.Timestamp()) assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) assert.Equal(t, int64(1), dp.IntValue()) + case "vcenter.datacenter.cluster.count": + assert.False(t, validatedMetrics["vcenter.datacenter.cluster.count"], "Found a duplicate in the metrics slice: vcenter.datacenter.cluster.count") + validatedMetrics["vcenter.datacenter.cluster.count"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The number of clusters in the datacenter.", ms.At(i).Description()) + assert.Equal(t, "{clusters}", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("status") + assert.True(t, ok) + assert.EqualValues(t, "red", attrVal.Str()) + case "vcenter.datacenter.cpu.limit": + assert.False(t, validatedMetrics["vcenter.datacenter.cpu.limit"], "Found a duplicate in the metrics slice: vcenter.datacenter.cpu.limit") + validatedMetrics["vcenter.datacenter.cpu.limit"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The total amount of CPU available to the datacenter.", ms.At(i).Description()) + assert.Equal(t, "{MHz}", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + case "vcenter.datacenter.datastore.count": + assert.False(t, validatedMetrics["vcenter.datacenter.datastore.count"], "Found a duplicate in the metrics slice: vcenter.datacenter.datastore.count") + validatedMetrics["vcenter.datacenter.datastore.count"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The number of datastores in the datacenter.", ms.At(i).Description()) + assert.Equal(t, "{datastores}", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + case "vcenter.datacenter.disk.space": + assert.False(t, validatedMetrics["vcenter.datacenter.disk.space"], "Found a duplicate in the metrics slice: vcenter.datacenter.disk.space") + validatedMetrics["vcenter.datacenter.disk.space"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The amount of available and used disk space in the datacenter.", ms.At(i).Description()) + assert.Equal(t, "By", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("disk_state") + assert.True(t, ok) + assert.EqualValues(t, "available", attrVal.Str()) + case "vcenter.datacenter.host.count": + assert.False(t, validatedMetrics["vcenter.datacenter.host.count"], "Found a duplicate in the metrics slice: vcenter.datacenter.host.count") + validatedMetrics["vcenter.datacenter.host.count"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The number of hosts in the datacenter.", ms.At(i).Description()) + assert.Equal(t, "{hosts}", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("status") + assert.True(t, ok) + assert.EqualValues(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("power_state") + assert.True(t, ok) + assert.EqualValues(t, "on", attrVal.Str()) + case "vcenter.datacenter.memory.limit": + assert.False(t, validatedMetrics["vcenter.datacenter.memory.limit"], "Found a duplicate in the metrics slice: vcenter.datacenter.memory.limit") + validatedMetrics["vcenter.datacenter.memory.limit"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The total amount of memory available to the datacenter.", ms.At(i).Description()) + assert.Equal(t, "By", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + case "vcenter.datacenter.vm.count": + assert.False(t, validatedMetrics["vcenter.datacenter.vm.count"], "Found a duplicate in the metrics slice: vcenter.datacenter.vm.count") + validatedMetrics["vcenter.datacenter.vm.count"] = true + assert.Equal(t, pmetric.MetricTypeSum, ms.At(i).Type()) + assert.Equal(t, 1, ms.At(i).Sum().DataPoints().Len()) + assert.Equal(t, "The number of VM's in the datacenter.", ms.At(i).Description()) + assert.Equal(t, "{virtual_machines}", ms.At(i).Unit()) + assert.Equal(t, false, ms.At(i).Sum().IsMonotonic()) + assert.Equal(t, pmetric.AggregationTemporalityCumulative, ms.At(i).Sum().AggregationTemporality()) + dp := ms.At(i).Sum().DataPoints().At(0) + assert.Equal(t, start, dp.StartTimestamp()) + assert.Equal(t, ts, dp.Timestamp()) + assert.Equal(t, pmetric.NumberDataPointValueTypeInt, dp.ValueType()) + assert.Equal(t, int64(1), dp.IntValue()) + attrVal, ok := dp.Attributes().Get("status") + assert.True(t, ok) + assert.EqualValues(t, "red", attrVal.Str()) + attrVal, ok = dp.Attributes().Get("power_state") + assert.True(t, ok) + assert.EqualValues(t, "on", attrVal.Str()) case "vcenter.datastore.disk.usage": assert.False(t, validatedMetrics["vcenter.datastore.disk.usage"], "Found a duplicate in the metrics slice: vcenter.datastore.disk.usage") validatedMetrics["vcenter.datastore.disk.usage"] = true diff --git a/receiver/vcenterreceiver/internal/metadata/testdata/config.yaml b/receiver/vcenterreceiver/internal/metadata/testdata/config.yaml index 410fb19f0079..521098442bbc 100644 --- a/receiver/vcenterreceiver/internal/metadata/testdata/config.yaml +++ b/receiver/vcenterreceiver/internal/metadata/testdata/config.yaml @@ -15,6 +15,20 @@ all_set: enabled: true vcenter.cluster.vm_template.count: enabled: true + vcenter.datacenter.cluster.count: + enabled: true + vcenter.datacenter.cpu.limit: + enabled: true + vcenter.datacenter.datastore.count: + enabled: true + vcenter.datacenter.disk.space: + enabled: true + vcenter.datacenter.host.count: + enabled: true + vcenter.datacenter.memory.limit: + enabled: true + vcenter.datacenter.vm.count: + enabled: true vcenter.datastore.disk.usage: enabled: true vcenter.datastore.disk.utilization: @@ -136,6 +150,20 @@ none_set: enabled: false vcenter.cluster.vm_template.count: enabled: false + vcenter.datacenter.cluster.count: + enabled: false + vcenter.datacenter.cpu.limit: + enabled: false + vcenter.datacenter.datastore.count: + enabled: false + vcenter.datacenter.disk.space: + enabled: false + vcenter.datacenter.host.count: + enabled: false + vcenter.datacenter.memory.limit: + enabled: false + vcenter.datacenter.vm.count: + enabled: false vcenter.datastore.disk.usage: enabled: false vcenter.datastore.disk.utilization: diff --git a/receiver/vcenterreceiver/internal/mockserver/responses/host-default-properties.xml b/receiver/vcenterreceiver/internal/mockserver/responses/host-default-properties.xml index 2f1ce3c9c456..400fead184d8 100644 --- a/receiver/vcenterreceiver/internal/mockserver/responses/host-default-properties.xml +++ b/receiver/vcenterreceiver/internal/mockserver/responses/host-default-properties.xml @@ -33,6 +33,14 @@ summary.quickStats.overallMemoryUsage 140833 + + runtime.powerState + poweredOn + + + summary.overallStatus + green + vm @@ -74,6 +82,14 @@ summary.quickStats.overallMemoryUsage 140833 + + runtime.powerState + poweredOn + + + summary.overallStatus + green + vm diff --git a/receiver/vcenterreceiver/internal/mockserver/responses/vm-default-properties.xml b/receiver/vcenterreceiver/internal/mockserver/responses/vm-default-properties.xml index e46edc6fd3eb..c1219271bcf2 100644 --- a/receiver/vcenterreceiver/internal/mockserver/responses/vm-default-properties.xml +++ b/receiver/vcenterreceiver/internal/mockserver/responses/vm-default-properties.xml @@ -33,6 +33,10 @@ runtime.powerState poweredOn + + summary.overallStatus + green + summary.config.memorySizeMB 16384 @@ -102,6 +106,10 @@ runtime.powerState poweredOn + + summary.overallStatus + green + summary.config.memorySizeMB 16384 @@ -171,6 +179,10 @@ runtime.powerState poweredOn + + summary.overallStatus + yellow + summary.config.memorySizeMB 16384 diff --git a/receiver/vcenterreceiver/metadata.yaml b/receiver/vcenterreceiver/metadata.yaml index f59025c48437..d748144b34c7 100644 --- a/receiver/vcenterreceiver/metadata.yaml +++ b/receiver/vcenterreceiver/metadata.yaml @@ -98,6 +98,15 @@ attributes: type: bool name_override: effective description: Whether the host is effective in the vCenter cluster. + host_power_state: + name_override: power_state + description: The current power state of the host. + type: string + enum: + - "on" + - "off" + - "standby" + - "unknown" disk_direction: name_override: direction description: The direction of disk latency. @@ -120,12 +129,99 @@ attributes: - "on" - "off" - "suspended" + - "unknown" + entity_status: + name_override: status + description: The current status of the managed entity. + type: string + enum: + - "red" + - "yellow" + - "green" + - "gray" object_name: name_override: object description: The object on the virtual machine or host that is being reported on. type: string metrics: + vcenter.datacenter.cluster.count: + enabled: false + description: The number of clusters in the datacenter. + unit: "{clusters}" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [entity_status] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" + vcenter.datacenter.host.count: + enabled: false + description: The number of hosts in the datacenter. + unit: "{hosts}" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [entity_status, host_power_state] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" + vcenter.datacenter.vm.count: + enabled: false + description: The number of VM's in the datacenter. + unit: "{virtual_machines}" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [entity_status, vm_count_power_state] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" + vcenter.datacenter.datastore.count: + enabled: false + description: The number of datastores in the datacenter. + unit: "{datastores}" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" + vcenter.datacenter.disk.space: + enabled: false + description: The amount of available and used disk space in the datacenter. + unit: "By" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [disk_state] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" + vcenter.datacenter.cpu.limit: + enabled: false + description: The total amount of CPU available to the datacenter. + unit: "{MHz}" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" + vcenter.datacenter.memory.limit: + enabled: false + description: The total amount of memory available to the datacenter. + unit: "By" + sum: + monotonic: false + value_type: int + aggregation_temporality: cumulative + attributes: [] + warnings: + if_enabled_not_set: "this metric will be enabled by default starting in release v0.106.0" vcenter.cluster.cpu.limit: enabled: true description: The amount of CPU available to the cluster. diff --git a/receiver/vcenterreceiver/metrics.go b/receiver/vcenterreceiver/metrics.go index f6299617181f..fbe7e54dc2a7 100644 --- a/receiver/vcenterreceiver/metrics.go +++ b/receiver/vcenterreceiver/metrics.go @@ -6,6 +6,7 @@ package vcenterreceiver // import "github.com/open-telemetry/opentelemetry-colle import ( "github.com/vmware/govmomi/performance" "github.com/vmware/govmomi/vim25/mo" + "github.com/vmware/govmomi/vim25/types" "go.opentelemetry.io/collector/featuregate" "go.opentelemetry.io/collector/pdata/pcommon" @@ -19,6 +20,94 @@ var enableResourcePoolMemoryUsageAttr = featuregate.GlobalRegistry().MustRegiste featuregate.WithRegisterDescription("Enables the memory usage type attribute for the vcenter.resource_pool.memory.usage metric"), featuregate.WithRegisterToVersion("v0.106.0")) +// recordDatacenterStats records stat metrics for a vSphere Datacenter +func (v *vcenterMetricScraper) recordDatacenterStats( + ts pcommon.Timestamp, + dcStat *DatacenterStats, +) { + // Cluster metrics + v.mb.RecordVcenterDatacenterClusterCountDataPoint(ts, dcStat.ClusterStatusCounts[types.ManagedEntityStatusRed], metadata.AttributeEntityStatusRed) + v.mb.RecordVcenterDatacenterClusterCountDataPoint(ts, dcStat.ClusterStatusCounts[types.ManagedEntityStatusYellow], metadata.AttributeEntityStatusYellow) + v.mb.RecordVcenterDatacenterClusterCountDataPoint(ts, dcStat.ClusterStatusCounts[types.ManagedEntityStatusGreen], metadata.AttributeEntityStatusGreen) + v.mb.RecordVcenterDatacenterClusterCountDataPoint(ts, dcStat.ClusterStatusCounts[types.ManagedEntityStatusGray], metadata.AttributeEntityStatusGray) + + // VM metrics + for powerState, vmStatusCounts := range dcStat.VMStats { + for status, count := range vmStatusCounts { + entityStatus, okStatus := getEntityStatusAttribute(status) + vmPowerState, okPowerState := getVMPowerStateAttribute(powerState) + switch { + case okStatus && okPowerState: + v.mb.RecordVcenterDatacenterVMCountDataPoint(ts, count, entityStatus, vmPowerState) + case !okStatus && okPowerState: + v.mb.RecordVcenterDatacenterVMCountDataPoint(ts, count, metadata.AttributeEntityStatusGray, vmPowerState) + case okStatus && !okPowerState: + v.mb.RecordVcenterDatacenterVMCountDataPoint(ts, count, entityStatus, metadata.AttributeVMCountPowerStateUnknown) + default: + v.mb.RecordVcenterDatacenterVMCountDataPoint(ts, count, metadata.AttributeEntityStatusGray, metadata.AttributeVMCountPowerStateUnknown) + } + } + } + + // Host metrics + for powerState, hostStatusCounts := range dcStat.HostStats { + for status, count := range hostStatusCounts { + entityStatus, okStatus := getEntityStatusAttribute(status) + hostPowerState, okPowerState := getHostPowerStateAttribute(powerState) + switch { + case okStatus && okPowerState: + v.mb.RecordVcenterDatacenterHostCountDataPoint(ts, count, entityStatus, hostPowerState) + case !okStatus && okPowerState: + v.mb.RecordVcenterDatacenterHostCountDataPoint(ts, count, metadata.AttributeEntityStatusGray, hostPowerState) + case okStatus && !okPowerState: + v.mb.RecordVcenterDatacenterHostCountDataPoint(ts, count, entityStatus, metadata.AttributeHostPowerStateUnknown) + default: + v.mb.RecordVcenterDatacenterHostCountDataPoint(ts, count, metadata.AttributeEntityStatusGray, metadata.AttributeHostPowerStateUnknown) + } + } + } + + // Datacenter stats + v.mb.RecordVcenterDatacenterDatastoreCountDataPoint(ts, dcStat.DatastoreCount) + v.mb.RecordVcenterDatacenterDiskSpaceDataPoint(ts, (dcStat.DiskCapacity - dcStat.DiskFree), metadata.AttributeDiskStateUsed) + v.mb.RecordVcenterDatacenterDiskSpaceDataPoint(ts, dcStat.DiskFree, metadata.AttributeDiskStateAvailable) + v.mb.RecordVcenterDatacenterCPULimitDataPoint(ts, dcStat.CPULimit) + v.mb.RecordVcenterDatacenterMemoryLimitDataPoint(ts, dcStat.MemoryLimit) + +} + +func getEntityStatusAttribute(status types.ManagedEntityStatus) (metadata.AttributeEntityStatus, bool) { + entityStatusToAttribute := map[types.ManagedEntityStatus]metadata.AttributeEntityStatus{ + types.ManagedEntityStatusRed: metadata.AttributeEntityStatusRed, + types.ManagedEntityStatusYellow: metadata.AttributeEntityStatusYellow, + types.ManagedEntityStatusGreen: metadata.AttributeEntityStatusGreen, + types.ManagedEntityStatusGray: metadata.AttributeEntityStatusGray, + } + attr, ok := entityStatusToAttribute[status] + return attr, ok +} + +func getVMPowerStateAttribute(state string) (metadata.AttributeVMCountPowerState, bool) { + vmPowerStateToAttribute := map[string]metadata.AttributeVMCountPowerState{ + "poweredOn": metadata.AttributeVMCountPowerStateOn, + "poweredOff": metadata.AttributeVMCountPowerStateOff, + "suspended": metadata.AttributeVMCountPowerStateSuspended, + } + attr, ok := vmPowerStateToAttribute[state] + return attr, ok +} + +func getHostPowerStateAttribute(state string) (metadata.AttributeHostPowerState, bool) { + hostPowerStateToAttribute := map[string]metadata.AttributeHostPowerState{ + "poweredOn": metadata.AttributeHostPowerStateOn, + "poweredOff": metadata.AttributeHostPowerStateOff, + "standby": metadata.AttributeHostPowerStateStandby, + "unknown": metadata.AttributeHostPowerStateUnknown, + } + attr, ok := hostPowerStateToAttribute[state] + return attr, ok +} + // recordDatastoreStats records stat metrics for a vSphere Datastore func (v *vcenterMetricScraper) recordDatastoreStats( ts pcommon.Timestamp, diff --git a/receiver/vcenterreceiver/processors.go b/receiver/vcenterreceiver/processors.go index f687218e8d5c..4ee2f520cf18 100644 --- a/receiver/vcenterreceiver/processors.go +++ b/receiver/vcenterreceiver/processors.go @@ -15,25 +15,60 @@ import ( "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/vcenterreceiver/internal/metadata" ) +type DatacenterStats struct { + ClusterStatusCounts map[types.ManagedEntityStatus]int64 + HostStats map[string]map[types.ManagedEntityStatus]int64 + VMStats map[string]map[types.ManagedEntityStatus]int64 + DatastoreCount int64 + DiskCapacity int64 + DiskFree int64 + CPULimit int64 + MemoryLimit int64 +} + // processDatacenterData creates all of the vCenter metrics from the stored scraped data under a single Datacenter func (v *vcenterMetricScraper) processDatacenterData(dc *mo.Datacenter, errs *scrapererror.ScrapeErrors) { // Init for current collection now := pcommon.NewTimestampFromTime(time.Now()) - - v.processDatastores(now, dc) + dcStats := &DatacenterStats{ + ClusterStatusCounts: make(map[types.ManagedEntityStatus]int64), + HostStats: make(map[string]map[types.ManagedEntityStatus]int64), + VMStats: make(map[string]map[types.ManagedEntityStatus]int64), + } + v.processDatastores(now, dc, dcStats) v.processResourcePools(now, dc, errs) - vmRefToComputeRef := v.processHosts(now, dc, errs) - vmGroupInfoByComputeRef := v.processVMs(now, dc, vmRefToComputeRef, errs) - v.processClusters(now, dc, vmGroupInfoByComputeRef, errs) + vmRefToComputeRef := v.processHosts(now, dc, dcStats, errs) + vmGroupInfoByComputeRef := v.processVMs(now, dc, vmRefToComputeRef, dcStats, errs) + v.processClusters(now, dc, vmGroupInfoByComputeRef, dcStats, errs) + v.buildDatacenterMetrics(now, dc, dcStats) +} + +// buildDatacenterMetrics builds a resource and metrics for a given scraped vCenter Datacenter +func (v *vcenterMetricScraper) buildDatacenterMetrics( + ts pcommon.Timestamp, + dc *mo.Datacenter, + dcStats *DatacenterStats, +) { + // Create Datacenter resource builder + rb := v.createDatacenterResourceBuilder(dc) + + // Record & emit Datacenter metric data points + v.recordDatacenterStats(ts, dcStats) + + v.mb.EmitForResource(metadata.WithResource(rb.Emit())) } // processDatastores creates the vCenter Datastore metrics and resources from the stored scraped data under a single Datacenter func (v *vcenterMetricScraper) processDatastores( ts pcommon.Timestamp, dc *mo.Datacenter, + dcStats *DatacenterStats, ) { for _, ds := range v.scrapeData.datastores { v.buildDatastoreMetrics(ts, dc, ds) + dcStats.DatastoreCount++ + dcStats.DiskCapacity += ds.Summary.Capacity + dcStats.DiskFree += ds.Summary.FreeSpace } } @@ -101,11 +136,19 @@ func (v *vcenterMetricScraper) buildResourcePoolMetrics( func (v *vcenterMetricScraper) processHosts( ts pcommon.Timestamp, dc *mo.Datacenter, + dcStats *DatacenterStats, errs *scrapererror.ScrapeErrors, ) map[string]*types.ManagedObjectReference { vmRefToComputeRef := map[string]*types.ManagedObjectReference{} for _, hs := range v.scrapeData.hostsByRef { + powerState := string(hs.Runtime.PowerState) + ensureInnerMapInitialized(dcStats.HostStats, powerState) + dcStats.HostStats[powerState][hs.Summary.OverallStatus]++ + + dcStats.CPULimit += int64(hs.Summary.Hardware.CpuMhz * int32(hs.Summary.Hardware.NumCpuCores)) + dcStats.MemoryLimit += hs.Summary.Hardware.MemorySize + hsVMRefToComputeRef, err := v.buildHostMetrics(ts, dc, hs) if err != nil { errs.AddPartial(1, err) @@ -167,10 +210,10 @@ func (v *vcenterMetricScraper) processVMs( ts pcommon.Timestamp, dc *mo.Datacenter, vmRefToComputeRef map[string]*types.ManagedObjectReference, + dcStats *DatacenterStats, errs *scrapererror.ScrapeErrors, ) map[string]*vmGroupInfo { vmGroupInfoByComputeRef := map[string]*vmGroupInfo{} - for _, vm := range v.scrapeData.vmsByRef { crRef, singleVMGroupInfo, err := v.buildVMMetrics(ts, dc, vm, vmRefToComputeRef) if err != nil { @@ -184,14 +227,21 @@ func (v *vcenterMetricScraper) processVMs( crVMGroupInfo = &vmGroupInfo{poweredOff: 0, poweredOn: 0, suspended: 0, templates: 0} vmGroupInfoByComputeRef[crRef.Value] = crVMGroupInfo } + overallStatus := vm.Summary.OverallStatus if singleVMGroupInfo.poweredOn > 0 { crVMGroupInfo.poweredOn++ + ensureInnerMapInitialized(dcStats.VMStats, "poweredOn") + dcStats.VMStats["poweredOn"][overallStatus]++ } if singleVMGroupInfo.poweredOff > 0 { crVMGroupInfo.poweredOff++ + ensureInnerMapInitialized(dcStats.VMStats, "poweredOff") + dcStats.VMStats["poweredOff"][overallStatus]++ } if singleVMGroupInfo.suspended > 0 { crVMGroupInfo.suspended++ + ensureInnerMapInitialized(dcStats.VMStats, "suspended") + dcStats.VMStats["suspended"][overallStatus]++ } if singleVMGroupInfo.templates > 0 { crVMGroupInfo.templates++ @@ -202,6 +252,13 @@ func (v *vcenterMetricScraper) processVMs( return vmGroupInfoByComputeRef } +// ensureInnerMapInitialized is a helper function that ensures maps are initialized in order to freely aggregate VM and Host stats +func ensureInnerMapInitialized(stats map[string]map[types.ManagedEntityStatus]int64, key string) { + if stats[key] == nil { + stats[key] = make(map[types.ManagedEntityStatus]int64) + } +} + // buildVMMetrics builds a resource and metrics for a given scraped VM // // returns the ComputeResource and power state info associated with this VM @@ -275,6 +332,7 @@ func (v *vcenterMetricScraper) processClusters( ts pcommon.Timestamp, dc *mo.Datacenter, vmStatesByComputeRef map[string]*vmGroupInfo, + dcStats *DatacenterStats, errs *scrapererror.ScrapeErrors, ) { for crRef, cr := range v.scrapeData.computesByRef { @@ -283,7 +341,10 @@ func (v *vcenterMetricScraper) processClusters( continue } + summary := cr.Summary.GetComputeResourceSummary() + dcStats.ClusterStatusCounts[summary.OverallStatus]++ vmGroupInfo := vmStatesByComputeRef[crRef] + if err := v.buildClusterMetrics(ts, dc, cr, vmGroupInfo); err != nil { errs.AddPartial(1, err) } diff --git a/receiver/vcenterreceiver/resources.go b/receiver/vcenterreceiver/resources.go index 35c7d12a5fc9..30bbdc92bfe1 100644 --- a/receiver/vcenterreceiver/resources.go +++ b/receiver/vcenterreceiver/resources.go @@ -24,6 +24,16 @@ func (v *vcenterMetricScraper) createDatastoreResourceBuilder( return rb } +// createDatacenterResourceBuilder returns a ResourceBuilder with +// attributes set for a vSphere datacenter +func (v *vcenterMetricScraper) createDatacenterResourceBuilder( + dc *mo.Datacenter, +) *metadata.ResourceBuilder { + rb := v.mb.NewResourceBuilder() + rb.SetVcenterDatacenterName(dc.Name) + return rb +} + // createClusterResourceBuilder returns a ResourceBuilder with // attributes set for a vSphere Cluster func (v *vcenterMetricScraper) createClusterResourceBuilder( diff --git a/receiver/vcenterreceiver/scraper.go b/receiver/vcenterreceiver/scraper.go index a1a358b038fa..42963268840b 100644 --- a/receiver/vcenterreceiver/scraper.go +++ b/receiver/vcenterreceiver/scraper.go @@ -236,7 +236,6 @@ func (v *vcenterMetricScraper) scrapeComputes(ctx context.Context, dc *mo.Datace func (v *vcenterMetricScraper) scrapeHosts(ctx context.Context, dc *mo.Datacenter, errs *scrapererror.ScrapeErrors) { // Init for current collection v.scrapeData.hostsByRef = make(map[string]*mo.HostSystem) - // Get HostSystems w/properties and store for later retrieval hosts, err := v.client.HostSystems(ctx, dc.Reference()) if err != nil { diff --git a/receiver/vcenterreceiver/scraper_test.go b/receiver/vcenterreceiver/scraper_test.go index 1ee053257d8a..4a5fe26921d9 100644 --- a/receiver/vcenterreceiver/scraper_test.go +++ b/receiver/vcenterreceiver/scraper_test.go @@ -48,6 +48,14 @@ func TestScrapeConfigsEnabled(t *testing.T) { optConfigs.Metrics.VcenterResourcePoolMemorySwapped.Enabled = true optConfigs.Metrics.VcenterResourcePoolMemoryBallooned.Enabled = true optConfigs.Metrics.VcenterResourcePoolMemoryGranted.Enabled = true + optConfigs.Metrics.VcenterDatacenterClusterCount.Enabled = true + optConfigs.Metrics.VcenterDatacenterDatastoreCount.Enabled = true + optConfigs.Metrics.VcenterDatacenterHostCount.Enabled = true + optConfigs.Metrics.VcenterDatacenterVMCount.Enabled = true + optConfigs.Metrics.VcenterDatacenterCPULimit.Enabled = true + optConfigs.Metrics.VcenterDatacenterMemoryLimit.Enabled = true + optConfigs.Metrics.VcenterDatacenterDiskSpace.Enabled = true + cfg := &Config{ MetricsBuilderConfig: optConfigs, Endpoint: mockServer.URL, diff --git a/receiver/vcenterreceiver/testdata/metrics/expected-all-enabled.yaml b/receiver/vcenterreceiver/testdata/metrics/expected-all-enabled.yaml index d6f115e2ecd0..ffe7e7ef2ceb 100644 --- a/receiver/vcenterreceiver/testdata/metrics/expected-all-enabled.yaml +++ b/receiver/vcenterreceiver/testdata/metrics/expected-all-enabled.yaml @@ -1,4 +1,137 @@ resourceMetrics: + - resource: + attributes: + - key: vcenter.datacenter.name + value: + stringValue: Datacenter + scopeMetrics: + - metrics: + - description: The number of clusters in the datacenter. + name: vcenter.datacenter.cluster.count + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "0" + attributes: + - key: status + value: + stringValue: gray + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "1" + attributes: + - key: status + value: + stringValue: green + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: status + value: + stringValue: red + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "0" + attributes: + - key: status + value: + stringValue: yellow + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: '{clusters}' + - description: The total amount of CPU available to the datacenter. + name: vcenter.datacenter.cpu.limit + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "186696" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: '{MHz}' + - description: The number of datastores in the datacenter. + name: vcenter.datacenter.datastore.count + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: '{datastores}' + - description: The amount of available and used disk space in the datacenter. + name: vcenter.datacenter.disk.space + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "51693551508648" + attributes: + - key: disk_state + value: + stringValue: available + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "5917763748696" + attributes: + - key: disk_state + value: + stringValue: used + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: The number of hosts in the datacenter. + name: vcenter.datacenter.host.count + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "2" + attributes: + - key: power_state + value: + stringValue: "on" + - key: status + value: + stringValue: green + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: '{hosts}' + - description: The total amount of memory available to the datacenter. + name: vcenter.datacenter.memory.limit + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "1645526253568" + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: By + - description: The number of VM's in the datacenter. + name: vcenter.datacenter.vm.count + sum: + aggregationTemporality: 2 + dataPoints: + - asInt: "2" + attributes: + - key: power_state + value: + stringValue: "on" + - key: status + value: + stringValue: green + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + - asInt: "1" + attributes: + - key: power_state + value: + stringValue: "on" + - key: status + value: + stringValue: yellow + startTimeUnixNano: "1000000" + timeUnixNano: "2000000" + unit: '{virtual_machines}' + scope: + name: otelcol/vcenterreceiver + version: latest - resource: attributes: - key: vcenter.cluster.name