diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 585d7eddb56..c8794d801a8 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -282,6 +282,8 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Add `redisenterprise` module. {pull}16482[16482] {issue}15269[15269] - Add `cloudfoundry` module to send events from Cloud Foundry. {pull}16671[16671] - Align fields to ECS and add more tests for the azure module. {issue}16024[16024] {pull}16754[16754] +- Add additional cgroup fields to docker/diskio{pull}16638[16638] +- Add PubSub metricset to Google Cloud Platform module {pull}15536[15536] *Packetbeat* diff --git a/metricbeat/docs/fields.asciidoc b/metricbeat/docs/fields.asciidoc index ddd4993a6f3..40ed7d675fd 100644 --- a/metricbeat/docs/fields.asciidoc +++ b/metricbeat/docs/fields.asciidoc @@ -6509,6 +6509,36 @@ format: bytes Number of current reads per second +type: long + +-- + +*`docker.diskio.read.service_time`*:: ++ +-- +Total time to service IO requests, in nanoseconds + + +type: long + +-- + +*`docker.diskio.read.wait_time`*:: ++ +-- +Total time requests spent waiting in queues for service, in nanoseconds + + +type: long + +-- + +*`docker.diskio.read.queued`*:: ++ +-- +Total number of queued requests + + type: long -- @@ -6561,6 +6591,36 @@ format: bytes Number of current writes per second +type: long + +-- + +*`docker.diskio.write.service_time`*:: ++ +-- +Total time to service IO requests, in nanoseconds + + +type: long + +-- + +*`docker.diskio.write.wait_time`*:: ++ +-- +Total time requests spent waiting in queues for service, in nanoseconds + + +type: long + +-- + +*`docker.diskio.write.queued`*:: ++ +-- +Total number of queued requests + + type: long -- @@ -6613,6 +6673,36 @@ format: bytes Number of current operations per second +type: long + +-- + +*`docker.diskio.summary.service_time`*:: ++ +-- +Total time to service IO requests, in nanoseconds + + +type: long + +-- + +*`docker.diskio.summary.wait_time`*:: ++ +-- +Total time requests spent waiting in queues for service, in nanoseconds + + +type: long + +-- + +*`docker.diskio.summary.queued`*:: ++ +-- +Total number of queued requests + + type: long -- diff --git a/metricbeat/module/docker/diskio/_meta/data.json b/metricbeat/module/docker/diskio/_meta/data.json index 2fba47412c8..1ccb1ca7936 100644 --- a/metricbeat/module/docker/diskio/_meta/data.json +++ b/metricbeat/module/docker/diskio/_meta/data.json @@ -1,55 +1,40 @@ { "@timestamp": "2017-10-12T08:05:34.853Z", - "agent": { - "hostname": "host.example.com", - "name": "host.example.com" - }, "container": { - "id": "cc78e58acfda4501105dc4de8e3ae218f2da616213e6e3af168c40103829302a", + "id": "8abaa1f3514d3554503034a1df6ee09457f328757bbc9555245244ee853c0b44", "image": { - "name": "metricbeat_elasticsearch" + "name": "zookeeper" }, - "name": "metricbeat_elasticsearch_1_df866b3a7b3d", + "name": "some-zookeeper", "runtime": "docker" }, "docker": { - "container": { - "labels": { - "com_docker_compose_config-hash": "e3e0a2c6e5d1afb741bc8b1ecb09cda0395886b7a3e5084a9fd110be46d70f78", - "com_docker_compose_container-number": "1", - "com_docker_compose_oneoff": "False", - "com_docker_compose_project": "metricbeat", - "com_docker_compose_service": "elasticsearch", - "com_docker_compose_slug": "df866b3a7b3d50c0802350cbe58ee5b34fa32b7f6ba7fe9e48cde2c12dd0201d", - "com_docker_compose_version": "1.23.1", - "license": "Elastic License", - "org_label-schema_build-date": "20181006", - "org_label-schema_license": "GPLv2", - "org_label-schema_name": "elasticsearch", - "org_label-schema_schema-version": "1.0", - "org_label-schema_url": "https://www.elastic.co/products/elasticsearch", - "org_label-schema_vcs-url": "https://github.com/elastic/elasticsearch-docker", - "org_label-schema_vendor": "Elastic", - "org_label-schema_version": "6.5.1" - } - }, "diskio": { "read": { - "bytes": 998932480, - "ops": 8473, - "rate": 0 + "bytes": 42409984, + "ops": 1823, + "queued": 0, + "rate": 0, + "service_time": 0, + "wait_time": 0 }, "reads": 0, "summary": { - "bytes": 1090650112, - "ops": 9585, - "rate": 0 + "bytes": 42414080, + "ops": 1824, + "queued": 0, + "rate": 0, + "service_time": 0, + "wait_time": 0 }, "total": 0, "write": { - "bytes": 91717632, - "ops": 1112, - "rate": 0 + "bytes": 4096, + "ops": 1, + "queued": 0, + "rate": 0, + "service_time": 0, + "wait_time": 0 }, "writes": 0 } @@ -60,7 +45,8 @@ "module": "docker" }, "metricset": { - "name": "diskio" + "name": "diskio", + "period": 10000 }, "service": { "address": "/var/run/docker.sock", diff --git a/metricbeat/module/docker/diskio/_meta/fields.yml b/metricbeat/module/docker/diskio/_meta/fields.yml index 2e207ff7e0b..71f9e22859a 100644 --- a/metricbeat/module/docker/diskio/_meta/fields.yml +++ b/metricbeat/module/docker/diskio/_meta/fields.yml @@ -22,6 +22,18 @@ type: long description: > Number of current reads per second + - name: service_time + type: long + description: > + Total time to service IO requests, in nanoseconds + - name: wait_time + type: long + description: > + Total time requests spent waiting in queues for service, in nanoseconds + - name: queued + type: long + description: > + Total number of queued requests - name: reads type: scaled_float deprecated: 6.4 @@ -45,6 +57,18 @@ type: long description: > Number of current writes per second + - name: service_time + type: long + description: > + Total time to service IO requests, in nanoseconds + - name: wait_time + type: long + description: > + Total time requests spent waiting in queues for service, in nanoseconds + - name: queued + type: long + description: > + Total number of queued requests - name: writes type: scaled_float deprecated: 6.4 @@ -68,6 +92,18 @@ type: long description: > Number of current operations per second + - name: service_time + type: long + description: > + Total time to service IO requests, in nanoseconds + - name: wait_time + type: long + description: > + Total time requests spent waiting in queues for service, in nanoseconds + - name: queued + type: long + description: > + Total number of queued requests - name: total type: scaled_float deprecated: 6.4 diff --git a/metricbeat/module/docker/diskio/data.go b/metricbeat/module/docker/diskio/data.go index 85b975ffeae..04665ca85cc 100644 --- a/metricbeat/module/docker/diskio/data.go +++ b/metricbeat/module/docker/diskio/data.go @@ -34,19 +34,28 @@ func eventMapping(r mb.ReporterV2, stats *BlkioStats) { "writes": stats.writes, "total": stats.totals, "read": common.MapStr{ - "ops": stats.serviced.reads, - "bytes": stats.servicedBytes.reads, - "rate": stats.reads, + "ops": stats.serviced.reads, + "bytes": stats.servicedBytes.reads, + "rate": stats.reads, + "service_time": stats.servicedTime.reads, + "wait_time": stats.waitTime.reads, + "queued": stats.queued.reads, }, "write": common.MapStr{ - "ops": stats.serviced.writes, - "bytes": stats.servicedBytes.writes, - "rate": stats.writes, + "ops": stats.serviced.writes, + "bytes": stats.servicedBytes.writes, + "rate": stats.writes, + "service_time": stats.servicedTime.writes, + "wait_time": stats.waitTime.writes, + "queued": stats.queued.writes, }, "summary": common.MapStr{ - "ops": stats.serviced.totals, - "bytes": stats.servicedBytes.totals, - "rate": stats.totals, + "ops": stats.serviced.totals, + "bytes": stats.servicedBytes.totals, + "rate": stats.totals, + "service_time": stats.servicedTime.totals, + "wait_time": stats.waitTime.totals, + "queued": stats.queued.totals, }, } diff --git a/metricbeat/module/docker/diskio/diskio.go b/metricbeat/module/docker/diskio/diskio.go index 8868d1607f7..6106c52322e 100644 --- a/metricbeat/module/docker/diskio/diskio.go +++ b/metricbeat/module/docker/diskio/diskio.go @@ -34,6 +34,7 @@ func init() { ) } +// MetricSet type defines all fields of the MetricSet type MetricSet struct { mb.BaseMetricSet blkioService *BlkioService diff --git a/metricbeat/module/docker/diskio/diskio_test.go b/metricbeat/module/docker/diskio/diskio_test.go index 520ec7bd265..8083449c43c 100644 --- a/metricbeat/module/docker/diskio/diskio_test.go +++ b/metricbeat/module/docker/diskio/diskio_test.go @@ -256,6 +256,30 @@ func TestGetBlkioStatsList(t *testing.T) { {Major: 1, Minor: 2, Op: "Write", Value: 1000}, {Major: 1, Minor: 2, Op: "Total", Value: 1500}, }, + IoServiceTimeRecursive: []types.BlkioStatEntry{ + {Major: 1, Minor: 1, Op: "Read", Value: 10000}, + {Major: 1, Minor: 1, Op: "Write", Value: 20000}, + {Major: 1, Minor: 1, Op: "Total", Value: 30000}, + {Major: 1, Minor: 2, Op: "Read", Value: 500}, + {Major: 1, Minor: 2, Op: "Write", Value: 1500}, + {Major: 1, Minor: 2, Op: "Total", Value: 2000}, + }, + IoWaitTimeRecursive: []types.BlkioStatEntry{ + {Major: 1, Minor: 1, Op: "Read", Value: 1000000}, + {Major: 1, Minor: 1, Op: "Write", Value: 25604332}, + {Major: 1, Minor: 1, Op: "Total", Value: 26604332}, + {Major: 1, Minor: 2, Op: "Read", Value: 500}, + {Major: 1, Minor: 2, Op: "Write", Value: 1500}, + {Major: 1, Minor: 2, Op: "Total", Value: 2000}, + }, + IoQueuedRecursive: []types.BlkioStatEntry{ + {Major: 1, Minor: 1, Op: "Read", Value: 100}, + {Major: 1, Minor: 1, Op: "Write", Value: 200}, + {Major: 1, Minor: 1, Op: "Total", Value: 300}, + {Major: 1, Minor: 2, Op: "Read", Value: 50}, + {Major: 1, Minor: 2, Op: "Write", Value: 100}, + {Major: 1, Minor: 2, Op: "Total", Value: 150}, + }, }, }}, }} @@ -271,6 +295,15 @@ func TestGetBlkioStatsList(t *testing.T) { assert.Equal(t, BlkioRaw{Time: later, reads: 1500, writes: 3000, totals: 4500}, stats.servicedBytes) + assert.Equal(t, + BlkioRaw{Time: later, reads: 10500, writes: 21500, totals: 32000}, + stats.servicedTime) + assert.Equal(t, + BlkioRaw{Time: later, reads: 1000500, writes: 25605832, totals: 26606332}, + stats.waitTime) + assert.Equal(t, + BlkioRaw{Time: later, reads: 150, writes: 300, totals: 450}, + stats.queued) } func TestGetBlkioStatsListWindows(t *testing.T) { diff --git a/metricbeat/module/docker/diskio/helper.go b/metricbeat/module/docker/diskio/helper.go index 6f984f1860d..96e9cf99b7d 100644 --- a/metricbeat/module/docker/diskio/helper.go +++ b/metricbeat/module/docker/diskio/helper.go @@ -25,6 +25,7 @@ import ( "github.com/elastic/beats/v7/metricbeat/module/docker" ) +// BlkioStats contains all formatted blkio stats type BlkioStats struct { Time time.Time Container *docker.Container @@ -34,6 +35,9 @@ type BlkioStats struct { serviced BlkioRaw servicedBytes BlkioRaw + servicedTime BlkioRaw + waitTime BlkioRaw + queued BlkioRaw } // Add adds blkio stats @@ -46,6 +50,7 @@ func (s *BlkioStats) Add(o *BlkioStats) { s.servicedBytes.Add(&o.servicedBytes) } +// BlkioRaw sums raw Blkio stats type BlkioRaw struct { Time time.Time reads uint64 @@ -130,6 +135,15 @@ func (io *BlkioService) getBlkioStats(myRawStat *docker.Stat, dedot bool) BlkioS servicedBytes: io.getNewStats( myRawStat.Stats.Read, myRawStat.Stats.BlkioStats.IoServiceBytesRecursive), + servicedTime: io.getNewStats( + myRawStat.Stats.Read, + myRawStat.Stats.BlkioStats.IoServiceTimeRecursive), + waitTime: io.getNewStats( + myRawStat.Stats.Read, + myRawStat.Stats.BlkioStats.IoWaitTimeRecursive), + queued: io.getNewStats( + myRawStat.Stats.Read, + myRawStat.Stats.BlkioStats.IoQueuedRecursive), } } diff --git a/metricbeat/module/docker/fields.go b/metricbeat/module/docker/fields.go index 31e6287f9a8..89cd5fc99a9 100644 --- a/metricbeat/module/docker/fields.go +++ b/metricbeat/module/docker/fields.go @@ -32,5 +32,5 @@ func init() { // AssetDocker returns asset data. // This is the base64 encoded gzipped contents of ../metricbeat/module/docker. func AssetDocker() string { - return "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" + return "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" }