Process Stats: remove sigar specific stats from APIs and add JMX implementation
This commit is contained in:
parent
f9a45fd605
commit
1c5d8efd47
|
@ -430,11 +430,11 @@ public class ClusterStatsNodes implements ToXContent, Streamable {
|
|||
return;
|
||||
}
|
||||
count++;
|
||||
if (nodeStats.getProcess().cpu() != null) {
|
||||
if (nodeStats.getProcess().getCpu() != null) {
|
||||
// with no sigar, this may not be available
|
||||
cpuPercent += nodeStats.getProcess().cpu().getPercent();
|
||||
cpuPercent += nodeStats.getProcess().getCpu().getPercent();
|
||||
}
|
||||
long fd = nodeStats.getProcess().openFileDescriptors();
|
||||
long fd = nodeStats.getProcess().getOpenFileDescriptors();
|
||||
if (fd > 0) {
|
||||
// fd can be -1 if not supported on platform
|
||||
totalOpenFileDescriptors += fd;
|
||||
|
|
|
@ -40,7 +40,7 @@ import org.elasticsearch.common.logging.log4j.LogConfigurator;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.env.Environment;
|
||||
import org.elasticsearch.monitor.jvm.JvmInfo;
|
||||
import org.elasticsearch.monitor.process.JmxProcessProbe;
|
||||
import org.elasticsearch.monitor.process.ProcessProbe;
|
||||
import org.elasticsearch.node.Node;
|
||||
import org.elasticsearch.node.NodeBuilder;
|
||||
import org.elasticsearch.node.internal.InternalSettingsPreparer;
|
||||
|
@ -143,14 +143,22 @@ public class Bootstrap {
|
|||
StringHelper.randomId();
|
||||
}
|
||||
|
||||
static void initializeProbes() {
|
||||
// Force probes to be loaded
|
||||
ProcessProbe.getInstance();
|
||||
}
|
||||
|
||||
public static boolean isMemoryLocked() {
|
||||
return Natives.isMemoryLocked();
|
||||
}
|
||||
|
||||
private void setup(boolean addShutdownHook, Settings settings, Environment environment) throws Exception {
|
||||
initializeNatives(settings.getAsBoolean("bootstrap.mlockall", false),
|
||||
initializeNatives(settings.getAsBoolean("bootstrap.mlockall", false),
|
||||
settings.getAsBoolean("bootstrap.ctrlhandler", true));
|
||||
|
||||
// initialize probes before the security manager is installed
|
||||
initializeProbes();
|
||||
|
||||
if (addShutdownHook) {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
@Override
|
||||
|
@ -167,7 +175,7 @@ public class Bootstrap {
|
|||
|
||||
// look for jar hell
|
||||
JarHell.checkJarHell();
|
||||
|
||||
|
||||
// install SM after natives, shutdown hooks, etc.
|
||||
setupSecurity(settings, environment);
|
||||
|
||||
|
@ -262,7 +270,7 @@ public class Bootstrap {
|
|||
|
||||
if (System.getProperty("es.max-open-files", "false").equals("true")) {
|
||||
ESLogger logger = Loggers.getLogger(Bootstrap.class);
|
||||
logger.info("max_open_files [{}]", JmxProcessProbe.getMaxFileDescriptorCount());
|
||||
logger.info("max_open_files [{}]", ProcessProbe.getInstance().getMaxFileDescriptorCount());
|
||||
}
|
||||
|
||||
// warn if running using the client VM
|
||||
|
|
|
@ -28,7 +28,6 @@ import org.elasticsearch.monitor.jvm.JvmService;
|
|||
import org.elasticsearch.monitor.os.JmxOsProbe;
|
||||
import org.elasticsearch.monitor.os.OsProbe;
|
||||
import org.elasticsearch.monitor.os.OsService;
|
||||
import org.elasticsearch.monitor.process.JmxProcessProbe;
|
||||
import org.elasticsearch.monitor.process.ProcessProbe;
|
||||
import org.elasticsearch.monitor.process.ProcessService;
|
||||
|
||||
|
@ -50,7 +49,7 @@ public class MonitorModule extends AbstractModule {
|
|||
@Override
|
||||
protected void configure() {
|
||||
// bind default implementations
|
||||
bind(ProcessProbe.class).to(JmxProcessProbe.class).asEagerSingleton();
|
||||
bind(ProcessProbe.class).toInstance(ProcessProbe.getInstance());
|
||||
bind(OsProbe.class).to(JmxOsProbe.class).asEagerSingleton();
|
||||
bind(FsProbe.class).asEagerSingleton();
|
||||
|
||||
|
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* 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.monitor.process;
|
||||
|
||||
import org.elasticsearch.common.component.AbstractComponent;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import static org.elasticsearch.monitor.jvm.JvmInfo.jvmInfo;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JmxProcessProbe extends AbstractComponent implements ProcessProbe {
|
||||
|
||||
private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
|
||||
private static final Method getMaxFileDescriptorCountField;
|
||||
private static final Method getOpenFileDescriptorCountField;
|
||||
|
||||
static {
|
||||
Method method = null;
|
||||
try {
|
||||
method = osMxBean.getClass().getDeclaredMethod("getMaxFileDescriptorCount");
|
||||
method.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
// not available
|
||||
}
|
||||
getMaxFileDescriptorCountField = method;
|
||||
|
||||
method = null;
|
||||
try {
|
||||
method = osMxBean.getClass().getDeclaredMethod("getOpenFileDescriptorCount");
|
||||
method.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
// not available
|
||||
}
|
||||
getOpenFileDescriptorCountField = method;
|
||||
}
|
||||
|
||||
public static long getMaxFileDescriptorCount() {
|
||||
if (getMaxFileDescriptorCountField == null) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
return (Long) getMaxFileDescriptorCountField.invoke(osMxBean);
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public static long getOpenFileDescriptorCount() {
|
||||
if (getOpenFileDescriptorCountField == null) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
return (Long) getOpenFileDescriptorCountField.invoke(osMxBean);
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@Inject
|
||||
public JmxProcessProbe(Settings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessInfo processInfo() {
|
||||
return new ProcessInfo(jvmInfo().pid(), getMaxFileDescriptorCount());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProcessStats processStats() {
|
||||
ProcessStats stats = new ProcessStats();
|
||||
stats.timestamp = System.currentTimeMillis();
|
||||
stats.openFileDescriptors = getOpenFileDescriptorCount();
|
||||
return stats;
|
||||
}
|
||||
}
|
|
@ -19,7 +19,6 @@
|
|||
|
||||
package org.elasticsearch.monitor.process;
|
||||
|
||||
import org.elasticsearch.bootstrap.Bootstrap;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Streamable;
|
||||
|
@ -29,27 +28,20 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ProcessInfo implements Streamable, ToXContent {
|
||||
|
||||
long refreshInterval;
|
||||
|
||||
private long id;
|
||||
|
||||
private long maxFileDescriptors = -1;
|
||||
|
||||
private boolean mlockall;
|
||||
|
||||
ProcessInfo() {
|
||||
|
||||
}
|
||||
|
||||
public ProcessInfo(long id, long maxFileDescriptors) {
|
||||
public ProcessInfo(long id, boolean mlockall) {
|
||||
this.id = id;
|
||||
this.maxFileDescriptors = maxFileDescriptors;
|
||||
this.mlockall = Bootstrap.isMemoryLocked();
|
||||
this.mlockall = mlockall;
|
||||
}
|
||||
|
||||
public long refreshInterval() {
|
||||
|
@ -60,30 +52,11 @@ public class ProcessInfo implements Streamable, ToXContent {
|
|||
return this.refreshInterval;
|
||||
}
|
||||
|
||||
/**
|
||||
* The process id.
|
||||
*/
|
||||
public long id() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The process id.
|
||||
*/
|
||||
public long getId() {
|
||||
return id();
|
||||
}
|
||||
|
||||
public long maxFileDescriptors() {
|
||||
return this.maxFileDescriptors;
|
||||
}
|
||||
|
||||
public long getMaxFileDescriptors() {
|
||||
return maxFileDescriptors;
|
||||
}
|
||||
|
||||
public boolean mlockAll() {
|
||||
return mlockall;
|
||||
return id;
|
||||
}
|
||||
|
||||
public boolean isMlockall() {
|
||||
|
@ -95,7 +68,6 @@ public class ProcessInfo implements Streamable, ToXContent {
|
|||
static final XContentBuilderString REFRESH_INTERVAL = new XContentBuilderString("refresh_interval");
|
||||
static final XContentBuilderString REFRESH_INTERVAL_IN_MILLIS = new XContentBuilderString("refresh_interval_in_millis");
|
||||
static final XContentBuilderString ID = new XContentBuilderString("id");
|
||||
static final XContentBuilderString MAX_FILE_DESCRIPTORS = new XContentBuilderString("max_file_descriptors");
|
||||
static final XContentBuilderString MLOCKALL = new XContentBuilderString("mlockall");
|
||||
}
|
||||
|
||||
|
@ -104,7 +76,6 @@ public class ProcessInfo implements Streamable, ToXContent {
|
|||
builder.startObject(Fields.PROCESS);
|
||||
builder.timeValueField(Fields.REFRESH_INTERVAL_IN_MILLIS, Fields.REFRESH_INTERVAL, refreshInterval);
|
||||
builder.field(Fields.ID, id);
|
||||
builder.field(Fields.MAX_FILE_DESCRIPTORS, maxFileDescriptors);
|
||||
builder.field(Fields.MLOCKALL, mlockall);
|
||||
builder.endObject();
|
||||
return builder;
|
||||
|
@ -120,7 +91,6 @@ public class ProcessInfo implements Streamable, ToXContent {
|
|||
public void readFrom(StreamInput in) throws IOException {
|
||||
refreshInterval = in.readLong();
|
||||
id = in.readLong();
|
||||
maxFileDescriptors = in.readLong();
|
||||
mlockall = in.readBoolean();
|
||||
}
|
||||
|
||||
|
@ -128,7 +98,6 @@ public class ProcessInfo implements Streamable, ToXContent {
|
|||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeLong(refreshInterval);
|
||||
out.writeLong(id);
|
||||
out.writeLong(maxFileDescriptors);
|
||||
out.writeBoolean(mlockall);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,156 @@
|
|||
|
||||
package org.elasticsearch.monitor.process;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface ProcessProbe {
|
||||
import org.elasticsearch.bootstrap.Bootstrap;
|
||||
|
||||
ProcessInfo processInfo();
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.OperatingSystemMXBean;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
ProcessStats processStats();
|
||||
import static org.elasticsearch.monitor.jvm.JvmInfo.jvmInfo;
|
||||
|
||||
public class ProcessProbe {
|
||||
|
||||
private static final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
|
||||
|
||||
private static final Method getMaxFileDescriptorCountField;
|
||||
private static final Method getOpenFileDescriptorCountField;
|
||||
private static final Method getProcessCpuLoad;
|
||||
private static final Method getProcessCpuTime;
|
||||
private static final Method getCommittedVirtualMemorySize;
|
||||
|
||||
static {
|
||||
getMaxFileDescriptorCountField = getMethod("getMaxFileDescriptorCount");
|
||||
getOpenFileDescriptorCountField = getMethod("getOpenFileDescriptorCount");
|
||||
getProcessCpuLoad = getMethod("getProcessCpuLoad");
|
||||
getProcessCpuTime = getMethod("getProcessCpuTime");
|
||||
getCommittedVirtualMemorySize = getMethod("getCommittedVirtualMemorySize");
|
||||
}
|
||||
|
||||
private static class ProcessProbeHolder {
|
||||
private final static ProcessProbe INSTANCE = new ProcessProbe();
|
||||
}
|
||||
|
||||
public static ProcessProbe getInstance() {
|
||||
return ProcessProbeHolder.INSTANCE;
|
||||
}
|
||||
|
||||
private ProcessProbe() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of file descriptors allowed on the system, or -1 if not supported.
|
||||
*/
|
||||
public long getMaxFileDescriptorCount() {
|
||||
if (getMaxFileDescriptorCountField == null) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
return (Long) getMaxFileDescriptorCountField.invoke(osMxBean);
|
||||
} catch (Throwable t) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of opened file descriptors associated with the current process, or -1 if not supported.
|
||||
*/
|
||||
public long getOpenFileDescriptorCount() {
|
||||
if (getOpenFileDescriptorCountField == null) {
|
||||
return -1;
|
||||
}
|
||||
try {
|
||||
return (Long) getOpenFileDescriptorCountField.invoke(osMxBean);
|
||||
} catch (Throwable t) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the process CPU usage in percent
|
||||
*/
|
||||
public short getProcessCpuPercent() {
|
||||
if (getProcessCpuLoad != null) {
|
||||
try {
|
||||
double load = (double) getProcessCpuLoad.invoke(osMxBean);
|
||||
if (load >= 0) {
|
||||
return (short) (load * 100);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the CPU time (in milliseconds) used by the process on which the Java virtual machine is running, or -1 if not supported.
|
||||
*/
|
||||
public long getProcessCpuTotalTime() {
|
||||
if (getProcessCpuTime != null) {
|
||||
try {
|
||||
long time = (long) getProcessCpuTime.invoke(osMxBean);
|
||||
if (time >= 0) {
|
||||
return (time / 1_000_000L);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size (in bytes) of virtual memory that is guaranteed to be available to the running process
|
||||
*/
|
||||
public long getTotalVirtualMemorySize() {
|
||||
if (getCommittedVirtualMemorySize != null) {
|
||||
try {
|
||||
long virtual = (long) getCommittedVirtualMemorySize.invoke(osMxBean);
|
||||
if (virtual >= 0) {
|
||||
return virtual;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public ProcessInfo processInfo() {
|
||||
return new ProcessInfo(jvmInfo().pid(), Bootstrap.isMemoryLocked());
|
||||
}
|
||||
|
||||
public ProcessStats processStats() {
|
||||
ProcessStats stats = new ProcessStats();
|
||||
stats.timestamp = System.currentTimeMillis();
|
||||
stats.openFileDescriptors = getOpenFileDescriptorCount();
|
||||
stats.maxFileDescriptors = getMaxFileDescriptorCount();
|
||||
|
||||
ProcessStats.Cpu cpu = new ProcessStats.Cpu();
|
||||
cpu.percent = getProcessCpuPercent();
|
||||
cpu.total = getProcessCpuTotalTime();
|
||||
stats.cpu = cpu;
|
||||
|
||||
ProcessStats.Mem mem = new ProcessStats.Mem();
|
||||
mem.totalVirtual = getTotalVirtualMemorySize();
|
||||
stats.mem = mem;
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a given method of the OperatingSystemMXBean,
|
||||
* or null if the method is not found or unavailable.
|
||||
*/
|
||||
private static Method getMethod(String methodName) {
|
||||
try {
|
||||
Method method = osMxBean.getClass().getDeclaredMethod(methodName);
|
||||
method.setAccessible(true);
|
||||
return method;
|
||||
} catch (Throwable t) {
|
||||
// not available
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,14 +30,12 @@ import org.elasticsearch.common.xcontent.XContentBuilderString;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class ProcessStats implements Streamable, ToXContent {
|
||||
|
||||
long timestamp = -1;
|
||||
|
||||
long openFileDescriptors;
|
||||
long openFileDescriptors = -1;
|
||||
long maxFileDescriptors = -1;
|
||||
|
||||
Cpu cpu = null;
|
||||
|
||||
|
@ -46,57 +44,38 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
ProcessStats() {
|
||||
}
|
||||
|
||||
public long timestamp() {
|
||||
return this.timestamp;
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
return timestamp();
|
||||
}
|
||||
|
||||
public long openFileDescriptors() {
|
||||
return this.openFileDescriptors;
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public long getOpenFileDescriptors() {
|
||||
return openFileDescriptors;
|
||||
}
|
||||
|
||||
public Cpu cpu() {
|
||||
return cpu;
|
||||
public long getMaxFileDescriptors() {
|
||||
return maxFileDescriptors;
|
||||
}
|
||||
|
||||
public Cpu getCpu() {
|
||||
return cpu();
|
||||
}
|
||||
|
||||
public Mem mem() {
|
||||
return mem;
|
||||
return cpu;
|
||||
}
|
||||
|
||||
public Mem getMem() {
|
||||
return mem();
|
||||
return mem;
|
||||
}
|
||||
|
||||
static final class Fields {
|
||||
static final XContentBuilderString PROCESS = new XContentBuilderString("process");
|
||||
static final XContentBuilderString TIMESTAMP = new XContentBuilderString("timestamp");
|
||||
static final XContentBuilderString OPEN_FILE_DESCRIPTORS = new XContentBuilderString("open_file_descriptors");
|
||||
static final XContentBuilderString MAX_FILE_DESCRIPTORS = new XContentBuilderString("max_file_descriptors");
|
||||
|
||||
static final XContentBuilderString CPU = new XContentBuilderString("cpu");
|
||||
static final XContentBuilderString PERCENT = new XContentBuilderString("percent");
|
||||
static final XContentBuilderString SYS = new XContentBuilderString("sys");
|
||||
static final XContentBuilderString SYS_IN_MILLIS = new XContentBuilderString("sys_in_millis");
|
||||
static final XContentBuilderString USER = new XContentBuilderString("user");
|
||||
static final XContentBuilderString USER_IN_MILLIS = new XContentBuilderString("user_in_millis");
|
||||
static final XContentBuilderString TOTAL = new XContentBuilderString("total");
|
||||
static final XContentBuilderString TOTAL_IN_MILLIS = new XContentBuilderString("total_in_millis");
|
||||
|
||||
static final XContentBuilderString MEM = new XContentBuilderString("mem");
|
||||
static final XContentBuilderString RESIDENT = new XContentBuilderString("resident");
|
||||
static final XContentBuilderString RESIDENT_IN_BYTES = new XContentBuilderString("resident_in_bytes");
|
||||
static final XContentBuilderString SHARE = new XContentBuilderString("share");
|
||||
static final XContentBuilderString SHARE_IN_BYTES = new XContentBuilderString("share_in_bytes");
|
||||
static final XContentBuilderString TOTAL_VIRTUAL = new XContentBuilderString("total_virtual");
|
||||
static final XContentBuilderString TOTAL_VIRTUAL_IN_BYTES = new XContentBuilderString("total_virtual_in_bytes");
|
||||
}
|
||||
|
@ -106,18 +85,15 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
builder.startObject(Fields.PROCESS);
|
||||
builder.field(Fields.TIMESTAMP, timestamp);
|
||||
builder.field(Fields.OPEN_FILE_DESCRIPTORS, openFileDescriptors);
|
||||
builder.field(Fields.MAX_FILE_DESCRIPTORS, maxFileDescriptors);
|
||||
if (cpu != null) {
|
||||
builder.startObject(Fields.CPU);
|
||||
builder.field(Fields.PERCENT, cpu.percent());
|
||||
builder.timeValueField(Fields.SYS_IN_MILLIS, Fields.SYS, cpu.sys);
|
||||
builder.timeValueField(Fields.USER_IN_MILLIS, Fields.USER, cpu.user);
|
||||
builder.field(Fields.PERCENT, cpu.percent);
|
||||
builder.timeValueField(Fields.TOTAL_IN_MILLIS, Fields.TOTAL, cpu.total);
|
||||
builder.endObject();
|
||||
}
|
||||
if (mem != null) {
|
||||
builder.startObject(Fields.MEM);
|
||||
builder.byteSizeField(Fields.RESIDENT_IN_BYTES, Fields.RESIDENT, mem.resident);
|
||||
builder.byteSizeField(Fields.SHARE_IN_BYTES, Fields.SHARE, mem.share);
|
||||
builder.byteSizeField(Fields.TOTAL_VIRTUAL_IN_BYTES, Fields.TOTAL_VIRTUAL, mem.totalVirtual);
|
||||
builder.endObject();
|
||||
}
|
||||
|
@ -135,6 +111,7 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
public void readFrom(StreamInput in) throws IOException {
|
||||
timestamp = in.readVLong();
|
||||
openFileDescriptors = in.readLong();
|
||||
maxFileDescriptors = in.readLong();
|
||||
if (in.readBoolean()) {
|
||||
cpu = Cpu.readCpu(in);
|
||||
}
|
||||
|
@ -147,6 +124,7 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeVLong(timestamp);
|
||||
out.writeLong(openFileDescriptors);
|
||||
out.writeLong(maxFileDescriptors);
|
||||
if (cpu == null) {
|
||||
out.writeBoolean(false);
|
||||
} else {
|
||||
|
@ -164,8 +142,6 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
public static class Mem implements Streamable {
|
||||
|
||||
long totalVirtual = -1;
|
||||
long resident = -1;
|
||||
long share = -1;
|
||||
|
||||
Mem() {
|
||||
}
|
||||
|
@ -179,47 +155,21 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
totalVirtual = in.readLong();
|
||||
resident = in.readLong();
|
||||
share = in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeLong(totalVirtual);
|
||||
out.writeLong(resident);
|
||||
out.writeLong(share);
|
||||
}
|
||||
|
||||
public ByteSizeValue totalVirtual() {
|
||||
return new ByteSizeValue(totalVirtual);
|
||||
}
|
||||
|
||||
public ByteSizeValue getTotalVirtual() {
|
||||
return totalVirtual();
|
||||
}
|
||||
|
||||
public ByteSizeValue resident() {
|
||||
return new ByteSizeValue(resident);
|
||||
}
|
||||
|
||||
public ByteSizeValue getResident() {
|
||||
return resident();
|
||||
}
|
||||
|
||||
public ByteSizeValue share() {
|
||||
return new ByteSizeValue(share);
|
||||
}
|
||||
|
||||
public ByteSizeValue getShare() {
|
||||
return share();
|
||||
return new ByteSizeValue(totalVirtual);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cpu implements Streamable {
|
||||
|
||||
short percent = -1;
|
||||
long sys = -1;
|
||||
long user = -1;
|
||||
long total = -1;
|
||||
|
||||
Cpu() {
|
||||
|
@ -235,90 +185,31 @@ public class ProcessStats implements Streamable, ToXContent {
|
|||
@Override
|
||||
public void readFrom(StreamInput in) throws IOException {
|
||||
percent = in.readShort();
|
||||
sys = in.readLong();
|
||||
user = in.readLong();
|
||||
total = in.readLong();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(StreamOutput out) throws IOException {
|
||||
out.writeShort(percent);
|
||||
out.writeLong(sys);
|
||||
out.writeLong(user);
|
||||
out.writeLong(total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu usage.
|
||||
* <p/>
|
||||
* <p>
|
||||
* <p>Supported Platforms: All.
|
||||
*/
|
||||
public short percent() {
|
||||
public short getPercent() {
|
||||
return percent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu usage.
|
||||
* <p/>
|
||||
* <p>Supported Platforms: All.
|
||||
*/
|
||||
public short getPercent() {
|
||||
return percent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu kernel time.
|
||||
* <p/>
|
||||
* <p>Supported Platforms: All.
|
||||
*/
|
||||
public TimeValue sys() {
|
||||
return new TimeValue(sys);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu kernel time.
|
||||
* <p/>
|
||||
* <p>Supported Platforms: All.
|
||||
*/
|
||||
public TimeValue getSys() {
|
||||
return sys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu user time.
|
||||
* <p/>
|
||||
* <p>Supported Platforms: All.
|
||||
*/
|
||||
public TimeValue user() {
|
||||
return new TimeValue(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu time (sum of User and Sys).
|
||||
* <p/>
|
||||
* Supported Platforms: All.
|
||||
*/
|
||||
public TimeValue total() {
|
||||
return new TimeValue(total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu time (sum of User and Sys).
|
||||
* <p/>
|
||||
* <p>
|
||||
* Supported Platforms: All.
|
||||
*/
|
||||
public TimeValue getTotal() {
|
||||
return total();
|
||||
return new TimeValue(total);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Process cpu user time.
|
||||
* <p/>
|
||||
* <p>Supported Platforms: All.
|
||||
*/
|
||||
public TimeValue getUser() {
|
||||
return user();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ import org.elasticsearch.monitor.jvm.JvmInfo;
|
|||
import org.elasticsearch.monitor.jvm.JvmStats;
|
||||
import org.elasticsearch.monitor.os.OsInfo;
|
||||
import org.elasticsearch.monitor.os.OsStats;
|
||||
import org.elasticsearch.monitor.process.ProcessInfo;
|
||||
import org.elasticsearch.monitor.process.ProcessStats;
|
||||
import org.elasticsearch.rest.*;
|
||||
import org.elasticsearch.rest.action.support.RestActionListener;
|
||||
|
@ -221,7 +220,6 @@ public class RestNodesAction extends AbstractCatAction {
|
|||
|
||||
JvmInfo jvmInfo = info == null ? null : info.getJvm();
|
||||
OsInfo osInfo = info == null ? null : info.getOs();
|
||||
ProcessInfo processInfo = info == null ? null : info.getProcess();
|
||||
|
||||
JvmStats jvmStats = stats == null ? null : stats.getJvm();
|
||||
FsInfo fsInfo = stats == null ? null : stats.getFs();
|
||||
|
@ -232,7 +230,7 @@ public class RestNodesAction extends AbstractCatAction {
|
|||
table.startRow();
|
||||
|
||||
table.addCell(fullId ? node.id() : Strings.substring(node.getId(), 0, 4));
|
||||
table.addCell(info == null ? null : info.getProcess().id());
|
||||
table.addCell(info == null ? null : info.getProcess().getId());
|
||||
table.addCell(node.getHostName());
|
||||
table.addCell(node.getHostAddress());
|
||||
if (node.address() instanceof InetSocketTransportAddress) {
|
||||
|
@ -252,9 +250,8 @@ public class RestNodesAction extends AbstractCatAction {
|
|||
table.addCell(osStats == null ? null : osStats.getMem() == null ? null : osStats.getMem().usedPercent());
|
||||
table.addCell(osInfo == null ? null : osInfo.getMem() == null ? null : osInfo.getMem().total()); // sigar fails to load in IntelliJ
|
||||
table.addCell(processStats == null ? null : processStats.getOpenFileDescriptors());
|
||||
table.addCell(processStats == null || processInfo == null ? null :
|
||||
calculatePercentage(processStats.getOpenFileDescriptors(), processInfo.getMaxFileDescriptors()));
|
||||
table.addCell(processInfo == null ? null : processInfo.getMaxFileDescriptors());
|
||||
table.addCell(processStats == null ? null : calculatePercentage(processStats.getOpenFileDescriptors(), processStats.getMaxFileDescriptors()));
|
||||
table.addCell(processStats == null ? null : processStats.getMaxFileDescriptors());
|
||||
|
||||
table.addCell(osStats == null ? null : osStats.getLoadAverage().length < 1 ? null : String.format(Locale.ROOT, "%.2f", osStats.getLoadAverage()[0]));
|
||||
table.addCell(jvmStats == null ? null : jvmStats.getUptime());
|
||||
|
|
|
@ -229,7 +229,7 @@ public class RestThreadPoolAction extends AbstractCatAction {
|
|||
table.startRow();
|
||||
|
||||
table.addCell(fullId ? node.id() : Strings.substring(node.getId(), 0, 4));
|
||||
table.addCell(info == null ? null : info.getProcess().id());
|
||||
table.addCell(info == null ? null : info.getProcess().getId());
|
||||
table.addCell(node.getHostName());
|
||||
table.addCell(node.getHostAddress());
|
||||
if (node.address() instanceof InetSocketTransportAddress) {
|
||||
|
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* 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.benchmark.monitor.process;
|
||||
|
||||
import org.elasticsearch.common.logging.ESLogger;
|
||||
import org.elasticsearch.common.logging.ESLoggerFactory;
|
||||
import org.elasticsearch.monitor.process.ProcessProbe;
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
|
||||
public class ProcessProbeBenchmark {
|
||||
|
||||
private static final int ITERATIONS = 100_000;
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.setProperty("es.logger.prefix", "");
|
||||
final ESLogger logger = ESLoggerFactory.getLogger("benchmark");
|
||||
|
||||
logger.info("--> loading process probe");
|
||||
ProcessProbe probe = ProcessProbe.getInstance();
|
||||
|
||||
logger.info("--> warming up...");
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
probe.getOpenFileDescriptorCount();
|
||||
probe.getMaxFileDescriptorCount();
|
||||
probe.getTotalVirtualMemorySize();
|
||||
probe.getProcessCpuPercent();
|
||||
probe.getProcessCpuTotalTime();
|
||||
}
|
||||
logger.info("--> warmed up");
|
||||
|
||||
|
||||
|
||||
|
||||
logger.info("--> testing 'getOpenFileDescriptorCount' method...");
|
||||
long start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
probe.getOpenFileDescriptorCount();
|
||||
}
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> total [{}] ms, avg [{}] ms", elapsed, (elapsed / (double)ITERATIONS));
|
||||
|
||||
logger.info("--> testing 'getMaxFileDescriptorCount' method...");
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
probe.getMaxFileDescriptorCount();
|
||||
}
|
||||
elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> total [{}] ms, avg [{}] ms", elapsed, (elapsed / (double)ITERATIONS));
|
||||
|
||||
logger.info("--> testing 'getTotalVirtualMemorySize' method...");
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
probe.getTotalVirtualMemorySize();
|
||||
}
|
||||
elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> total [{}] ms, avg [{}] ms", elapsed, (elapsed / (double)ITERATIONS));
|
||||
|
||||
logger.info("--> testing 'getProcessCpuPercent' method...");
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
probe.getProcessCpuPercent();
|
||||
}
|
||||
elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> total [{}] ms, avg [{}] ms", elapsed, (elapsed / (double)ITERATIONS));
|
||||
|
||||
logger.info("--> testing 'getProcessCpuTotalTime' method...");
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
probe.getProcessCpuTotalTime();
|
||||
}
|
||||
elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> total [{}] ms, avg [{}] ms", elapsed, (elapsed / (double)ITERATIONS));
|
||||
|
||||
|
||||
|
||||
|
||||
logger.info("--> calculating process CPU user time with 'getAllThreadIds + getThreadUserTime' methods...");
|
||||
final ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
|
||||
final long[] threadIds = threadMxBean.getAllThreadIds();
|
||||
long sum = 0;
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
for (long threadId : threadIds) {
|
||||
sum += threadMxBean.getThreadUserTime(threadId);
|
||||
}
|
||||
}
|
||||
elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> execution time [total: {} ms, avg: {} ms] for {} iterations with average result of {}",
|
||||
elapsed, (elapsed / (double)ITERATIONS), ITERATIONS, (sum / (double)ITERATIONS));
|
||||
|
||||
/* Commented as com.sun.management is listed as forbidden usage
|
||||
if (threadMxBean instanceof com.sun.management.ThreadMXBean) {
|
||||
logger.info("--> calculating process CPU user time with 'getAllThreadIds + getThreadUserTime(long[])' methods...");
|
||||
final com.sun.management.ThreadMXBean threadMxBean2 = (com.sun.management.ThreadMXBean)threadMxBean;
|
||||
sum = 0;
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < ITERATIONS; i++) {
|
||||
long[] user = threadMxBean2.getThreadUserTime(threadIds);
|
||||
for (int n = 0 ; n != threadIds.length; ++n) {
|
||||
sum += user[n];
|
||||
}
|
||||
}
|
||||
elapsed = System.currentTimeMillis() - start;
|
||||
logger.info("--> execution time [total: {} ms, avg: {} ms] for {} iterations with average result of {}",
|
||||
elapsed, (elapsed / (double)ITERATIONS), ITERATIONS, (sum / (double)ITERATIONS));
|
||||
|
||||
}*/
|
||||
}
|
||||
}
|
|
@ -51,6 +51,9 @@ public class BootstrapForTesting {
|
|||
static {
|
||||
// just like bootstrap, initialize natives, then SM
|
||||
Bootstrap.initializeNatives(true, true);
|
||||
|
||||
// initialize probes
|
||||
Bootstrap.initializeProbes();
|
||||
|
||||
// check for jar hell
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.monitor.process;
|
||||
|
||||
import org.elasticsearch.bootstrap.Bootstrap;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.elasticsearch.monitor.jvm.JvmInfo.jvmInfo;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
|
||||
public class ProcessProbeTests extends ElasticsearchTestCase {
|
||||
|
||||
ProcessProbe probe = ProcessProbe.getInstance();
|
||||
|
||||
@Test
|
||||
public void testProcessInfo() {
|
||||
ProcessInfo info = probe.processInfo();
|
||||
assertNotNull(info);
|
||||
assertThat(info.getRefreshInterval(), greaterThanOrEqualTo(0L));
|
||||
assertThat(info.getId(), equalTo(jvmInfo().pid()));
|
||||
assertThat(info.isMlockall(), equalTo(Bootstrap.isMemoryLocked()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testProcessStats() {
|
||||
ProcessStats stats = probe.processStats();
|
||||
assertNotNull(stats);
|
||||
|
||||
ProcessStats.Cpu cpu = stats.getCpu();
|
||||
assertNotNull(cpu);
|
||||
assertThat(cpu.getPercent(), greaterThanOrEqualTo((short) 0));
|
||||
assertThat(cpu.total, anyOf(equalTo(-1L), greaterThan(0L)));
|
||||
|
||||
ProcessStats.Mem mem = stats.getMem();
|
||||
assertNotNull(mem);
|
||||
assertThat(mem.totalVirtual, anyOf(equalTo(-1L), greaterThan(0L)));
|
||||
}
|
||||
}
|
|
@ -32,6 +32,28 @@ curl -XGET 'http://localhost:9200/_nodes/nodeId1,nodeId2/_all
|
|||
|
||||
The `_all` flag can be set to return all the information - or you can simply omit it.
|
||||
|
||||
|
||||
[float]
|
||||
[[process-info]]
|
||||
==== Process information
|
||||
|
||||
The `process` flag can be set to retrieve information that concern
|
||||
the current running process:
|
||||
|
||||
`process.refresh_interval_in_millis`::
|
||||
Refresh interval for the process statistics.
|
||||
|
||||
`process.id`::
|
||||
Process identifier (PID)
|
||||
|
||||
`process.mlockall`::
|
||||
Indicates if the process address space has been successfully locked in memory
|
||||
|
||||
|
||||
[float]
|
||||
[[plugins-info]]
|
||||
==== Plugins information
|
||||
|
||||
`plugins` - if set, the result will contain details about the loaded
|
||||
plugins per node:
|
||||
|
||||
|
|
|
@ -23,33 +23,33 @@ of `indices`, `os`, `process`, `jvm`, `transport`, `http`,
|
|||
`fs`, `breaker` and `thread_pool`. For example:
|
||||
|
||||
[horizontal]
|
||||
`indices`::
|
||||
`indices`::
|
||||
Indices stats about size, document count, indexing and
|
||||
deletion times, search times, field cache size, merges and flushes
|
||||
|
||||
`fs`::
|
||||
`fs`::
|
||||
File system information, data path, free disk space, read/write
|
||||
stats (see <<fs-info,FS information>>)
|
||||
|
||||
`http`::
|
||||
`http`::
|
||||
HTTP connection information
|
||||
|
||||
`jvm`::
|
||||
`jvm`::
|
||||
JVM stats, memory pool information, garbage collection, buffer
|
||||
pools
|
||||
|
||||
`os`::
|
||||
`os`::
|
||||
Operating system stats, load average, cpu, mem, swap
|
||||
|
||||
`process`::
|
||||
`process`::
|
||||
Process statistics, memory consumption, cpu usage, open
|
||||
file descriptors
|
||||
file descriptors (see <<process-stats,Process statistics>>)
|
||||
|
||||
`thread_pool`::
|
||||
`thread_pool`::
|
||||
Statistics about each thread pool, including current
|
||||
size, queue and rejected tasks
|
||||
|
||||
`transport`::
|
||||
`transport`::
|
||||
Transport statistics about sent and received bytes in
|
||||
cluster communication
|
||||
|
||||
|
@ -114,6 +114,31 @@ information that concern the file system:
|
|||
`null` means we could not determine it, `true` means the device possibly spins
|
||||
and `false` means it does not (ex: solid-state disks).
|
||||
|
||||
[float]
|
||||
[[process-stats]]
|
||||
==== Process statistics
|
||||
|
||||
The `process` flag can be set to retrieve statistics that concern
|
||||
the current running process:
|
||||
|
||||
`process.timestamp`::
|
||||
Last time the process statistics have been refreshed
|
||||
|
||||
`process.open_file_descriptors`::
|
||||
Number of opened file descriptors associated with the current process, or -1 if not supported
|
||||
|
||||
`process.max_file_descriptors`::
|
||||
Maximum number of file descriptors allowed on the system, or -1 if not supported
|
||||
|
||||
`process.cpu.percent`::
|
||||
CPU usage in percent
|
||||
|
||||
`process.cpu.total_in_millis`::
|
||||
CPU time (in milliseconds) used by the process on which the Java virtual machine is running, or -1 if not supported
|
||||
|
||||
`process.mem.total_virtual_in_bytes`::
|
||||
Size in bytes of virtual memory that is guaranteed to be available to the running process
|
||||
|
||||
|
||||
[float]
|
||||
[[field-data]]
|
||||
|
|
Loading…
Reference in New Issue