diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java index 71ec050b481..4c475229ae5 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsNodes.java @@ -87,7 +87,7 @@ public class ClusterStatsNodes implements ToXContent { } } this.counts = new Counts(nodeInfos); - this.os = new OsStats(nodeInfos); + this.os = new OsStats(nodeInfos, nodeStats); this.process = new ProcessStats(nodeStats); this.jvm = new JvmStats(nodeInfos, nodeStats); this.networkTypes = new NetworkTypes(nodeInfos); @@ -226,11 +226,12 @@ public class ClusterStatsNodes implements ToXContent { final int availableProcessors; final int allocatedProcessors; final ObjectIntHashMap names; + final org.elasticsearch.monitor.os.OsStats.Mem mem; /** * Build the stats from information about each node. */ - private OsStats(List nodeInfos) { + private OsStats(List nodeInfos, List nodeStatsList) { this.names = new ObjectIntHashMap<>(); int availableProcessors = 0; int allocatedProcessors = 0; @@ -244,6 +245,22 @@ public class ClusterStatsNodes implements ToXContent { } this.availableProcessors = availableProcessors; this.allocatedProcessors = allocatedProcessors; + + long totalMemory = 0; + long freeMemory = 0; + for (NodeStats nodeStats : nodeStatsList) { + if (nodeStats.getOs() != null) { + long total = nodeStats.getOs().getMem().getTotal().bytes(); + if (total > 0) { + totalMemory += total; + } + long free = nodeStats.getOs().getMem().getFree().bytes(); + if (free > 0) { + freeMemory += free; + } + } + } + this.mem = new org.elasticsearch.monitor.os.OsStats.Mem(totalMemory, freeMemory); } public int getAvailableProcessors() { @@ -254,6 +271,10 @@ public class ClusterStatsNodes implements ToXContent { return allocatedProcessors; } + public org.elasticsearch.monitor.os.OsStats.Mem getMem() { + return mem; + } + static final class Fields { static final String AVAILABLE_PROCESSORS = "available_processors"; static final String ALLOCATED_PROCESSORS = "allocated_processors"; @@ -274,6 +295,7 @@ public class ClusterStatsNodes implements ToXContent { builder.endObject(); } builder.endArray(); + mem.toXContent(builder, params); return builder; } } diff --git a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java index 72287c84662..3eb73273832 100644 --- a/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java +++ b/core/src/main/java/org/elasticsearch/action/admin/cluster/stats/TransportClusterStatsAction.java @@ -92,7 +92,7 @@ public class TransportClusterStatsAction extends TransportNodesAction shardsStats = new ArrayList<>(); for (IndexService indexService : indicesService) { for (IndexShard indexShard : indexService) { diff --git a/core/src/test/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIT.java b/core/src/test/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIT.java index f2ed690bb9c..b8068083e66 100644 --- a/core/src/test/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIT.java +++ b/core/src/test/java/org/elasticsearch/action/admin/cluster/stats/ClusterStatsIT.java @@ -181,6 +181,12 @@ public class ClusterStatsIT extends ESIntegTestCase { assertThat(msg, response.nodesStats.getProcess().getMinOpenFileDescriptors(), Matchers.greaterThanOrEqualTo(-1L)); assertThat(msg, response.nodesStats.getProcess().getMaxOpenFileDescriptors(), Matchers.greaterThanOrEqualTo(-1L)); + assertThat(msg, response.nodesStats.getOs().getMem().getFree().bytes(), Matchers.greaterThanOrEqualTo(0L)); + assertThat(msg, response.nodesStats.getOs().getMem().getTotal().bytes(), Matchers.greaterThanOrEqualTo(0L)); + assertThat(msg, response.nodesStats.getOs().getMem().getUsed().bytes(), Matchers.greaterThanOrEqualTo(0L)); + assertThat(msg, response.nodesStats.getOs().getMem().getUsedPercent(), Matchers.greaterThanOrEqualTo((short)0)); + assertThat(msg, response.nodesStats.getOs().getMem().getFreePercent(), Matchers.greaterThanOrEqualTo((short)0)); + } public void testAllocatedProcessors() throws Exception { diff --git a/docs/reference/cluster/stats.asciidoc b/docs/reference/cluster/stats.asciidoc index 4758ea2b0c4..a95273f85f9 100644 --- a/docs/reference/cluster/stats.asciidoc +++ b/docs/reference/cluster/stats.asciidoc @@ -116,7 +116,17 @@ Will return, for example: "name": "Mac OS X", "count": 1 } - ] + ], + "mem" : { + "total" : "16gb", + "total_in_bytes" : 17179869184, + "free" : "78.1mb", + "free_in_bytes" : 81960960, + "used" : "15.9gb", + "used_in_bytes" : 17097908224, + "free_percent" : 0, + "used_percent" : 100 + } }, "process": { "cpu": { diff --git a/docs/reference/migration/migrate_5_0/java.asciidoc b/docs/reference/migration/migrate_5_0/java.asciidoc index 270e9a20681..e0f7fba26b0 100644 --- a/docs/reference/migration/migrate_5_0/java.asciidoc +++ b/docs/reference/migration/migrate_5_0/java.asciidoc @@ -349,7 +349,9 @@ The `setQuery(BytesReference)` method have been removed in favor of using `setQu ==== ClusterStatsResponse Removed the `getMemoryAvailable` method from `OsStats`, which could be previously accessed calling -`clusterStatsResponse.getNodesStats().getOs().getMemoryAvailable()`. +`clusterStatsResponse.getNodesStats().getOs().getMemoryAvailable()`. It is now replaced with +`clusterStatsResponse.getNodesStats().getOs().getMem()` which exposes `getTotal()`, `getFree()`, +`getUsed()`, `getFreePercent()` and `getUsedPercent()`. ==== setRefresh(boolean) has been removed diff --git a/docs/reference/migration/migrate_5_0/rest.asciidoc b/docs/reference/migration/migrate_5_0/rest.asciidoc index 278acd52c43..6df1341b0cc 100644 --- a/docs/reference/migration/migrate_5_0/rest.asciidoc +++ b/docs/reference/migration/migrate_5_0/rest.asciidoc @@ -29,9 +29,9 @@ document exists in an index. The old endpoint will keep working until 6.0. ==== Removed `mem` section from `/_cluster/stats` response -The `mem` section contained only one value, the total memory available -throughout all nodes in the cluster. The section was removed as it didn't -prove useful. +The `mem` section contained only the `total` value, which was actually the +memory available throughout all nodes in the cluster. The section contains now +`total`, `free`, `used`, `used_percent` and `free_percent`. ==== Revised node roles aggregate returned by `/_cluster/stats` diff --git a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.stats/10_basic.yaml b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.stats/10_basic.yaml index 08d13e04bea..ccbfc199cec 100644 --- a/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.stats/10_basic.yaml +++ b/rest-api-spec/src/main/resources/rest-api-spec/test/cluster.stats/10_basic.yaml @@ -19,6 +19,11 @@ - gte: { nodes.count.ingest: 0} - gte: { nodes.count.coordinating_only: 0} - is_true: nodes.os + - is_true: nodes.os.mem.total_in_bytes + - is_true: nodes.os.mem.free_in_bytes + - is_true: nodes.os.mem.used_in_bytes + - is_true: nodes.os.mem.free_percent + - is_true: nodes.os.mem.used_percent - is_true: nodes.process - is_true: nodes.jvm - is_true: nodes.fs