org.elasticsearch.action.admin.cluster.stats.ClusterStatsNodes Maven / Gradle / Ivy
The newest version!
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.action.admin.cluster.stats;
import com.carrotsearch.hppc.ObjectIntHashMap;
import com.carrotsearch.hppc.cursors.ObjectIntCursor;
import org.elasticsearch.Version;
import org.elasticsearch.action.admin.cluster.node.info.NodeInfo;
import org.elasticsearch.plugins.PluginInfo;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.cluster.node.DiscoveryNode;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Streamable;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentBuilderString;
import org.elasticsearch.monitor.fs.FsInfo;
import org.elasticsearch.monitor.jvm.JvmInfo;
import java.io.IOException;
import java.net.InetAddress;
import java.util.HashSet;
import java.util.Set;
public class ClusterStatsNodes implements ToXContent, Streamable {
private Counts counts;
private Set versions;
private OsStats os;
private ProcessStats process;
private JvmStats jvm;
private FsInfo.Path fs;
private Set plugins;
private ClusterStatsNodes() {
}
public ClusterStatsNodes(ClusterStatsNodeResponse[] nodeResponses) {
this.counts = new Counts();
this.versions = new HashSet<>();
this.os = new OsStats();
this.jvm = new JvmStats();
this.fs = new FsInfo.Path();
this.plugins = new HashSet<>();
this.process = new ProcessStats();
Set seenAddresses = new HashSet<>(nodeResponses.length);
for (ClusterStatsNodeResponse nodeResponse : nodeResponses) {
counts.addNodeInfo(nodeResponse.nodeInfo());
versions.add(nodeResponse.nodeInfo().getVersion());
process.addNodeStats(nodeResponse.nodeStats());
jvm.addNodeInfoStats(nodeResponse.nodeInfo(), nodeResponse.nodeStats());
plugins.addAll(nodeResponse.nodeInfo().getPlugins().getPluginInfos());
// now do the stats that should be deduped by hardware (implemented by ip deduping)
TransportAddress publishAddress = nodeResponse.nodeInfo().getTransport().address().publishAddress();
InetAddress inetAddress = null;
if (publishAddress.uniqueAddressTypeId() == 1) {
inetAddress = ((InetSocketTransportAddress) publishAddress).address().getAddress();
}
if (!seenAddresses.add(inetAddress)) {
continue;
}
os.addNodeInfoStats(nodeResponse.nodeInfo(), nodeResponse.nodeStats());
if (nodeResponse.nodeStats().getFs() != null) {
fs.add(nodeResponse.nodeStats().getFs().total());
}
}
}
public Counts getCounts() {
return this.counts;
}
public Set getVersions() {
return versions;
}
public OsStats getOs() {
return os;
}
public ProcessStats getProcess() {
return process;
}
public JvmStats getJvm() {
return jvm;
}
public FsInfo.Path getFs() {
return fs;
}
public Set getPlugins() {
return plugins;
}
@Override
public void readFrom(StreamInput in) throws IOException {
counts = Counts.readCounts(in);
int size = in.readVInt();
versions = new HashSet<>(size);
for (; size > 0; size--) {
versions.add(Version.readVersion(in));
}
os = OsStats.readOsStats(in);
process = ProcessStats.readStats(in);
jvm = JvmStats.readJvmStats(in);
fs = FsInfo.Path.readInfoFrom(in);
size = in.readVInt();
plugins = new HashSet<>(size);
for (; size > 0; size--) {
plugins.add(PluginInfo.readFromStream(in));
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
counts.writeTo(out);
out.writeVInt(versions.size());
for (Version v : versions) Version.writeVersion(v, out);
os.writeTo(out);
process.writeTo(out);
jvm.writeTo(out);
fs.writeTo(out);
out.writeVInt(plugins.size());
for (PluginInfo p : plugins) {
p.writeTo(out);
}
}
public static ClusterStatsNodes readNodeStats(StreamInput in) throws IOException {
ClusterStatsNodes nodeStats = new ClusterStatsNodes();
nodeStats.readFrom(in);
return nodeStats;
}
static final class Fields {
static final XContentBuilderString COUNT = new XContentBuilderString("count");
static final XContentBuilderString VERSIONS = new XContentBuilderString("versions");
static final XContentBuilderString OS = new XContentBuilderString("os");
static final XContentBuilderString PROCESS = new XContentBuilderString("process");
static final XContentBuilderString JVM = new XContentBuilderString("jvm");
static final XContentBuilderString FS = new XContentBuilderString("fs");
static final XContentBuilderString PLUGINS = new XContentBuilderString("plugins");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(Fields.COUNT);
counts.toXContent(builder, params);
builder.endObject();
builder.startArray(Fields.VERSIONS);
for (Version v : versions) {
builder.value(v.toString());
}
builder.endArray();
builder.startObject(Fields.OS);
os.toXContent(builder, params);
builder.endObject();
builder.startObject(Fields.PROCESS);
process.toXContent(builder, params);
builder.endObject();
builder.startObject(Fields.JVM);
jvm.toXContent(builder, params);
builder.endObject();
builder.field(Fields.FS);
fs.toXContent(builder, params);
builder.startArray(Fields.PLUGINS);
for (PluginInfo pluginInfo : plugins) {
pluginInfo.toXContent(builder, params);
}
builder.endArray();
return builder;
}
public static class Counts implements Streamable, ToXContent {
int total;
int masterOnly;
int dataOnly;
int masterData;
int client;
public void addNodeInfo(NodeInfo nodeInfo) {
total++;
DiscoveryNode node = nodeInfo.getNode();
if (node.masterNode()) {
if (node.dataNode()) {
masterData++;
} else {
masterOnly++;
}
} else if (node.dataNode()) {
dataOnly++;
} else if (node.clientNode()) {
client++;
}
}
public int getTotal() {
return total;
}
public int getMasterOnly() {
return masterOnly;
}
public int getDataOnly() {
return dataOnly;
}
public int getMasterData() {
return masterData;
}
public int getClient() {
return client;
}
public static Counts readCounts(StreamInput in) throws IOException {
Counts c = new Counts();
c.readFrom(in);
return c;
}
@Override
public void readFrom(StreamInput in) throws IOException {
total = in.readVInt();
masterOnly = in.readVInt();
dataOnly = in.readVInt();
masterData = in.readVInt();
client = in.readVInt();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(total);
out.writeVInt(masterOnly);
out.writeVInt(dataOnly);
out.writeVInt(masterData);
out.writeVInt(client);
}
static final class Fields {
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString MASTER_ONLY = new XContentBuilderString("master_only");
static final XContentBuilderString DATA_ONLY = new XContentBuilderString("data_only");
static final XContentBuilderString MASTER_DATA = new XContentBuilderString("master_data");
static final XContentBuilderString CLIENT = new XContentBuilderString("client");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field(Fields.TOTAL, total);
builder.field(Fields.MASTER_ONLY, masterOnly);
builder.field(Fields.DATA_ONLY, dataOnly);
builder.field(Fields.MASTER_DATA, masterData);
builder.field(Fields.CLIENT, client);
return builder;
}
}
public static class OsStats implements ToXContent, Streamable {
int availableProcessors;
int allocatedProcessors;
long availableMemory;
final ObjectIntHashMap names;
public OsStats() {
names = new ObjectIntHashMap<>();
}
public void addNodeInfoStats(NodeInfo nodeInfo, NodeStats nodeStats) {
availableProcessors += nodeInfo.getOs().getAvailableProcessors();
allocatedProcessors += nodeInfo.getOs().getAllocatedProcessors();
if (nodeInfo.getOs().getName() != null) {
names.addTo(nodeInfo.getOs().getName(), 1);
}
if (nodeStats.getOs() != null && nodeStats.getOs().getMem() != null) {
availableMemory += nodeStats.getOs().getMem().getFree().bytes();
}
}
public int getAvailableProcessors() {
return availableProcessors;
}
public int getAllocatedProcessors() {
return allocatedProcessors;
}
public ByteSizeValue getAvailableMemory() {
return new ByteSizeValue(availableMemory);
}
@Override
public void readFrom(StreamInput in) throws IOException {
availableProcessors = in.readVInt();
if (in.getVersion().onOrAfter(Version.V_2_1_0)) {
allocatedProcessors = in.readVInt();
}
availableMemory = in.readLong();
int size = in.readVInt();
names.clear();
for (int i = 0; i < size; i++) {
names.addTo(in.readString(), in.readVInt());
}
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(availableProcessors);
if (out.getVersion().onOrAfter(Version.V_2_1_0)) {
out.writeVInt(allocatedProcessors);
}
out.writeLong(availableMemory);
out.writeVInt(names.size());
for (ObjectIntCursor name : names) {
out.writeString(name.key);
out.writeVInt(name.value);
}
}
public static OsStats readOsStats(StreamInput in) throws IOException {
OsStats os = new OsStats();
os.readFrom(in);
return os;
}
static final class Fields {
static final XContentBuilderString AVAILABLE_PROCESSORS = new XContentBuilderString("available_processors");
static final XContentBuilderString ALLOCATED_PROCESSORS = new XContentBuilderString("allocated_processors");
static final XContentBuilderString NAME = new XContentBuilderString("name");
static final XContentBuilderString NAMES = new XContentBuilderString("names");
static final XContentBuilderString MEM = new XContentBuilderString("mem");
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
static final XContentBuilderString TOTAL_IN_BYTES = new XContentBuilderString("total_in_bytes");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.field(Fields.AVAILABLE_PROCESSORS, availableProcessors);
builder.field(Fields.ALLOCATED_PROCESSORS, allocatedProcessors);
builder.startObject(Fields.MEM);
builder.byteSizeField(Fields.TOTAL_IN_BYTES, Fields.TOTAL, availableMemory);
builder.endObject();
builder.startArray(Fields.NAMES);
for (ObjectIntCursor name : names) {
builder.startObject();
builder.field(Fields.NAME, name.key);
builder.field(Fields.COUNT, name.value);
builder.endObject();
}
builder.endArray();
return builder;
}
}
public static class ProcessStats implements ToXContent, Streamable {
int count;
int cpuPercent;
long totalOpenFileDescriptors;
long minOpenFileDescriptors = Long.MAX_VALUE;
long maxOpenFileDescriptors = Long.MIN_VALUE;
public void addNodeStats(NodeStats nodeStats) {
if (nodeStats.getProcess() == null) {
return;
}
count++;
if (nodeStats.getProcess().getCpu() != null) {
cpuPercent += nodeStats.getProcess().getCpu().getPercent();
}
long fd = nodeStats.getProcess().getOpenFileDescriptors();
if (fd > 0) {
// fd can be -1 if not supported on platform
totalOpenFileDescriptors += fd;
}
// we still do min max calc on -1, so we'll have an indication of it not being supported on one of the nodes.
minOpenFileDescriptors = Math.min(minOpenFileDescriptors, fd);
maxOpenFileDescriptors = Math.max(maxOpenFileDescriptors, fd);
}
/**
* Cpu usage in percentages - 100 is 1 core.
*/
public int getCpuPercent() {
return cpuPercent;
}
public long getAvgOpenFileDescriptors() {
if (count == 0) {
return -1;
}
return totalOpenFileDescriptors / count;
}
public long getMaxOpenFileDescriptors() {
if (count == 0) {
return -1;
}
return maxOpenFileDescriptors;
}
public long getMinOpenFileDescriptors() {
if (count == 0) {
return -1;
}
return minOpenFileDescriptors;
}
@Override
public void readFrom(StreamInput in) throws IOException {
count = in.readVInt();
cpuPercent = in.readVInt();
totalOpenFileDescriptors = in.readVLong();
minOpenFileDescriptors = in.readLong();
maxOpenFileDescriptors = in.readLong();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(count);
out.writeVInt(cpuPercent);
out.writeVLong(totalOpenFileDescriptors);
out.writeLong(minOpenFileDescriptors);
out.writeLong(maxOpenFileDescriptors);
}
public static ProcessStats readStats(StreamInput in) throws IOException {
ProcessStats cpu = new ProcessStats();
cpu.readFrom(in);
return cpu;
}
static final class Fields {
static final XContentBuilderString CPU = new XContentBuilderString("cpu");
static final XContentBuilderString PERCENT = new XContentBuilderString("percent");
static final XContentBuilderString OPEN_FILE_DESCRIPTORS = new XContentBuilderString("open_file_descriptors");
static final XContentBuilderString MIN = new XContentBuilderString("min");
static final XContentBuilderString MAX = new XContentBuilderString("max");
static final XContentBuilderString AVG = new XContentBuilderString("avg");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(Fields.CPU).field(Fields.PERCENT, cpuPercent).endObject();
if (count > 0) {
builder.startObject(Fields.OPEN_FILE_DESCRIPTORS);
builder.field(Fields.MIN, getMinOpenFileDescriptors());
builder.field(Fields.MAX, getMaxOpenFileDescriptors());
builder.field(Fields.AVG, getAvgOpenFileDescriptors());
builder.endObject();
}
return builder;
}
}
public static class JvmStats implements Streamable, ToXContent {
ObjectIntHashMap versions;
long threads;
long maxUptime;
long heapUsed;
long heapMax;
JvmStats() {
versions = new ObjectIntHashMap<>();
threads = 0;
maxUptime = 0;
heapMax = 0;
heapUsed = 0;
}
public ObjectIntHashMap getVersions() {
return versions;
}
/**
* The total number of threads in the cluster
*/
public long getThreads() {
return threads;
}
/**
* The maximum uptime of a node in the cluster
*/
public TimeValue getMaxUpTime() {
return new TimeValue(maxUptime);
}
/**
* Total heap used in the cluster
*/
public ByteSizeValue getHeapUsed() {
return new ByteSizeValue(heapUsed);
}
/**
* Maximum total heap available to the cluster
*/
public ByteSizeValue getHeapMax() {
return new ByteSizeValue(heapMax);
}
public void addNodeInfoStats(NodeInfo nodeInfo, NodeStats nodeStats) {
versions.addTo(new JvmVersion(nodeInfo.getJvm()), 1);
org.elasticsearch.monitor.jvm.JvmStats js = nodeStats.getJvm();
if (js == null) {
return;
}
if (js.getThreads() != null) {
threads += js.getThreads().getCount();
}
maxUptime = Math.max(maxUptime, js.getUptime().millis());
if (js.getMem() != null) {
heapUsed += js.getMem().getHeapUsed().bytes();
heapMax += js.getMem().getHeapMax().bytes();
}
}
@Override
public void readFrom(StreamInput in) throws IOException {
int size = in.readVInt();
versions = new ObjectIntHashMap<>(size);
for (; size > 0; size--) {
versions.addTo(JvmVersion.readJvmVersion(in), in.readVInt());
}
threads = in.readVLong();
maxUptime = in.readVLong();
heapUsed = in.readVLong();
heapMax = in.readVLong();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVInt(versions.size());
for (ObjectIntCursor v : versions) {
v.key.writeTo(out);
out.writeVInt(v.value);
}
out.writeVLong(threads);
out.writeVLong(maxUptime);
out.writeVLong(heapUsed);
out.writeVLong(heapMax);
}
public static JvmStats readJvmStats(StreamInput in) throws IOException {
JvmStats jvmStats = new JvmStats();
jvmStats.readFrom(in);
return jvmStats;
}
static final class Fields {
static final XContentBuilderString VERSIONS = new XContentBuilderString("versions");
static final XContentBuilderString VERSION = new XContentBuilderString("version");
static final XContentBuilderString VM_NAME = new XContentBuilderString("vm_name");
static final XContentBuilderString VM_VERSION = new XContentBuilderString("vm_version");
static final XContentBuilderString VM_VENDOR = new XContentBuilderString("vm_vendor");
static final XContentBuilderString COUNT = new XContentBuilderString("count");
static final XContentBuilderString THREADS = new XContentBuilderString("threads");
static final XContentBuilderString MAX_UPTIME = new XContentBuilderString("max_uptime");
static final XContentBuilderString MAX_UPTIME_IN_MILLIS = new XContentBuilderString("max_uptime_in_millis");
static final XContentBuilderString MEM = new XContentBuilderString("mem");
static final XContentBuilderString HEAP_USED = new XContentBuilderString("heap_used");
static final XContentBuilderString HEAP_USED_IN_BYTES = new XContentBuilderString("heap_used_in_bytes");
static final XContentBuilderString HEAP_MAX = new XContentBuilderString("heap_max");
static final XContentBuilderString HEAP_MAX_IN_BYTES = new XContentBuilderString("heap_max_in_bytes");
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.timeValueField(Fields.MAX_UPTIME_IN_MILLIS, Fields.MAX_UPTIME, maxUptime);
builder.startArray(Fields.VERSIONS);
for (ObjectIntCursor v : versions) {
builder.startObject();
builder.field(Fields.VERSION, v.key.version);
builder.field(Fields.VM_NAME, v.key.vmName);
builder.field(Fields.VM_VERSION, v.key.vmVersion);
builder.field(Fields.VM_VENDOR, v.key.vmVendor);
builder.field(Fields.COUNT, v.value);
builder.endObject();
}
builder.endArray();
builder.startObject(Fields.MEM);
builder.byteSizeField(Fields.HEAP_USED_IN_BYTES, Fields.HEAP_USED, heapUsed);
builder.byteSizeField(Fields.HEAP_MAX_IN_BYTES, Fields.HEAP_MAX, heapMax);
builder.endObject();
builder.field(Fields.THREADS, threads);
return builder;
}
}
public static class JvmVersion implements Streamable {
String version;
String vmName;
String vmVersion;
String vmVendor;
JvmVersion(JvmInfo jvmInfo) {
version = jvmInfo.version();
vmName = jvmInfo.getVmName();
vmVersion = jvmInfo.getVmVersion();
vmVendor = jvmInfo.getVmVendor();
}
JvmVersion() {
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
JvmVersion jvm = (JvmVersion) o;
return vmVersion.equals(jvm.vmVersion) && vmVendor.equals(jvm.vmVendor);
}
@Override
public int hashCode() {
return vmVersion.hashCode();
}
public static JvmVersion readJvmVersion(StreamInput in) throws IOException {
JvmVersion jvm = new JvmVersion();
jvm.readFrom(in);
return jvm;
}
@Override
public void readFrom(StreamInput in) throws IOException {
version = in.readString();
vmName = in.readString();
vmVersion = in.readString();
vmVendor = in.readString();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeString(version);
out.writeString(vmName);
out.writeString(vmVersion);
out.writeString(vmVendor);
}
}
}