diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 9b73c52df06..b649d7950dc 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -54,6 +54,7 @@ https://github.com/elastic/beats/compare/v8.8.1\...main[Check the HEAD diff] - Allow metricsets to report their status via control v2 protocol. {pull}40025[40025] - Remove fallback to the node limit for the `kubernetes.pod.cpu.usage.limit.pct` and `kubernetes.pod.memory.usage.limit.pct` metrics calculation - Add support for Kibana status metricset in v8 format {pull}40275[40275] +- Update metrics for the vSphere Host metricset. {pull}40429[40429] *Osquerybeat* diff --git a/NOTICE.txt b/NOTICE.txt index a86a98a6869..5504aa5b2ef 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -22704,11 +22704,11 @@ SOFTWARE. -------------------------------------------------------------------------------- Dependency : github.com/vmware/govmomi -Version: v0.0.0-20170802214208-2cad15190b41 +Version: v0.39.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/vmware/govmomi@v0.0.0-20170802214208-2cad15190b41/LICENSE.txt: +Contents of probable licence file $GOMODCACHE/github.com/vmware/govmomi@v0.39.0/LICENSE.txt: Apache License diff --git a/go.mod b/go.mod index ed977c54215..e9acdbaefae 100644 --- a/go.mod +++ b/go.mod @@ -132,7 +132,7 @@ require ( github.com/stretchr/testify v1.9.0 github.com/tsg/go-daemon v0.0.0-20200207173439-e704b93fd89b github.com/ugorji/go/codec v1.1.8 - github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41 + github.com/vmware/govmomi v0.39.0 go.elastic.co/ecszap v1.0.2 go.elastic.co/go-licence-detector v0.6.1 go.etcd.io/bbolt v1.3.10 diff --git a/go.sum b/go.sum index 747473783f8..2b46e4c2cad 100644 --- a/go.sum +++ b/go.sum @@ -1653,8 +1653,8 @@ github.com/vishvananda/netlink v1.2.1-beta.2/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhg github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41 h1:NeNpIvfvaFOh0BH7nMEljE5Rk/VJlxhm58M41SeOD20= -github.com/vmware/govmomi v0.0.0-20170802214208-2cad15190b41/go.mod h1:URlwyTFZX72RmxtxuaFL2Uj3fD1JTvZdx59bHWk6aFU= +github.com/vmware/govmomi v0.39.0 h1:soLZ08Q2zvjRSinNup8xVlw0KDDCJPPA1rIDmBhi7As= +github.com/vmware/govmomi v0.39.0/go.mod h1:oHzAQ1r6152zYDGcUqeK+EO8LhKo5wjtvWZBGHws2Hc= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/willf/bitset v1.1.9/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index df93b4a6d8c..2ebe8a22783 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -66932,54 +66932,96 @@ format: percent [float] === host -host +Host information from vSphere environment. -*`vsphere.host.name`*:: +*`vsphere.host.cpu.used.mhz`*:: + -- -Host name +Used CPU in MHz. + + +type: long + +-- + +*`vsphere.host.cpu.total.mhz`*:: ++ +-- +Total CPU in MHz. + + +type: long + +-- + +*`vsphere.host.cpu.free.mhz`*:: ++ +-- +Free CPU in MHz. + + +type: long + +-- + +*`vsphere.host.datastore.names`*:: ++ +-- +List of all the datastore names. type: keyword -- -*`vsphere.host.cpu.used.mhz`*:: +*`vsphere.host.datastore.count`*:: + -- -Used CPU in Mhz +Number of datastores on the host. type: long -- -*`vsphere.host.cpu.total.mhz`*:: +*`vsphere.host.disk.capacity.usage.bytes`*:: + -- -Total CPU in Mhz +The amount of storage capacity currently being consumed by or on the entity. type: long +format: bytes + -- -*`vsphere.host.cpu.free.mhz`*:: +*`vsphere.host.disk.devicelatency.average.ms`*:: + -- -Free CPU in Mhz +Average amount of time it takes to complete an SCSI command from physical device in milliseconds. type: long -- -*`vsphere.host.memory.used.bytes`*:: +*`vsphere.host.disk.latency.total.ms`*:: ++ +-- +Highest latency value across all disks used by the host in milliseconds. + + +type: long + +-- + +*`vsphere.host.disk.read.bytes`*:: + -- -Used Memory in bytes +Average number of bytes read from the disk each second. type: long @@ -66988,10 +67030,22 @@ format: bytes -- -*`vsphere.host.memory.total.bytes`*:: +*`vsphere.host.disk.write.bytes`*:: ++ +-- +Average number of bytes written to the disk each second. + + +type: long + +format: bytes + +-- + +*`vsphere.host.disk.total.bytes`*:: + -- -Total Memory in bytes +Sum of disk read and write rates each second in bytes. type: long @@ -67003,7 +67057,7 @@ format: bytes *`vsphere.host.memory.free.bytes`*:: + -- -Free Memory in bytes +Free Memory in bytes. type: long @@ -67012,16 +67066,256 @@ format: bytes -- +*`vsphere.host.memory.total.bytes`*:: ++ +-- +Total Memory in bytes. + + +type: long + +format: bytes + +-- + +*`vsphere.host.memory.used.bytes`*:: ++ +-- +Used Memory in bytes. + + +type: long + +format: bytes + +-- + +*`vsphere.host.name`*:: ++ +-- +Host name. + + +type: keyword + +-- + *`vsphere.host.network_names`*:: + -- -Network names +Network names. + + +type: keyword + +-- + +*`vsphere.host.network.names`*:: ++ +-- +List of all the network names. + + +type: keyword + +-- + +*`vsphere.host.network.count`*:: ++ +-- +Number of networks on the host. + + +type: long + +-- + +*`vsphere.host.network.bandwidth.transmitted.bytes`*:: ++ +-- +Average rate at which data was transmitted during the interval. This represents the bandwidth of the network. + + +type: long + +format: bytes + +-- + +*`vsphere.host.network.bandwidth.received.bytes`*:: ++ +-- +Average rate at which data was received during the interval. This represents the bandwidth of the network. + + +type: long + +format: bytes + +-- + +*`vsphere.host.network.bandwidth.total.bytes`*:: ++ +-- +Sum of network transmitted and received rates in bytes during the interval. + + +type: long + +format: bytes + +-- + +*`vsphere.host.network.packets.transmitted.count`*:: ++ +-- +Number of packets transmitted. + + +type: long + +-- + +*`vsphere.host.network.packets.received.count`*:: ++ +-- +Number of packets received. + + +type: long + +-- + +*`vsphere.host.network.packets.errors.transmitted.count`*:: ++ +-- +Number of packets with errors transmitted. + + +type: long + +-- + +*`vsphere.host.network.packets.errors.received.count`*:: ++ +-- +Number of packets with errors received. + + +type: long + +-- + +*`vsphere.host.network.packets.errors.total.count`*:: ++ +-- +Total number of packets with errors. + + +type: long + +-- + +*`vsphere.host.network.packets.multicast.transmitted.count`*:: ++ +-- +Number of multicast packets transmitted. + + +type: long + +-- + +*`vsphere.host.network.packets.multicast.received.count`*:: ++ +-- +Number of multicast packets received. + + +type: long + +-- + +*`vsphere.host.network.packets.multicast.total.count`*:: ++ +-- +Total number of multicast packets. + + +type: long + +-- + +*`vsphere.host.network.packets.dropped.transmitted.count`*:: ++ +-- +Number of transmitted packets dropped. + + +type: long + +-- + +*`vsphere.host.network.packets.dropped.received.count`*:: ++ +-- +Number of received packets dropped. + + +type: long + +-- + +*`vsphere.host.network.packets.dropped.total.count`*:: ++ +-- +Total number of packets dropped. + + +type: long + +-- + +*`vsphere.host.status`*:: ++ +-- +The overall health status of a host in the vSphere environment. type: keyword -- +*`vsphere.host.uptime`*:: ++ +-- +The total uptime of a host in seconds within the vSphere environment. + + +type: long + +-- + +*`vsphere.host.vm.names`*:: ++ +-- +List of all the VM names. + + +type: keyword + +-- + +*`vsphere.host.vm.count`*:: ++ +-- +Number of virtual machines on the host. + + +type: long + +-- + [float] === virtualmachine diff --git a/metricbeat/docs/modules/vsphere.asciidoc b/metricbeat/docs/modules/vsphere.asciidoc index daab01568eb..738bc1153d2 100644 --- a/metricbeat/docs/modules/vsphere.asciidoc +++ b/metricbeat/docs/modules/vsphere.asciidoc @@ -36,7 +36,8 @@ metricbeat.modules: - module: vsphere enabled: true metricsets: ["datastore", "host", "virtualmachine"] - period: 10s + # Real-time data collection – An ESXi Server collects data for each performance counter every 20 seconds. + period: 20s hosts: ["https://localhost/sdk"] username: "user" diff --git a/metricbeat/metricbeat.reference.yml b/metricbeat/metricbeat.reference.yml index 985e4795910..4c72f9dad04 100644 --- a/metricbeat/metricbeat.reference.yml +++ b/metricbeat/metricbeat.reference.yml @@ -1008,7 +1008,8 @@ metricbeat.modules: - module: vsphere enabled: true metricsets: ["datastore", "host", "virtualmachine"] - period: 10s + # Real-time data collection – An ESXi Server collects data for each performance counter every 20 seconds. + period: 20s hosts: ["https://localhost/sdk"] username: "user" diff --git a/metricbeat/module/vsphere/_meta/config.reference.yml b/metricbeat/module/vsphere/_meta/config.reference.yml index d4803d0c775..18da5eb6b91 100644 --- a/metricbeat/module/vsphere/_meta/config.reference.yml +++ b/metricbeat/module/vsphere/_meta/config.reference.yml @@ -1,7 +1,8 @@ - module: vsphere enabled: true metricsets: ["datastore", "host", "virtualmachine"] - period: 10s + # Real-time data collection – An ESXi Server collects data for each performance counter every 20 seconds. + period: 20s hosts: ["https://localhost/sdk"] username: "user" diff --git a/metricbeat/module/vsphere/_meta/config.yml b/metricbeat/module/vsphere/_meta/config.yml index 6862012209b..8b76d29f907 100644 --- a/metricbeat/module/vsphere/_meta/config.yml +++ b/metricbeat/module/vsphere/_meta/config.yml @@ -3,7 +3,8 @@ # - datastore # - host # - virtualmachine - period: 10s + # Real-time data collection – An ESXi Server collects data for each performance counter every 20 seconds. + period: 20s hosts: ["https://localhost/sdk"] username: "user" diff --git a/metricbeat/module/vsphere/datastore/datastore_test.go b/metricbeat/module/vsphere/datastore/datastore_test.go index 88f5b772b5a..1e3387adef8 100644 --- a/metricbeat/module/vsphere/datastore/datastore_test.go +++ b/metricbeat/module/vsphere/datastore/datastore_test.go @@ -48,7 +48,7 @@ func TestFetchEventContents(t *testing.T) { t.Logf("%s/%s event: %+v", f.Module().Name(), f.Name(), event.StringToPrint()) assert.EqualValues(t, "LocalDS_0", event["name"]) - assert.EqualValues(t, "local", event["fstype"]) + assert.EqualValues(t, "OTHER", event["fstype"]) // Values are based on the result 'df -k'. fields := []string{"capacity.total.bytes", "capacity.free.bytes", diff --git a/metricbeat/module/vsphere/fields.go b/metricbeat/module/vsphere/fields.go index fae0b2cc264..26d9707a819 100644 --- a/metricbeat/module/vsphere/fields.go +++ b/metricbeat/module/vsphere/fields.go @@ -32,5 +32,5 @@ func init() { // AssetVsphere returns asset data. // This is the base64 encoded zlib format compressed contents of module/vsphere. func AssetVsphere() string { - return "eJzsl8+OmzAQxu95itHedx+AQ6Vqq20vaSttt9fIgSG4MQyyh6zo01e2IeKP002KaS/1ASnYfN8PzHxD7uGIbQInUxeocQPAkhUmcHd6dmfuNgAZmlTLmiVVCbzbAAB0s1BS1ih7mUaFwmACB7EByCWqzCRu6T1UosShhR3c1naxpqbuzgRcxkJDsUywMExnubDkRdluKiAyvo9+TDGGKPY4muhJjti+ks4mc7/hseNDzzTX7Q1zY/XjWT5JhaY1jCXMhHvPVNQildw+MLFQD/uW0QQJFFWH2+y/WUVwikA5cIHBjbEjJ10KTmBuP+PMNWJUzCeNGJ2yMZhFpXwxmK1DWaccZDSpUJjtckViuuAa1hp1ihVfS9stP8/OgqEgw0syYXL9v46DT2T4chKkdeM3pyx+xnyBHr++gKxgO1Ed2vociOfrU+AKY1fY8XxdWb9hW2JJeq1i3Tpxax+SfrtKO7i1cjkS3jpxvBSuQn4lfdzZX2GwPyraz14WxrLn7yCpuRGqFGkhq0XfLxeVbk8tG3sPcnqfS4NrIjgys4eVsrJvJpMsXyujv/ttgK3fh8txTRHfsanplxq1YFkd4Nl/yv1vGus1jfcnIZXYq5s6x6FBw6v1D8rhozVYnNSO1VXoiqg+HaK0vPiPddT4oj1X9wrGhx32weWsaWOYyp3vFEFC2v/A2T8Bf3K3IM4enTEEjP9qr/4VAAD//9YITTs=" + return "eJzMmc2O2zYQx+9+ikHu8QP4UCDYIt0C3bTAbnJd0NTYYs0PgRzJcJ6+ICkpsi15LZs06sMCkZT5/zicGQ7Jz7DDwwoaV5VocQFAgiSu4FPzGp58WgAU6LgVFQmjV/DbAgCgfQvKFLX0/82iROZwBVu2ANgIlIVbhU8/g2YKhxL+R4fKf2xNXbVPRlSODQ2NFYyYI9ObGzc5abZ9NWLkeBzd7xRjiOL/Hr3oSHZ42BtbnLy7wON/v3dM53Y7wY3z9tNJfhUS3cERKjgz3GlyVjEu6LAkQ0wu1wdCN0ogjd7Ok3/zFiFYBLMBKnF0YvxvY6xitIJz+TPOjUVMivnVIianrB0WSSm/OyzyUFacRhkdZxKL94007PSDa1grtBw1XUvbft6/PSsMpXF0T014No5A6KgnjIaNNaovd6gbYY1WqGl5V9HgVR3dqsqfKaf+6Z/vIDS8PP9cTurGFE4nHBP4GuWQlOmEQ0p+pNtH1NL/ezzPbiqbfwkXwpZJeRy6Qdh9RMNNrcczar4jvtVqjdbD9PYdGB2wfEJMsAi3Ww6SnG3TVsy3EoEpP0xP5qnYFvuqAry2FjXJA6xR6C1wo12tQvkCYzt81OTpZhevMLgCG8FRMkLND0vWoCdYqlQD/BINDgZJQiEIAmI7dEAGuFGVREJgGl6fXv/0DxTTRSwrVXlwgjMJEdTHsRJSCofc6GIqhPzIujG1uZxqRM9iW6IjaM1Dw2SNwLg1zoVA9+IO6rjK9PE1A9wiS7vidZOg+xyIy58Xil4OySncDpDxEiLijQG1t4LSJskUvlci1D6GEvKn795eaxXqjucLLvfBHdwElvmBDKB9mATt+fQKlbG5urqXYPx+uly9cSq+PN3m3XRpN1ChgfMmx4uQRtobu3tP3Ax8i2YvLf2tcu42RF9PkqcFaa1f0YB0HGumi70oqFySZdopX/nyLBK+JAEj2JeCl6FZgj1zMJCFora+G/HkQhPahsklvJXCryiVRYeaXHjbU3d7l2448xPgzA8WOYrmsU7oNP8fHsi2UnX5MZxzv2b1w4/LVlfORr1x8/gqxndI7ijO82RhqzQc5uUk7ND60MvL1ctcBYXWGvtIt+0FlRBV57uwpX2QJ4eot3k1pFpKyNi26Euo1xGqWpLgzNEDpr7Xuj13fuFmnvtz1nkzP/Br9sk/Y70OsbCmqrB4wMQPV4LOnZ36LNTMk96vUHdBPi7bL+I5YlQnbIPfSgTjGxwpoUQmqWwlQm/cn1L4ZfyDw9xfjHVFYmJrcttpWPB9a/aYqz04CRVyLmajcu8pfrxc2k40KlPAN8JSzSQoxkuhp440e4z4dfvx4hRkxh3ApKX55/wBVZy6/97t7YnBIzH/J9OOumvzT+5Ycu3kf7TT/xLnYfpC1CQM/VPRvyu0jPwO4DVekU5S5L7SObH6uBudC8KJL3S+NExItpb4kfbwQGtbo6Nsx1pmA394gX5DOHvvN2QNGZoRtb29vI80RlN6tx4dZibzawjB9LDDg+H7WXntyKj3uFKMEpr1v3h2wx4fvt9Rzp6CMIwIP/JAdPFfAAAA//+hUbzT" } diff --git a/metricbeat/module/vsphere/host/_meta/data.json b/metricbeat/module/vsphere/host/_meta/data.json index b2df68bd4f6..cb8d7896ce5 100644 --- a/metricbeat/module/vsphere/host/_meta/data.json +++ b/metricbeat/module/vsphere/host/_meta/data.json @@ -1,46 +1,142 @@ { "@timestamp": "2022-09-06T06:41:22.128Z", "metricset": { - "name": "host", - "period": 10000 + "name": "host", + "period": 10000 }, "service": { - "address": "https://localhost:8989/sdk", - "type": "vsphere" + "address": "https://localhost:8989/sdk", + "type": "vsphere" }, "event": { - "module": "vsphere", - "duration": 23519250, - "dataset": "vsphere.host" + "module": "vsphere", + "duration": 23519250, + "dataset": "vsphere.host" }, "vsphere": { - "host": { - "cpu": { - "used": { - "mhz": 67 - }, - "total": { - "mhz": 4588 - }, - "free": { - "mhz": 4521 - } - }, - "memory": { - "free": { - "bytes": 2822230016 - }, - "total": { - "bytes": 4294430720 - }, - "used": { - "bytes": 1472200704 - } - }, - "network_names": [ - "VM Network" - ], - "name": "DC0_H0" - } + "host": { + "cpu": { + "used": { + "mhz": 67 + }, + "total": { + "mhz": 4588 + }, + "free": { + "mhz": 4521 + } + }, + "disk": { + "capacity": { + "usage": { + "bytes": 0 + } + }, + "devicelatency": { + "average": { + "ms": 0 + } + }, + "latency": { + "total": { + "ms": 18 + } + }, + "total": { + "bytes": 262000 + }, + "read": { + "bytes": 13000 + }, + "write": { + "bytes": 248000 + } + }, + "memory": { + "free": { + "bytes": 2822230016 + }, + "total": { + "bytes": 4294430720 + }, + "used": { + "bytes": 1472200704 + } + }, + "network": { + "bandwidth": { + "total": { + "bytes": 372000 + }, + "transmitted": { + "bytes": 0 + }, + "received": { + "bytes": 371000 + } + }, + "packets": { + "received": { + "count": 9463 + }, + "errors": { + "transmitted": { + "count": 0 + }, + "received": { + "count": 0 + }, + "total": { + "count": 0 + } + }, + "multicast": { + "total": { + "count": 6679 + }, + "transmitted": { + "count": 0 + }, + "received": { + "count": 6679 + } + }, + "dropped": { + "received": { + "count": 0 + }, + "total": { + "count": 0 + }, + "transmitted": { + "count": 0 + } + }, + "transmitted": { + "count": 54 + } + } + }, + "vm": { + "count": 2, + "names": [ + "DC0_H0_VM0", + "DC0_H0_VM1" + ] + }, + "datastore": { + "count": 1, + "names": [ + "LocalDS_0" + ] + }, + "network_count": 1, + "network_names": [ + "VM Network" + ], + "name": "DC0_H0", + "status": "green", + "uptime": 1728865 + } } -} \ No newline at end of file +} diff --git a/metricbeat/module/vsphere/host/_meta/fields.yml b/metricbeat/module/vsphere/host/_meta/fields.yml index ef6331082eb..b45061b863e 100644 --- a/metricbeat/module/vsphere/host/_meta/fields.yml +++ b/metricbeat/module/vsphere/host/_meta/fields.yml @@ -1,41 +1,160 @@ - name: host type: group description: > - host + Host information from vSphere environment. release: ga fields: - - name: name - type: keyword - description: > - Host name - name: cpu.used.mhz type: long description: > - Used CPU in Mhz + Used CPU in MHz. - name: cpu.total.mhz type: long description: > - Total CPU in Mhz + Total CPU in MHz. - name: cpu.free.mhz type: long description: > - Free CPU in Mhz - - name: memory.used.bytes + Free CPU in MHz. + - name: datastore.names + type: keyword + description: > + List of all the datastore names. + - name: datastore.count + type: long + description: > + Number of datastores on the host. + - name: disk.capacity.usage.bytes type: long description: > - Used Memory in bytes + The amount of storage capacity currently being consumed by or on the entity. format: bytes - - name: memory.total.bytes + - name: disk.devicelatency.average.ms + type: long + description: > + Average amount of time it takes to complete an SCSI command from physical device in milliseconds. + - name: disk.latency.total.ms + type: long + description: > + Highest latency value across all disks used by the host in milliseconds. + - name: disk.read.bytes + type: long + description: > + Average number of bytes read from the disk each second. + format: bytes + - name: disk.write.bytes + type: long + description: > + Average number of bytes written to the disk each second. + format: bytes + - name: disk.total.bytes type: long description: > - Total Memory in bytes + Sum of disk read and write rates each second in bytes. format: bytes - name: memory.free.bytes type: long description: > - Free Memory in bytes + Free Memory in bytes. format: bytes + - name: memory.total.bytes + type: long + description: > + Total Memory in bytes. + format: bytes + - name: memory.used.bytes + type: long + description: > + Used Memory in bytes. + format: bytes + - name: name + type: keyword + description: > + Host name. - name: network_names type: keyword description: > - Network names + Network names. + - name: network.names + type: keyword + description: > + List of all the network names. + - name: network.count + type: long + description: > + Number of networks on the host. + - name: network.bandwidth.transmitted.bytes + type: long + description: > + Average rate at which data was transmitted during the interval. This represents the bandwidth of the network. + format: bytes + - name: network.bandwidth.received.bytes + type: long + description: > + Average rate at which data was received during the interval. This represents the bandwidth of the network. + format: bytes + - name: network.bandwidth.total.bytes + type: long + description: > + Sum of network transmitted and received rates in bytes during the interval. + format: bytes + - name: network.packets.transmitted.count + type: long + description: > + Number of packets transmitted. + - name: network.packets.received.count + type: long + description: > + Number of packets received. + - name: network.packets.errors.transmitted.count + type: long + description: > + Number of packets with errors transmitted. + - name: network.packets.errors.received.count + type: long + description: > + Number of packets with errors received. + - name: network.packets.errors.total.count + type: long + description: > + Total number of packets with errors. + - name: network.packets.multicast.transmitted.count + type: long + description: > + Number of multicast packets transmitted. + - name: network.packets.multicast.received.count + type: long + description: > + Number of multicast packets received. + - name: network.packets.multicast.total.count + type: long + description: > + Total number of multicast packets. + - name: network.packets.dropped.transmitted.count + type: long + description: > + Number of transmitted packets dropped. + - name: network.packets.dropped.received.count + type: long + description: > + Number of received packets dropped. + - name: network.packets.dropped.total.count + type: long + description: > + Total number of packets dropped. + - name: status + type: keyword + description: > + The overall health status of a host in the vSphere environment. + - name: uptime + type: long + description: > + The total uptime of a host in seconds within the vSphere environment. + - name: vm.names + type: keyword + description: > + List of all the VM names. + - name: vm.count + type: long + description: > + Number of virtual machines on the host. diff --git a/metricbeat/module/vsphere/host/data.go b/metricbeat/module/vsphere/host/data.go index 4be828fd448..7e984074953 100644 --- a/metricbeat/module/vsphere/host/data.go +++ b/metricbeat/module/vsphere/host/data.go @@ -23,37 +23,117 @@ import ( "github.com/elastic/elastic-agent-libs/mapstr" ) -func eventMapping(hs mo.HostSystem) mapstr.M { - totalCPU := int64(hs.Summary.Hardware.CpuMhz) * int64(hs.Summary.Hardware.NumCpuCores) - freeCPU := int64(totalCPU) - int64(hs.Summary.QuickStats.OverallCpuUsage) - usedMemory := int64(hs.Summary.QuickStats.OverallMemoryUsage) * 1024 * 1024 - freeMemory := int64(hs.Summary.Hardware.MemorySize) - usedMemory - +func (m *MetricSet) eventMapping(hs mo.HostSystem, data *metricData) mapstr.M { event := mapstr.M{ - "name": hs.Summary.Config.Name, - "cpu": mapstr.M{ - "used": mapstr.M{ - "mhz": hs.Summary.QuickStats.OverallCpuUsage, - }, - "total": mapstr.M{ - "mhz": totalCPU, - }, - "free": mapstr.M{ - "mhz": freeCPU, - }, - }, - "memory": mapstr.M{ - "used": mapstr.M{ - "bytes": usedMemory, - }, - "total": mapstr.M{ - "bytes": hs.Summary.Hardware.MemorySize, - }, - "free": mapstr.M{ - "bytes": freeMemory, - }, - }, + "name": hs.Summary.Config.Name, + "status": hs.Summary.OverallStatus, + "uptime": hs.Summary.QuickStats.Uptime, + "cpu": mapstr.M{"used": mapstr.M{"mhz": hs.Summary.QuickStats.OverallCpuUsage}}, + } + + mapPerfMetricToEvent(event, data.perfMetrics) + + if hw := hs.Summary.Hardware; hw != nil { + totalCPU := int64(hw.CpuMhz) * int64(hw.NumCpuCores) + usedMemory := int64(hs.Summary.QuickStats.OverallMemoryUsage) * 1024 * 1024 + event.Put("cpu.total.mhz", totalCPU) + event.Put("cpu.free.mhz", totalCPU-int64(hs.Summary.QuickStats.OverallCpuUsage)) + event.Put("memory.used.bytes", usedMemory) + event.Put("memory.free.bytes", hw.MemorySize-usedMemory) + event.Put("memory.total.bytes", hw.MemorySize) + } else { + m.Logger().Debug("'Hardware' or 'Summary' data not found. This is either a parsing error from vsphere library, an error trying to reach host/guest or incomplete information returned from host/guest") + } + + if len(data.assetsName.outputVmNames) > 0 { + event.Put("vm.names", data.assetsName.outputVmNames) + event.Put("vm.count", len(data.assetsName.outputVmNames)) + } + + if len(data.assetsName.outputDsNames) > 0 { + event.Put("datastore.names", data.assetsName.outputDsNames) + event.Put("datastore.count", len(data.assetsName.outputDsNames)) + } + + if len(data.assetsName.outputNetworkNames) > 0 { + event.Put("network_names", data.assetsName.outputNetworkNames) + event.Put("network.names", data.assetsName.outputNetworkNames) + event.Put("network.count", len(data.assetsName.outputNetworkNames)) } return event } + +func mapPerfMetricToEvent(event mapstr.M, perfMetricMap map[string]interface{}) { + if val, exist := perfMetricMap["disk.capacity.usage.average"]; exist { + event.Put("disk.capacity.usage.bytes", val.(int64)*1000) + } + if val, exist := perfMetricMap["disk.deviceLatency.average"]; exist { + event.Put("disk.devicelatency.average.ms", val) + } + if val, exist := perfMetricMap["disk.maxTotalLatency.latest"]; exist { + event.Put("disk.latency.total.ms", val) + } + if val, exist := perfMetricMap["disk.usage.average"]; exist { + event.Put("disk.total.bytes", val.(int64)*1000) + } + if val, exist := perfMetricMap["disk.read.average"]; exist { + event.Put("disk.read.bytes", val.(int64)*1000) + } + if val, exist := perfMetricMap["disk.write.average"]; exist { + event.Put("disk.write.bytes", val.(int64)*1000) + } + + if val, exist := perfMetricMap["net.transmitted.average"]; exist { + event.Put("network.bandwidth.transmitted.bytes", val.(int64)*1000) + } + if val, exist := perfMetricMap["net.received.average"]; exist { + event.Put("network.bandwidth.received.bytes", val.(int64)*1000) + } + if val, exist := perfMetricMap["net.usage.average"]; exist { + event.Put("network.bandwidth.total.bytes", val.(int64)*1000) + } + + if val, exist := perfMetricMap["net.packetsTx.summation"]; exist { + event.Put("network.packets.transmitted.count", val) + } + if val, exist := perfMetricMap["net.packetsRx.summation"]; exist { + event.Put("network.packets.received.count", val) + } + + netErrorsTransmitted, netErrorsTransmittedExist := perfMetricMap["net.errorsTx.summation"] + if netErrorsTransmittedExist { + event.Put("network.packets.errors.transmitted.count", netErrorsTransmitted) + } + netErrorsReceived, netErrorsReceivedExist := perfMetricMap["net.errorsRx.summation"] + if netErrorsReceivedExist { + event.Put("network.packets.errors.received.count", netErrorsReceived) + } + if netErrorsTransmittedExist && netErrorsReceivedExist { + event.Put("network.packets.errors.total.count", netErrorsTransmitted.(int64)+netErrorsReceived.(int64)) + } + + netMulticastTransmitted, netMulticastTransmittedExist := perfMetricMap["net.multicastTx.summation"] + if netMulticastTransmittedExist { + event.Put("network.packets.multicast.transmitted.count", netMulticastTransmitted) + } + netMulticastReceived, netMulticastReceivedExist := perfMetricMap["net.multicastRx.summation"] + if netMulticastReceivedExist { + event.Put("network.packets.multicast.received.count", netMulticastReceived) + } + if netMulticastTransmittedExist && netMulticastReceivedExist { + event.Put("network.packets.multicast.total.count", netMulticastTransmitted.(int64)+netMulticastReceived.(int64)) + } + + netDroppedTransmitted, netDroppedTransmittedExist := perfMetricMap["net.droppedTx.summation"] + if netDroppedTransmittedExist { + event.Put("network.packets.dropped.transmitted.count", netDroppedTransmitted) + } + netDroppedReceived, netDroppedReceivedExist := perfMetricMap["net.droppedRx.summation"] + if netDroppedReceivedExist { + event.Put("network.packets.dropped.received.count", netDroppedReceived) + } + if netDroppedTransmittedExist && netDroppedReceivedExist { + event.Put("network.packets.dropped.total.count", netDroppedTransmitted.(int64)+netDroppedReceived.(int64)) + } +} diff --git a/metricbeat/module/vsphere/host/data_test.go b/metricbeat/module/vsphere/host/data_test.go index 2a991a7c265..85dc46183f7 100644 --- a/metricbeat/module/vsphere/host/data_test.go +++ b/metricbeat/module/vsphere/host/data_test.go @@ -27,6 +27,7 @@ import ( ) func TestEventMapping(t *testing.T) { + var m *MetricSet var HostSystemTest = mo.HostSystem{ Summary: types.HostListSummary{ Host: &types.ManagedObjectReference{Type: "HostSystem", Value: "ha-host"}, @@ -45,7 +46,34 @@ func TestEventMapping(t *testing.T) { }, } - event := eventMapping(HostSystemTest) + var metricDataTest = metricData{ + perfMetrics: map[string]interface{}{ + "disk.capacity.usage.average": int64(100), + "disk.deviceLatency.average": int64(5), + "disk.maxTotalLatency.latest": int64(3), + "disk.usage.average": int64(10), + "disk.read.average": int64(8), + "disk.write.average": int64(1), + "net.transmitted.average": int64(2), + "net.received.average": int64(1500), + "net.usage.average": int64(1450), + "net.packetsTx.summation": int64(2000), + "net.packetsRx.summation": int64(1800), + "net.errorsTx.summation": int64(500), + "net.errorsRx.summation": int64(600), + "net.multicastTx.summation": int64(700), + "net.multicastRx.summation": int64(100), + "net.droppedTx.summation": int64(50), + "net.droppedRx.summation": int64(80), + }, + assetsName: assetNames{ + outputNetworkNames: []string{"network-1", "network-2"}, + outputDsNames: []string{"datastore-1", "datastore-2"}, + outputVmNames: []string{"vm-1", "vm-2"}, + }, + } + + event := m.eventMapping(HostSystemTest, &metricDataTest) cpuUsed, _ := event.GetValue("cpu.used.mhz") assert.EqualValues(t, 67, cpuUsed) @@ -64,4 +92,56 @@ func TestEventMapping(t *testing.T) { memoryFree, _ := event.GetValue("memory.free.bytes") assert.EqualValues(t, 0, memoryFree) + + // New asserts for PerformanceMetricsTest + diskCapacityUsage, _ := event.GetValue("disk.capacity.usage.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["disk.capacity.usage.average"].(int64)*1000, diskCapacityUsage) + diskDevicelatency, _ := event.GetValue("disk.devicelatency.average.ms") + assert.EqualValues(t, metricDataTest.perfMetrics["disk.deviceLatency.average"], diskDevicelatency) + diskLatency, _ := event.GetValue("disk.latency.total.ms") + assert.EqualValues(t, metricDataTest.perfMetrics["disk.maxTotalLatency.latest"], diskLatency) + diskTotal, _ := event.GetValue("disk.total.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["disk.usage.average"].(int64)*1000, diskTotal) + diskRead, _ := event.GetValue("disk.read.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["disk.read.average"].(int64)*1000, diskRead) + diskWrite, _ := event.GetValue("disk.write.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["disk.write.average"].(int64)*1000, diskWrite) + + networkBandwidthTransmitted, _ := event.GetValue("network.bandwidth.transmitted.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["net.transmitted.average"].(int64)*1000, networkBandwidthTransmitted) + networkBandwidthReceived, _ := event.GetValue("network.bandwidth.received.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["net.received.average"].(int64)*1000, networkBandwidthReceived) + networkBandwidthTotal, _ := event.GetValue("network.bandwidth.total.bytes") + assert.EqualValues(t, metricDataTest.perfMetrics["net.usage.average"].(int64)*1000, networkBandwidthTotal) + networkPacketsTransmitted, _ := event.GetValue("network.packets.transmitted.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.packetsTx.summation"], networkPacketsTransmitted) + networkPacketsReceived, _ := event.GetValue("network.packets.received.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.packetsRx.summation"], networkPacketsReceived) + networkPacketsErrorsTransmitted, _ := event.GetValue("network.packets.errors.transmitted.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.errorsTx.summation"], networkPacketsErrorsTransmitted) + networkPacketsErrorsReceived, _ := event.GetValue("network.packets.errors.received.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.errorsRx.summation"], networkPacketsErrorsReceived) + networkPacketsErrorsTotal, _ := event.GetValue("network.packets.errors.total.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.errorsTx.summation"].(int64)+metricDataTest.perfMetrics["net.errorsRx.summation"].(int64), networkPacketsErrorsTotal) + networkPacketsMulticastTransmitted, _ := event.GetValue("network.packets.multicast.transmitted.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.multicastTx.summation"], networkPacketsMulticastTransmitted) + networkPacketsMulticastReceived, _ := event.GetValue("network.packets.multicast.received.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.multicastRx.summation"], networkPacketsMulticastReceived) + networkPacketsMulticastTotal, _ := event.GetValue("network.packets.multicast.total.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.multicastTx.summation"].(int64)+metricDataTest.perfMetrics["net.multicastRx.summation"].(int64), networkPacketsMulticastTotal) + networkPacketsDroppedTransmitted, _ := event.GetValue("network.packets.dropped.transmitted.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.droppedTx.summation"], networkPacketsDroppedTransmitted) + networkPacketsDroppedReceived, _ := event.GetValue("network.packets.dropped.received.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.droppedRx.summation"], networkPacketsDroppedReceived) + networkPacketsDroppedTotal, _ := event.GetValue("network.packets.dropped.total.count") + assert.EqualValues(t, metricDataTest.perfMetrics["net.droppedTx.summation"].(int64)+metricDataTest.perfMetrics["net.droppedRx.summation"].(int64), networkPacketsDroppedTotal) + + networkNames, _ := event.GetValue("network_names") + assert.EqualValues(t, metricDataTest.assetsName.outputNetworkNames, networkNames) + + vmNames, _ := event.GetValue("vm.names") + assert.EqualValues(t, metricDataTest.assetsName.outputVmNames, vmNames) + + datastoreNames, _ := event.GetValue("datastore.names") + assert.EqualValues(t, metricDataTest.assetsName.outputDsNames, datastoreNames) } diff --git a/metricbeat/module/vsphere/host/host.go b/metricbeat/module/vsphere/host/host.go index 457d4a65452..1a2e3a1a7c8 100644 --- a/metricbeat/module/vsphere/host/host.go +++ b/metricbeat/module/vsphere/host/host.go @@ -19,18 +19,16 @@ package host import ( "context" - "errors" "fmt" "strings" "github.com/elastic/beats/v7/metricbeat/mb" "github.com/elastic/beats/v7/metricbeat/module/vsphere" - "github.com/elastic/elastic-agent-libs/mapstr" "github.com/vmware/govmomi" + "github.com/vmware/govmomi/performance" "github.com/vmware/govmomi/property" "github.com/vmware/govmomi/view" - "github.com/vmware/govmomi/vim25" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/types" ) @@ -56,6 +54,38 @@ func New(base mb.BaseMetricSet) (mb.MetricSet, error) { return &MetricSet{ms}, nil } +type metricData struct { + perfMetrics map[string]interface{} + assetsName assetNames +} + +type assetNames struct { + outputNetworkNames []string + outputDsNames []string + outputVmNames []string +} + +// Define metrics to be collected +var metricSet = map[string]struct{}{ + "disk.capacity.usage.average": {}, + "disk.deviceLatency.average": {}, + "disk.maxTotalLatency.latest": {}, + "disk.usage.average": {}, + "disk.read.average": {}, + "disk.write.average": {}, + "net.transmitted.average": {}, + "net.received.average": {}, + "net.usage.average": {}, + "net.packetsTx.summation": {}, + "net.packetsRx.summation": {}, + "net.errorsTx.summation": {}, + "net.errorsRx.summation": {}, + "net.multicastTx.summation": {}, + "net.multicastRx.summation": {}, + "net.droppedTx.summation": {}, + "net.droppedRx.summation": {}, +} + // Fetch methods implements the data gathering and data conversion to the right // format. It publishes the event which is then forwarded to the output. In case // of an error set the Error field of mb.Event or simply call report.Error(). @@ -70,7 +100,7 @@ func (m *MetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) error { defer func() { if err := client.Logout(ctx); err != nil { - m.Logger().Debug(fmt.Errorf("error trying to logout from vshphere: %w", err)) + m.Logger().Errorf("error trying to log out from vSphere: %w", err) } }() @@ -86,89 +116,130 @@ func (m *MetricSet) Fetch(ctx context.Context, reporter mb.ReporterV2) error { defer func() { if err := v.Destroy(ctx); err != nil { - m.Logger().Debug(fmt.Errorf("error trying to destroy view from vshphere: %w", err)) + m.Logger().Errorf("error trying to destroy view from vSphere: %w", err) } }() // Retrieve summary property for all hosts. var hst []mo.HostSystem - err = v.Retrieve(ctx, []string{"HostSystem"}, []string{"summary"}, &hst) + err = v.Retrieve(ctx, []string{"HostSystem"}, []string{"summary", "network", "name", "vm", "datastore"}, &hst) if err != nil { return fmt.Errorf("error in Retrieve: %w", err) } - for _, hs := range hst { - - event := mapstr.M{} + // Create a performance manager + perfManager := performance.NewManager(c) - event["name"] = hs.Summary.Config.Name - event.Put("cpu.used.mhz", hs.Summary.QuickStats.OverallCpuUsage) - event.Put("memory.used.bytes", int64(hs.Summary.QuickStats.OverallMemoryUsage)*1024*1024) + // Retrieve all available metrics + metrics, err := perfManager.CounterInfoByName(ctx) + if err != nil { + return fmt.Errorf("failed to retrieve metrics: %w", err) + } - if hs.Summary.Hardware != nil { - totalCPU := int64(hs.Summary.Hardware.CpuMhz) * int64(hs.Summary.Hardware.NumCpuCores) - event.Put("cpu.total.mhz", totalCPU) - event.Put("cpu.free.mhz", int64(totalCPU)-int64(hs.Summary.QuickStats.OverallCpuUsage)) - event.Put("memory.free.bytes", int64(hs.Summary.Hardware.MemorySize)-(int64(hs.Summary.QuickStats.OverallMemoryUsage)*1024*1024)) - event.Put("memory.total.bytes", hs.Summary.Hardware.MemorySize) + // Filter for required metrics + var metricIds []types.PerfMetricId + for metricName := range metricSet { + if metric, ok := metrics[metricName]; ok { + metricIds = append(metricIds, types.PerfMetricId{CounterId: metric.Key}) } else { - m.Logger().Debug("'Hardware' or 'Summary' data not found. This is either a parsing error from vsphere library, an error trying to reach host/guest or incomplete information returned from host/guest") + m.Logger().Warnf("Metric %s not found", metricName) } + } - if hs.Summary.Host != nil { - networkNames, err := getNetworkNames(ctx, c, hs.Summary.Host.Reference()) + pc := property.DefaultCollector(c) + for i := range hst { + select { + case <-ctx.Done(): + return ctx.Err() + default: + assetNames, err := getAssetNames(ctx, pc, &hst[i]) if err != nil { - m.Logger().Debugf("error trying to get network names: %s", err.Error()) - } else { - if len(networkNames) > 0 { - event["network_names"] = networkNames - } + m.Logger().Errorf("Failed to retrieve object from host %s: %w", hst[i].Name, err) } - } - reporter.Event(mb.Event{ - MetricSetFields: event, - }) - } - return nil -} + spec := types.PerfQuerySpec{ + Entity: hst[i].Reference(), + MetricId: metricIds, + MaxSample: 1, + IntervalId: 20, // right now we are only grabbing real time metrics from the performance manager + } -func getNetworkNames(ctx context.Context, c *vim25.Client, ref types.ManagedObjectReference) ([]string, error) { - var outputNetworkNames []string + // Query performance data + samples, err := perfManager.Query(ctx, []types.PerfQuerySpec{spec}) + if err != nil { + m.Logger().Errorf("Failed to query performance data from host %s: %v", hst[i].Name, err) + continue + } - pc := property.DefaultCollector(c) + if len(samples) == 0 { + m.Logger().Debug("No samples returned from performance manager") + continue + } - var hs mo.HostSystem - err := pc.RetrieveOne(ctx, ref, []string{"network"}, &hs) - if err != nil { - return nil, fmt.Errorf("error retrieving host information: %v", err) - } + results, err := perfManager.ToMetricSeries(ctx, samples) + if err != nil { + m.Logger().Errorf("Failed to convert performance data to metric series for host %s: %v", hst[i].Name, err) + } - if len(hs.Network) == 0 { - return nil, errors.New("no networks found") - } + metricMap := make(map[string]interface{}) + for _, result := range results[0].Value { + if len(result.Value) > 0 { + metricMap[result.Name] = result.Value[0] + continue + } + m.Logger().Debugf("For host %s,Metric %v: No result found", hst[i].Name, result.Name) + } - var networkRefs []types.ManagedObjectReference - for _, obj := range hs.Network { - if obj.Type == "Network" { - networkRefs = append(networkRefs, obj) + reporter.Event(mb.Event{ + MetricSetFields: m.eventMapping(hst[i], &metricData{ + perfMetrics: metricMap, + assetsName: assetNames, + }), + }) } } - if len(networkRefs) == 0 { - return nil, errors.New("no networks found") + return nil +} + +func getAssetNames(ctx context.Context, pc *property.Collector, hs *mo.HostSystem) (assetNames, error) { + referenceList := append(hs.Datastore, hs.Vm...) + + var objects []mo.ManagedEntity + if len(referenceList) > 0 { + if err := pc.Retrieve(ctx, referenceList, []string{"name"}, &objects); err != nil { + return assetNames{}, err + } } - var nets []mo.Network - err = pc.Retrieve(ctx, networkRefs, []string{"name"}, &nets) - if err != nil { - return nil, fmt.Errorf("error retrieving network from host: %v", err) + outputDsNames := make([]string, 0, len(hs.Datastore)) + outputVmNames := make([]string, 0, len(hs.Vm)) + for _, ob := range objects { + name := strings.ReplaceAll(ob.Name, ".", "_") + switch ob.Reference().Type { + case "Datastore": + outputDsNames = append(outputDsNames, name) + case "VirtualMachine": + outputVmNames = append(outputVmNames, name) + } } - for _, net := range nets { - name := strings.Replace(net.Name, ".", "_", -1) - outputNetworkNames = append(outputNetworkNames, name) + // calling network explicitly because of mo.Network's ManagedEntityObject.Name does not store Network name + // instead mo.Network.Name contains correct value of Network name + outputNetworkNames := make([]string, 0, len(hs.Network)) + if len(hs.Network) > 0 { + var netObjects []mo.Network + if err := pc.Retrieve(ctx, hs.Network, []string{"name"}, &netObjects); err != nil { + return assetNames{}, err + } + for _, ob := range netObjects { + outputNetworkNames = append(outputNetworkNames, strings.ReplaceAll(ob.Name, ".", "_")) + } } - return outputNetworkNames, nil + return assetNames{ + outputNetworkNames: outputNetworkNames, + outputDsNames: outputDsNames, + outputVmNames: outputVmNames, + }, nil } diff --git a/metricbeat/module/vsphere/host/host_test.go b/metricbeat/module/vsphere/host/host_test.go index 17bd2a09dd1..2889004a965 100644 --- a/metricbeat/module/vsphere/host/host_test.go +++ b/metricbeat/module/vsphere/host/host_test.go @@ -50,6 +50,23 @@ func TestFetchEventContents(t *testing.T) { assert.EqualValues(t, "localhost.localdomain", event["name"]) + vm := event["vm"].(mapstr.M) + assert.NotNil(t, vm["names"]) + assert.GreaterOrEqual(t, vm["count"], 0) + + dataStore := event["datastore"].(mapstr.M) + assert.NotNil(t, dataStore["names"]) + assert.GreaterOrEqual(t, dataStore["count"], 0) + + assert.NotNil(t, event["network_names"]) + network := event["network"].(mapstr.M) + assert.NotNil(t, network["names"]) + assert.GreaterOrEqual(t, network["count"], 0) + + assert.NotNil(t, event["status"]) + + assert.GreaterOrEqual(t, event["uptime"], int32(0)) + cpu := event["cpu"].(mapstr.M) cpuUsed := cpu["used"].(mapstr.M) @@ -61,6 +78,34 @@ func TestFetchEventContents(t *testing.T) { cpuFree := cpu["free"].(mapstr.M) assert.EqualValues(t, 4521, cpuFree["mhz"]) + disk := event["disk"].(mapstr.M) + + diskCapacity, ok := disk["capacity"].(mapstr.M) + if ok { + diskCapacityUsage := diskCapacity["usage"].(mapstr.M) + assert.GreaterOrEqual(t, diskCapacityUsage["bytes"], int64(0)) + } + + diskDevielatency, ok := disk["devicelatency"].(mapstr.M) + if ok { + diskDevielatencyAverage := diskDevielatency["average"].(mapstr.M) + assert.GreaterOrEqual(t, diskDevielatencyAverage["ms"], int64(0)) + } + diskLatency, ok := disk["latency"].(mapstr.M) + if ok { + diskLatencyTotal := diskLatency["total"].(mapstr.M) + assert.GreaterOrEqual(t, diskLatencyTotal["ms"], int64(0)) + } + + diskTotal := disk["total"].(mapstr.M) + assert.GreaterOrEqual(t, diskTotal["bytes"], int64(0)) + + diskRead := disk["read"].(mapstr.M) + assert.GreaterOrEqual(t, diskRead["bytes"], int64(0)) + + diskWrite := disk["write"].(mapstr.M) + assert.GreaterOrEqual(t, diskWrite["bytes"], int64(0)) + memory := event["memory"].(mapstr.M) memoryUsed := memory["used"].(mapstr.M) @@ -71,6 +116,55 @@ func TestFetchEventContents(t *testing.T) { memoryFree := memory["free"].(mapstr.M) assert.EqualValues(t, uint64(2822230016), memoryFree["bytes"]) + + network = event["network"].(mapstr.M) + + networkBandwidth := network["bandwidth"].(mapstr.M) + networkBandwidthTransmitted := networkBandwidth["transmitted"].(mapstr.M) + networkBandwidthReceived := networkBandwidth["received"].(mapstr.M) + networkBandwidthTotal := networkBandwidth["total"].(mapstr.M) + assert.GreaterOrEqual(t, networkBandwidthTransmitted["bytes"], int64(0)) + assert.GreaterOrEqual(t, networkBandwidthReceived["bytes"], int64(0)) + assert.GreaterOrEqual(t, networkBandwidthTotal["bytes"], int64(0)) + + networkPackets := network["packets"].(mapstr.M) + networkPacketsTransmitted := networkPackets["transmitted"].(mapstr.M) + networkPacketsReceived := networkPackets["received"].(mapstr.M) + assert.GreaterOrEqual(t, networkPacketsTransmitted["count"], int64(0)) + assert.GreaterOrEqual(t, networkPacketsReceived["count"], int64(0)) + + networkErrors, ok := networkPackets["errors"].(mapstr.M) + if ok { + networkErrorsTransmitted := networkErrors["transmitted"].(mapstr.M) + networkErrorsReceived := networkErrors["received"].(mapstr.M) + networkErrorsTotal := networkErrors["total"].(mapstr.M) + assert.GreaterOrEqual(t, networkErrorsTransmitted["count"], int64(0)) + assert.GreaterOrEqual(t, networkErrorsReceived["count"], int64(0)) + assert.GreaterOrEqual(t, networkErrorsTotal["count"], int64(0)) + } + + networkMulticast := networkPackets["multicast"].(mapstr.M) + if networkMulticastTransmitted, ok := networkMulticast["transmitted"].(mapstr.M); ok { + assert.GreaterOrEqual(t, networkMulticastTransmitted["count"], int64(0)) + } + if networkMulticastReceived, ok := networkMulticast["received"].(mapstr.M); ok { + assert.GreaterOrEqual(t, networkMulticastReceived["count"], int64(0)) + } + if networkMulticastTotal, ok := networkMulticast["total"].(mapstr.M); ok { + assert.GreaterOrEqual(t, networkMulticastTotal["count"], int64(0)) + } + + if networkDropped, ok := networkPackets["dropped"].(mapstr.M); ok { + if networkDroppedTransmitted, ok := networkDropped["transmitted"].(mapstr.M); ok { + assert.GreaterOrEqual(t, networkDroppedTransmitted["count"], int64(0)) + } + if networkDroppedReceived, ok := networkDropped["received"].(mapstr.M); ok { + assert.GreaterOrEqual(t, networkDroppedReceived["count"], int64(0)) + } + if networkDroppedTotal, ok := networkDropped["total"].(mapstr.M); ok { + assert.GreaterOrEqual(t, networkDroppedTotal["count"], int64(0)) + } + } } func TestData(t *testing.T) { diff --git a/metricbeat/modules.d/vsphere.yml.disabled b/metricbeat/modules.d/vsphere.yml.disabled index 874b3b5b2e8..6659aa39bbc 100644 --- a/metricbeat/modules.d/vsphere.yml.disabled +++ b/metricbeat/modules.d/vsphere.yml.disabled @@ -6,7 +6,8 @@ # - datastore # - host # - virtualmachine - period: 10s + # Real-time data collection – An ESXi Server collects data for each performance counter every 20 seconds. + period: 20s hosts: ["https://localhost/sdk"] username: "user" diff --git a/x-pack/metricbeat/metricbeat.reference.yml b/x-pack/metricbeat/metricbeat.reference.yml index 1d2957306db..026c1c6f993 100644 --- a/x-pack/metricbeat/metricbeat.reference.yml +++ b/x-pack/metricbeat/metricbeat.reference.yml @@ -1569,7 +1569,8 @@ metricbeat.modules: - module: vsphere enabled: true metricsets: ["datastore", "host", "virtualmachine"] - period: 10s + # Real-time data collection – An ESXi Server collects data for each performance counter every 20 seconds. + period: 20s hosts: ["https://localhost/sdk"] username: "user"