Process Stats: remove sigar specific stats from APIs and add JMX implementation

This commit is contained in:
Tanguy Leroux 2015-07-06 09:37:11 +02:00
parent f9a45fd605
commit 1c5d8efd47
14 changed files with 435 additions and 292 deletions

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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();
}
}
}

View File

@ -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());

View File

@ -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) {

View File

@ -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));
}*/
}
}

View File

@ -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 {

View File

@ -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)));
}
}

View File

@ -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:

View File

@ -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]]