JvmInfo to implement Writeable rather than Streamable

This commit is contained in:
javanna 2016-09-01 17:14:08 +02:00 committed by Luca Cavanna
parent bea863c660
commit 279f8b27e3
3 changed files with 215 additions and 156 deletions

View File

@ -208,7 +208,7 @@ public class NodeInfo extends BaseNodeResponse {
process = ProcessInfo.readProcessInfo(in);
}
if (in.readBoolean()) {
jvm = JvmInfo.readJvmInfo(in);
jvm = new JvmInfo(in);
}
if (in.readBoolean()) {
threadPool = ThreadPoolInfo.readThreadPoolInfo(in);

View File

@ -19,10 +19,9 @@
package org.elasticsearch.monitor.jvm;
import org.elasticsearch.common.Strings;
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.io.stream.Writeable;
import org.elasticsearch.common.unit.ByteSizeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
@ -41,10 +40,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
*/
public class JvmInfo implements Streamable, ToXContent {
public class JvmInfo implements Writeable, ToXContent {
private static JvmInfo INSTANCE;
@ -61,100 +57,106 @@ public class JvmInfo implements Streamable, ToXContent {
} catch (Exception e) {
pid = -1;
}
JvmInfo info = new JvmInfo();
info.pid = pid;
info.startTime = runtimeMXBean.getStartTime();
info.version = System.getProperty("java.version");
info.vmName = runtimeMXBean.getVmName();
info.vmVendor = runtimeMXBean.getVmVendor();
info.vmVersion = runtimeMXBean.getVmVersion();
info.mem = new Mem();
info.mem.heapInit = memoryMXBean.getHeapMemoryUsage().getInit() < 0 ? 0 : memoryMXBean.getHeapMemoryUsage().getInit();
info.mem.heapMax = memoryMXBean.getHeapMemoryUsage().getMax() < 0 ? 0 : memoryMXBean.getHeapMemoryUsage().getMax();
info.mem.nonHeapInit = memoryMXBean.getNonHeapMemoryUsage().getInit() < 0 ? 0 : memoryMXBean.getNonHeapMemoryUsage().getInit();
info.mem.nonHeapMax = memoryMXBean.getNonHeapMemoryUsage().getMax() < 0 ? 0 : memoryMXBean.getNonHeapMemoryUsage().getMax();
long heapInit = memoryMXBean.getHeapMemoryUsage().getInit() < 0 ? 0 : memoryMXBean.getHeapMemoryUsage().getInit();
long heapMax = memoryMXBean.getHeapMemoryUsage().getMax() < 0 ? 0 : memoryMXBean.getHeapMemoryUsage().getMax();
long nonHeapInit = memoryMXBean.getNonHeapMemoryUsage().getInit() < 0 ? 0 : memoryMXBean.getNonHeapMemoryUsage().getInit();
long nonHeapMax = memoryMXBean.getNonHeapMemoryUsage().getMax() < 0 ? 0 : memoryMXBean.getNonHeapMemoryUsage().getMax();
long directMemoryMax = 0;
try {
Class<?> vmClass = Class.forName("sun.misc.VM");
info.mem.directMemoryMax = (Long) vmClass.getMethod("maxDirectMemory").invoke(null);
directMemoryMax = (Long) vmClass.getMethod("maxDirectMemory").invoke(null);
} catch (Exception t) {
// ignore
}
info.inputArguments = runtimeMXBean.getInputArguments().toArray(new String[runtimeMXBean.getInputArguments().size()]);
String[] inputArguments = runtimeMXBean.getInputArguments().toArray(new String[runtimeMXBean.getInputArguments().size()]);
Mem mem = new Mem(heapInit, heapMax, nonHeapInit, nonHeapMax, directMemoryMax);
String bootClassPath;
try {
info.bootClassPath = runtimeMXBean.getBootClassPath();
bootClassPath = runtimeMXBean.getBootClassPath();
} catch (UnsupportedOperationException e) {
// oracle java 9
info.bootClassPath = System.getProperty("sun.boot.class.path");
if (info.bootClassPath == null) {
bootClassPath = System.getProperty("sun.boot.class.path");
if (bootClassPath == null) {
// something else
info.bootClassPath = "<unknown>";
bootClassPath = "<unknown>";
}
}
info.classPath = runtimeMXBean.getClassPath();
info.systemProperties = Collections.unmodifiableMap(runtimeMXBean.getSystemProperties());
String classPath = runtimeMXBean.getClassPath();
Map<String, String> systemProperties = Collections.unmodifiableMap(runtimeMXBean.getSystemProperties());
List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
info.gcCollectors = new String[gcMxBeans.size()];
String[] gcCollectors = new String[gcMxBeans.size()];
for (int i = 0; i < gcMxBeans.size(); i++) {
GarbageCollectorMXBean gcMxBean = gcMxBeans.get(i);
info.gcCollectors[i] = gcMxBean.getName();
gcCollectors[i] = gcMxBean.getName();
}
List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
info.memoryPools = new String[memoryPoolMXBeans.size()];
String[] memoryPools = new String[memoryPoolMXBeans.size()];
for (int i = 0; i < memoryPoolMXBeans.size(); i++) {
MemoryPoolMXBean memoryPoolMXBean = memoryPoolMXBeans.get(i);
info.memoryPools[i] = memoryPoolMXBean.getName();
memoryPools[i] = memoryPoolMXBean.getName();
}
String onError = null;
String onOutOfMemoryError = null;
String useCompressedOops = "unknown";
String useG1GC = "unknown";
long configuredInitialHeapSize = -1;
long configuredMaxHeapSize = -1;
try {
@SuppressWarnings("unchecked") Class<? extends PlatformManagedObject> clazz =
(Class<? extends PlatformManagedObject>)Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
(Class<? extends PlatformManagedObject>)Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
Class<?> vmOptionClazz = Class.forName("com.sun.management.VMOption");
PlatformManagedObject hotSpotDiagnosticMXBean = ManagementFactory.getPlatformMXBean(clazz);
Method vmOptionMethod = clazz.getMethod("getVMOption", String.class);
Method valueMethod = vmOptionClazz.getMethod("getValue");
try {
Object onError = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "OnError");
info.onError = (String) valueMethod.invoke(onError);
Object onErrorObject = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "OnError");
onError = (String) valueMethod.invoke(onErrorObject);
} catch (Exception ignored) {
}
try {
Object onOutOfMemoryError = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "OnOutOfMemoryError");
info.onOutOfMemoryError = (String) valueMethod.invoke(onOutOfMemoryError);
Object onOutOfMemoryErrorObject = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "OnOutOfMemoryError");
onOutOfMemoryError = (String) valueMethod.invoke(onOutOfMemoryErrorObject);
} catch (Exception ignored) {
}
try {
Object useCompressedOopsVmOption = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "UseCompressedOops");
info.useCompressedOops = (String) valueMethod.invoke(useCompressedOopsVmOption);
Object useCompressedOopsVmOptionObject = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "UseCompressedOops");
useCompressedOops = (String) valueMethod.invoke(useCompressedOopsVmOptionObject);
} catch (Exception ignored) {
}
try {
Object useG1GCVmOption = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "UseG1GC");
info.useG1GC = (String) valueMethod.invoke(useG1GCVmOption);
Object useG1GCVmOptionObject = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "UseG1GC");
useG1GC = (String) valueMethod.invoke(useG1GCVmOptionObject);
} catch (Exception ignored) {
}
try {
Object initialHeapSizeVmOption = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "InitialHeapSize");
info.configuredInitialHeapSize = Long.parseLong((String) valueMethod.invoke(initialHeapSizeVmOption));
Object initialHeapSizeVmOptionObject = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "InitialHeapSize");
configuredInitialHeapSize = Long.parseLong((String) valueMethod.invoke(initialHeapSizeVmOptionObject));
} catch (Exception ignored) {
}
try {
Object maxHeapSizeVmOption = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "MaxHeapSize");
info.configuredMaxHeapSize = Long.parseLong((String) valueMethod.invoke(maxHeapSizeVmOption));
Object maxHeapSizeVmOptionObject = vmOptionMethod.invoke(hotSpotDiagnosticMXBean, "MaxHeapSize");
configuredMaxHeapSize = Long.parseLong((String) valueMethod.invoke(maxHeapSizeVmOptionObject));
} catch (Exception ignored) {
}
} catch (Exception ignored) {
}
INSTANCE = info;
INSTANCE = new JvmInfo(pid, System.getProperty("java.version"), runtimeMXBean.getVmName(), runtimeMXBean.getVmVersion(),
runtimeMXBean.getVmVendor(), runtimeMXBean.getStartTime(), configuredInitialHeapSize, configuredMaxHeapSize,
mem, inputArguments, bootClassPath, classPath, systemProperties, gcCollectors, memoryPools, onError, onOutOfMemoryError,
useCompressedOops, useG1GC);
}
public static JvmInfo jvmInfo() {
@ -166,40 +168,104 @@ public class JvmInfo implements Streamable, ToXContent {
return INSTANCE;
}
long pid = -1;
private final long pid;
private final String version;
private final String vmName;
private final String vmVersion;
private final String vmVendor;
private final long startTime;
private final long configuredInitialHeapSize;
private final long configuredMaxHeapSize;
private final Mem mem;
private final String[] inputArguments;
private final String bootClassPath;
private final String classPath;
private final Map<String, String> systemProperties;
private final String[] gcCollectors;
private final String[] memoryPools;
private final String onError;
private final String onOutOfMemoryError;
private final String useCompressedOops;
private final String useG1GC;
String version = "";
String vmName = "";
String vmVersion = "";
String vmVendor = "";
private JvmInfo(long pid, String version, String vmName, String vmVersion, String vmVendor, long startTime,
long configuredInitialHeapSize, long configuredMaxHeapSize, Mem mem, String[] inputArguments, String bootClassPath,
String classPath, Map<String, String> systemProperties, String[] gcCollectors, String[] memoryPools, String onError,
String onOutOfMemoryError, String useCompressedOops, String useG1GC) {
this.pid = pid;
this.version = version;
this.vmName = vmName;
this.vmVersion = vmVersion;
this.vmVendor = vmVendor;
this.startTime = startTime;
this.configuredInitialHeapSize = configuredInitialHeapSize;
this.configuredMaxHeapSize = configuredMaxHeapSize;
this.mem = mem;
this.inputArguments = inputArguments;
this.bootClassPath = bootClassPath;
this.classPath = classPath;
this.systemProperties = systemProperties;
this.gcCollectors = gcCollectors;
this.memoryPools = memoryPools;
this.onError = onError;
this.onOutOfMemoryError = onOutOfMemoryError;
this.useCompressedOops = useCompressedOops;
this.useG1GC = useG1GC;
}
long startTime = -1;
public JvmInfo(StreamInput in) throws IOException {
pid = in.readLong();
version = in.readString();
vmName = in.readString();
vmVersion = in.readString();
vmVendor = in.readString();
startTime = in.readLong();
inputArguments = new String[in.readInt()];
for (int i = 0; i < inputArguments.length; i++) {
inputArguments[i] = in.readString();
}
bootClassPath = in.readString();
classPath = in.readString();
systemProperties = new HashMap<>();
int size = in.readInt();
for (int i = 0; i < size; i++) {
systemProperties.put(in.readString(), in.readString());
}
mem = new Mem(in);
gcCollectors = in.readStringArray();
memoryPools = in.readStringArray();
useCompressedOops = in.readString();
//the following members are only used locally for boostrap checks, never serialized nor printed out
this.configuredMaxHeapSize = -1;
this.configuredInitialHeapSize = -1;
this.onError = null;
this.onOutOfMemoryError = null;
this.useG1GC = "unknown";
}
private long configuredInitialHeapSize;
private long configuredMaxHeapSize;
Mem mem;
String[] inputArguments;
String bootClassPath;
String classPath;
Map<String, String> systemProperties;
String[] gcCollectors = Strings.EMPTY_ARRAY;
String[] memoryPools = Strings.EMPTY_ARRAY;
private String onError;
private String onOutOfMemoryError;
private String useCompressedOops = "unknown";
private String useG1GC = "unknown";
private JvmInfo() {
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeLong(pid);
out.writeString(version);
out.writeString(vmName);
out.writeString(vmVersion);
out.writeString(vmVendor);
out.writeLong(startTime);
out.writeInt(inputArguments.length);
for (String inputArgument : inputArguments) {
out.writeString(inputArgument);
}
out.writeString(bootClassPath);
out.writeString(classPath);
out.writeInt(systemProperties.size());
for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
out.writeString(entry.getKey());
out.writeString(entry.getValue());
}
mem.writeTo(out);
out.writeStringArray(gcCollectors);
out.writeStringArray(memoryPools);
out.writeString(useCompressedOops);
}
/**
@ -354,6 +420,14 @@ public class JvmInfo implements Streamable, ToXContent {
return this.useG1GC;
}
public String[] getGcCollectors() {
return gcCollectors;
}
public String[] getMemoryPools() {
return memoryPools;
}
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(Fields.JVM);
@ -407,72 +481,37 @@ public class JvmInfo implements Streamable, ToXContent {
static final String USING_COMPRESSED_OOPS = "using_compressed_ordinary_object_pointers";
}
public static JvmInfo readJvmInfo(StreamInput in) throws IOException {
JvmInfo jvmInfo = new JvmInfo();
jvmInfo.readFrom(in);
return jvmInfo;
}
public static class Mem implements Writeable {
@Override
public void readFrom(StreamInput in) throws IOException {
pid = in.readLong();
version = in.readString();
vmName = in.readString();
vmVersion = in.readString();
vmVendor = in.readString();
startTime = in.readLong();
inputArguments = new String[in.readInt()];
for (int i = 0; i < inputArguments.length; i++) {
inputArguments[i] = in.readString();
private final long heapInit;
private final long heapMax;
private final long nonHeapInit;
private final long nonHeapMax;
private final long directMemoryMax;
public Mem(long heapInit, long heapMax, long nonHeapInit, long nonHeapMax, long directMemoryMax) {
this.heapInit = heapInit;
this.heapMax = heapMax;
this.nonHeapInit = nonHeapInit;
this.nonHeapMax = nonHeapMax;
this.directMemoryMax = directMemoryMax;
}
bootClassPath = in.readString();
classPath = in.readString();
systemProperties = new HashMap<>();
int size = in.readInt();
for (int i = 0; i < size; i++) {
systemProperties.put(in.readString(), in.readString());
public Mem(StreamInput in) throws IOException {
this.heapInit = in.readVLong();
this.heapMax = in.readVLong();
this.nonHeapInit = in.readVLong();
this.nonHeapMax = in.readVLong();
this.directMemoryMax = in.readVLong();
}
mem = new Mem();
mem.readFrom(in);
gcCollectors = in.readStringArray();
memoryPools = in.readStringArray();
useCompressedOops = in.readString();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeLong(pid);
out.writeString(version);
out.writeString(vmName);
out.writeString(vmVersion);
out.writeString(vmVendor);
out.writeLong(startTime);
out.writeInt(inputArguments.length);
for (String inputArgument : inputArguments) {
out.writeString(inputArgument);
}
out.writeString(bootClassPath);
out.writeString(classPath);
out.writeInt(systemProperties.size());
for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
out.writeString(entry.getKey());
out.writeString(entry.getValue());
}
mem.writeTo(out);
out.writeStringArray(gcCollectors);
out.writeStringArray(memoryPools);
out.writeString(useCompressedOops);
}
public static class Mem implements Streamable {
long heapInit = 0;
long heapMax = 0;
long nonHeapInit = 0;
long nonHeapMax = 0;
long directMemoryMax = 0;
Mem() {
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVLong(heapInit);
out.writeVLong(heapMax);
out.writeVLong(nonHeapInit);
out.writeVLong(nonHeapMax);
out.writeVLong(directMemoryMax);
}
public ByteSizeValue getHeapInit() {
@ -494,23 +533,5 @@ public class JvmInfo implements Streamable, ToXContent {
public ByteSizeValue getDirectMemoryMax() {
return new ByteSizeValue(directMemoryMax);
}
@Override
public void readFrom(StreamInput in) throws IOException {
heapInit = in.readVLong();
heapMax = in.readVLong();
nonHeapInit = in.readVLong();
nonHeapMax = in.readVLong();
directMemoryMax = in.readVLong();
}
@Override
public void writeTo(StreamOutput out) throws IOException {
out.writeVLong(heapInit);
out.writeVLong(heapMax);
out.writeVLong(nonHeapInit);
out.writeVLong(nonHeapMax);
out.writeVLong(directMemoryMax);
}
}
}

View File

@ -21,8 +21,12 @@ package org.elasticsearch.monitor.jvm;
import org.apache.lucene.util.Constants;
import org.elasticsearch.bootstrap.JavaVersion;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.test.ESTestCase;
import java.io.IOException;
public class JvmInfoTests extends ESTestCase {
public void testUseG1GC() {
@ -58,4 +62,38 @@ public class JvmInfoTests extends ESTestCase {
return argline.charAt(index - 1) == '+';
}
public void testSerialization() throws IOException {
JvmInfo jvmInfo = JvmInfo.jvmInfo();
try (BytesStreamOutput out = new BytesStreamOutput()) {
jvmInfo.writeTo(out);
try (StreamInput in = out.bytes().streamInput()) {
JvmInfo deserializedJvmInfo = new JvmInfo(in);
assertEquals(jvmInfo.getVersion(), deserializedJvmInfo.getVersion());
assertEquals(jvmInfo.getVmName(), deserializedJvmInfo.getVmName());
assertEquals(jvmInfo.getVmVendor(), deserializedJvmInfo.getVmVendor());
assertEquals(jvmInfo.getVmVersion(), deserializedJvmInfo.getVmVersion());
assertEquals(jvmInfo.getBootClassPath(), deserializedJvmInfo.getBootClassPath());
assertEquals(jvmInfo.getClassPath(), deserializedJvmInfo.getClassPath());
assertEquals(jvmInfo.getPid(), deserializedJvmInfo.getPid());
assertEquals(jvmInfo.getStartTime(), deserializedJvmInfo.getStartTime());
assertEquals(jvmInfo.versionUpdatePack(), deserializedJvmInfo.versionUpdatePack());
assertEquals(jvmInfo.versionAsInteger(), deserializedJvmInfo.versionAsInteger());
assertEquals(jvmInfo.getMem().getDirectMemoryMax(), deserializedJvmInfo.getMem().getDirectMemoryMax());
assertEquals(jvmInfo.getMem().getHeapInit(), deserializedJvmInfo.getMem().getHeapInit());
assertEquals(jvmInfo.getMem().getHeapMax(), deserializedJvmInfo.getMem().getHeapMax());
assertEquals(jvmInfo.getMem().getNonHeapInit(), deserializedJvmInfo.getMem().getNonHeapInit());
assertEquals(jvmInfo.getMem().getNonHeapMax(), deserializedJvmInfo.getMem().getNonHeapMax());
assertEquals(jvmInfo.getSystemProperties(), deserializedJvmInfo.getSystemProperties());
assertArrayEquals(jvmInfo.getInputArguments(), deserializedJvmInfo.getInputArguments());
assertArrayEquals(jvmInfo.getGcCollectors(), deserializedJvmInfo.getGcCollectors());
assertArrayEquals(jvmInfo.getMemoryPools(), deserializedJvmInfo.getMemoryPools());
assertEquals(jvmInfo.useCompressedOops(), deserializedJvmInfo.useCompressedOops());
assertEquals(-1, deserializedJvmInfo.getConfiguredInitialHeapSize());
assertEquals(-1, deserializedJvmInfo.getConfiguredMaxHeapSize());
assertEquals("unknown", deserializedJvmInfo.useG1GC());
assertNull(deserializedJvmInfo.onError());
assertNull(deserializedJvmInfo.onOutOfMemoryError());
}
}
}
}