Skip to content

Commit 9047287

Browse files
piotrsulkowski-elasticjfreden
authored andcommitted
available_processors field in CAT Nodes (elastic#135936)
Cat nodes REST action will return an extra field: available_processors. It is now also part of all responses which contain Os Stats. Closes elastic#134692
1 parent a051033 commit 9047287

File tree

13 files changed

+89
-14
lines changed

13 files changed

+89
-14
lines changed

rest-api-spec/src/yamlRestTest/resources/rest-api-spec/test/cat.nodes/10_basic.yml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
---
22
"Test cat nodes output":
3-
43
- do:
54
cat.nodes: {}
65

76
- match:
87
$body: |
9-
/ #ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
10-
^ ((\d{1,3}\.){3}\d{1,3} \s+ \d+ \s+ \d* \s+ (-)?\d* \s+ ((-)?\d*(\.\d+)?)? \s+ ((-)?\d*(\.\d+)?)?\s+ ((-)?\d*(\.\d+)?)? \s+ (-|[cdfhilmrstvwIS]{1,11}) \s+ [-*x] \s+ .* \n)+ $/
8+
/ #ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name
9+
^ ((\d{1,3}\.){3}\d{1,3} \s+ \d+ \s+ \d* \s+ (-)?\d* \s+ ((-)?\d*(\.\d+)?)? \s+ ((-)?\d*(\.\d+)?)?\s+ ((-)?\d*(\.\d+)?)? \s+ (-|[cdfhilmrstvwIS]{1,11}) \s+ [-*x] \s+ .* \n)+ $/
1110
1211
- do:
1312
cat.nodes:
1413
v: true
1514

1615
- match:
1716
$body: |
18-
/^ ip \s+ heap\.percent \s+ ram\.percent \s+ cpu \s+ load_1m \s+ load_5m \s+ load_15m \s+ node\.role \s+ master \s+ name \n
19-
((\d{1,3}\.){3}\d{1,3} \s+ \d+ \s+ \d* \s+ (-)?\d* \s+ ((-)?\d*(\.\d+)?)? \s+ ((-)?\d*(\.\d+)?)? \s+ ((-)?\d*(\.\d+)?)? \s+ (-|[cdfhilmrstvwIS]{1,11}) \s+ [-*x] \s+ .* \n)+ $/
17+
/^ ip \s+ heap\.percent \s+ ram\.percent \s+ cpu \s+ load_1m \s+ load_5m \s+ load_15m \s+ node\.role \s+ master \s+ name \n
18+
((\d{1,3}\.){3}\d{1,3} \s+ \d+ \s+ \d* \s+ (-)?\d* \s+ ((-)?\d*(\.\d+)?)? \s+ ((-)?\d*(\.\d+)?)? \s+ ((-)?\d*(\.\d+)?)? \s+ (-|[cdfhilmrstvwIS]{1,11}) \s+ [-*x] \s+ .* \n)+ $/
2019
2120
- do:
2221
cat.nodes:
@@ -58,6 +57,26 @@
5857
$body: |
5958
/^ http \n ((\d{1,3}\.){3}\d{1,3}:\d{1,5}\n)+ $/
6059
60+
---
61+
"Test cat nodes output for all fields with available_processors":
62+
- requires:
63+
capabilities:
64+
- method: GET
65+
path: /_cat/nodes
66+
capabilities: [ available_processors_availability ]
67+
test_runner_features: [ capabilities ]
68+
reason: available_processors capability required to run test
69+
70+
- do:
71+
cat.nodes:
72+
h: ap,available_processors
73+
v: true
74+
75+
- match:
76+
$body: |
77+
/^ ap \s+ available_processors \n
78+
( \s+ \d+ \s+ \d+ \n )+ $/
79+
6180
---
6281
"Additional disk information":
6382
- do:

server/src/main/java/org/elasticsearch/monitor/os/OsProbe.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public class OsProbe {
7272
private static final Method getTotalSwapSpaceSize;
7373
private static final Method getSystemLoadAverage;
7474
private static final Method getSystemCpuLoad;
75+
private static final Method getAvailableProcessors;
7576

7677
static {
7778
getFreePhysicalMemorySize = getMethod("getFreePhysicalMemorySize");
@@ -80,6 +81,7 @@ public class OsProbe {
8081
getTotalSwapSpaceSize = getMethod("getTotalSwapSpaceSize");
8182
getSystemLoadAverage = getMethod("getSystemLoadAverage");
8283
getSystemCpuLoad = getMethod("getSystemCpuLoad");
84+
getAvailableProcessors = getMethod("getAvailableProcessors");
8385
}
8486

8587
/**
@@ -259,6 +261,24 @@ public static short getSystemCpuPercent() {
259261
return Probes.getLoadAndScaleToPercent(getSystemCpuLoad, osMxBean);
260262
}
261263

264+
public static int getAvailableProcessors() {
265+
if (getAvailableProcessors == null) {
266+
logger.warn("getAvailableProcessors is not available");
267+
return 0;
268+
}
269+
try {
270+
int availableProcessors = (int) getAvailableProcessors.invoke(osMxBean);
271+
if (availableProcessors <= 0) {
272+
logger.debug("OS reported a non-positive number of available processors [{}]", availableProcessors);
273+
return 0;
274+
}
275+
return availableProcessors;
276+
} catch (Exception e) {
277+
logger.warn("exception retrieving available processors", e);
278+
return 0;
279+
}
280+
}
281+
262282
/**
263283
* Reads a file containing a single line.
264284
*
@@ -902,7 +922,7 @@ OsStats.Cgroup getCgroup(boolean isLinux) {
902922
}
903923

904924
public OsStats osStats() {
905-
final OsStats.Cpu cpu = new OsStats.Cpu(getSystemCpuPercent(), getSystemLoadAverage());
925+
final OsStats.Cpu cpu = new OsStats.Cpu(getSystemCpuPercent(), getSystemLoadAverage(), getAvailableProcessors());
906926
final OsStats.Mem mem = new OsStats.Mem(getTotalPhysicalMemorySize(), getAdjustedTotalMemorySize(), getFreePhysicalMemorySize());
907927
final OsStats.Swap swap = new OsStats.Swap(getTotalSwapSpaceSize(), getFreeSwapSpaceSize());
908928
final OsStats.Cgroup cgroup = getCgroup(Constants.LINUX);

server/src/main/java/org/elasticsearch/monitor/os/OsService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ private static class OsStatsCache extends SingleObjectCache<OsStats> {
5555

5656
private static final OsStats MISSING = new OsStats(
5757
0L,
58-
new OsStats.Cpu((short) 0, new double[0]),
58+
new OsStats.Cpu((short) 0, new double[0], 0),
5959
new OsStats.Mem(0, 0, 0),
6060
new OsStats.Swap(0, 0),
6161
null

server/src/main/java/org/elasticsearch/monitor/os/OsStats.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import org.apache.logging.log4j.LogManager;
1313
import org.apache.logging.log4j.Logger;
14+
import org.elasticsearch.TransportVersion;
1415
import org.elasticsearch.common.io.stream.StreamInput;
1516
import org.elasticsearch.common.io.stream.StreamOutput;
1617
import org.elasticsearch.common.io.stream.Writeable;
@@ -85,6 +86,7 @@ static final class Fields {
8586
static final String LOAD_AVERAGE_1M = "1m";
8687
static final String LOAD_AVERAGE_5M = "5m";
8788
static final String LOAD_AVERAGE_15M = "15m";
89+
static final String AVAILABLE_PROCESSORS = "available_processors";
8890

8991
static final String MEM = "mem";
9092
static final String SWAP = "swap";
@@ -117,12 +119,18 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
117119

118120
public static class Cpu implements Writeable, ToXContentFragment {
119121

122+
private static final TransportVersion AVAILABLE_PROCESSORS_TRANSPORT_VERSION = TransportVersion.fromName(
123+
"available_processors_in_os_stats"
124+
);
125+
120126
private final short percent;
121127
private final double[] loadAverage;
128+
private final int availableProcessors;
122129

123-
public Cpu(short systemCpuPercent, double[] systemLoadAverage) {
130+
public Cpu(short systemCpuPercent, double[] systemLoadAverage, int availableProcessors) {
124131
this.percent = systemCpuPercent;
125132
this.loadAverage = systemLoadAverage;
133+
this.availableProcessors = availableProcessors;
126134
}
127135

128136
public Cpu(StreamInput in) throws IOException {
@@ -132,6 +140,7 @@ public Cpu(StreamInput in) throws IOException {
132140
} else {
133141
this.loadAverage = null;
134142
}
143+
this.availableProcessors = in.getTransportVersion().supports(AVAILABLE_PROCESSORS_TRANSPORT_VERSION) ? in.readInt() : 0;
135144
}
136145

137146
@Override
@@ -143,6 +152,9 @@ public void writeTo(StreamOutput out) throws IOException {
143152
out.writeBoolean(true);
144153
out.writeDoubleArray(loadAverage);
145154
}
155+
if (out.getTransportVersion().supports(AVAILABLE_PROCESSORS_TRANSPORT_VERSION)) {
156+
out.writeInt(availableProcessors);
157+
}
146158
}
147159

148160
public short getPercent() {
@@ -153,6 +165,10 @@ public double[] getLoadAverage() {
153165
return loadAverage;
154166
}
155167

168+
public int getAvailableProcessors() {
169+
return availableProcessors;
170+
}
171+
156172
@Override
157173
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
158174
builder.startObject(Fields.CPU);
@@ -170,6 +186,7 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
170186
}
171187
builder.endObject();
172188
}
189+
builder.field(Fields.AVAILABLE_PROCESSORS, getAvailableProcessors());
173190
builder.endObject();
174191
return builder;
175192
}

server/src/main/java/org/elasticsearch/rest/action/cat/RestNodesAction.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.elasticsearch.common.network.NetworkAddress;
2929
import org.elasticsearch.common.transport.TransportAddress;
3030
import org.elasticsearch.common.unit.ByteSizeValue;
31+
import org.elasticsearch.common.util.set.Sets;
3132
import org.elasticsearch.http.HttpInfo;
3233
import org.elasticsearch.index.bulk.stats.BulkStats;
3334
import org.elasticsearch.index.cache.query.QueryCacheStats;
@@ -58,6 +59,7 @@
5859
import org.elasticsearch.search.suggest.completion.CompletionStats;
5960

6061
import java.util.List;
62+
import java.util.Set;
6163
import java.util.concurrent.atomic.AtomicReference;
6264

6365
import static org.elasticsearch.rest.RestRequest.Method.GET;
@@ -66,6 +68,8 @@
6668
@ServerlessScope(Scope.INTERNAL)
6769
public class RestNodesAction extends AbstractCatAction {
6870

71+
private static final String CAPABILITY_AVAILABLE_PROCESSORS_AVAILABILITY = "available_processors_availability";
72+
6973
@Override
7074
public List<Route> routes() {
7175
return List.of(new Route(GET, "/_cat/nodes"));
@@ -168,6 +172,7 @@ protected Table getTableWithHeader(final RestRequest request) {
168172
table.addCell("load_1m", "alias:l;text-align:right;desc:1m load avg");
169173
table.addCell("load_5m", "alias:l;text-align:right;desc:5m load avg");
170174
table.addCell("load_15m", "alias:l;text-align:right;desc:15m load avg");
175+
table.addCell("available_processors", "default:false;alias:ap;text-align:right;desc:available processors");
171176
table.addCell("uptime", "default:false;alias:u;text-align:right;desc:node uptime");
172177
table.addCell(
173178
"node.role",
@@ -335,6 +340,11 @@ protected Table getTableWithHeader(final RestRequest request) {
335340
return table;
336341
}
337342

343+
@Override
344+
public Set<String> supportedCapabilities() {
345+
return Sets.union(super.supportedCapabilities(), Set.of(CAPABILITY_AVAILABLE_PROCESSORS_AVAILABILITY));
346+
}
347+
338348
Table buildTable(
339349
boolean fullId,
340350
RestRequest req,
@@ -425,6 +435,8 @@ Table buildTable(
425435
? null
426436
: RestTable.FormattedDouble.format2DecimalPlaces(osStats.getCpu().getLoadAverage()[2])
427437
);
438+
table.addCell(osStats == null ? null : osStats.getCpu().getAvailableProcessors());
439+
428440
table.addCell(jvmStats == null ? null : jvmStats.getUptime());
429441

430442
table.addCell(node.getRoleAbbreviationString());
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
9193000
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
indices_options_resolution_mode,9192000
1+
available_processors_in_os_stats,9193000

server/src/test/java/org/elasticsearch/action/admin/cluster/node/stats/NodeStatsTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,10 @@ public void testSerialization() throws IOException {
130130
assertEquals(nodeStats.getOs().getMem().getFreePercent(), deserializedNodeStats.getOs().getMem().getFreePercent());
131131
assertEquals(nodeStats.getOs().getMem().getUsedPercent(), deserializedNodeStats.getOs().getMem().getUsedPercent());
132132
assertEquals(nodeStats.getOs().getCpu().getPercent(), deserializedNodeStats.getOs().getCpu().getPercent());
133+
assertEquals(
134+
nodeStats.getOs().getCpu().getAvailableProcessors(),
135+
deserializedNodeStats.getOs().getCpu().getAvailableProcessors()
136+
);
133137
assertEquals(
134138
nodeStats.getOs().getCgroup().getCpuAcctControlGroup(),
135139
deserializedNodeStats.getOs().getCgroup().getCpuAcctControlGroup()
@@ -711,7 +715,7 @@ public static NodeStats createNodeStats() {
711715
long swapTotal = randomNonNegativeLong();
712716
osStats = new OsStats(
713717
System.currentTimeMillis(),
714-
new OsStats.Cpu(randomShort(), loadAverages),
718+
new OsStats.Cpu(randomShort(), loadAverages, randomInt()),
715719
new OsStats.Mem(memTotal, randomLongBetween(0, memTotal), randomLongBetween(0, memTotal)),
716720
new OsStats.Swap(swapTotal, randomLongBetween(0, swapTotal)),
717721
new OsStats.Cgroup(

server/src/test/java/org/elasticsearch/monitor/os/OsProbeTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ public void testOsStats() {
110110
assertThat(loadAverage[2], equalTo((double) -1));
111111
}
112112
}
113+
assertThat(stats.getCpu().getAvailableProcessors(), greaterThanOrEqualTo(1));
113114

114115
assertNotNull(stats.getMem());
115116
assertThat(stats.getMem().getTotal().getBytes(), greaterThan(0L));

server/src/test/java/org/elasticsearch/monitor/os/OsStatsTests.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public void testSerialization() throws IOException {
2626
for (int i = 0; i < loadAverages.length; i++) {
2727
loadAverages[i] = randomDouble();
2828
}
29-
OsStats.Cpu cpu = new OsStats.Cpu(randomShort(), loadAverages);
29+
OsStats.Cpu cpu = new OsStats.Cpu(randomShort(), loadAverages, randomInt());
3030
long memTotal = randomNonNegativeLong();
3131
OsStats.Mem mem = new OsStats.Mem(memTotal, randomLongBetween(0, memTotal), randomLongBetween(0, memTotal));
3232
long swapTotal = randomNonNegativeLong();
@@ -55,6 +55,7 @@ public void testSerialization() throws IOException {
5555
assertEquals(osStats.getTimestamp(), deserializedOsStats.getTimestamp());
5656
assertEquals(osStats.getCpu().getPercent(), deserializedOsStats.getCpu().getPercent());
5757
assertArrayEquals(osStats.getCpu().getLoadAverage(), deserializedOsStats.getCpu().getLoadAverage(), 0);
58+
assertEquals(osStats.getCpu().getAvailableProcessors(), deserializedOsStats.getCpu().getAvailableProcessors());
5859
assertEquals(osStats.getMem().getFree(), deserializedOsStats.getMem().getFree());
5960
assertEquals(osStats.getMem().getTotal(), deserializedOsStats.getMem().getTotal());
6061
assertEquals(osStats.getSwap().getFree(), deserializedOsStats.getSwap().getFree());

0 commit comments

Comments
 (0)