Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRILL-8446: Incorrect use of OperatingSystemMXBean #2843

Merged
merged 2 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 46 additions & 66 deletions common/src/main/java/org/apache/drill/exec/metrics/CpuGaugeSet.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,95 +18,75 @@
package org.apache.drill.exec.metrics;

import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.util.HashMap;
import java.util.Map;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricSet;
import com.sun.management.OperatingSystemMXBean;
import com.google.common.collect.ImmutableMap;

/**
* Creates a Cpu GaugeSet
*/
@SuppressWarnings("restriction")
public class CpuGaugeSet implements MetricSet {
private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(CpuGaugeSet.class);

private final OperatingSystemMXBean osMXBean;
private final RuntimeMXBean rtMXBean;

public CpuGaugeSet() {
this.rtMXBean = ManagementFactory.getRuntimeMXBean();
//DRILL-6702: Instead of worrying about compiling with IBM JDK, for now, we shall provide no CPU metrics for non-HotSpot JVMs
this.osMXBean = getOSMXBeanForCpuMetrics();
}
private final OperatingSystemMXBean osMxBean = ManagementFactory.getOperatingSystemMXBean();
private final RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();

@Override
public Map<String, Metric> getMetrics() {
final Map<String, Metric> metric = new HashMap<>(1);
metric.put("os.load.avg", new OperatingSystemLoad(osMXBean));
metric.put("drillbit.load.avg", new DrillbitProcessLoad(osMXBean));
metric.put("drillbit.uptime", new DrillbitUptime(rtMXBean));
return metric;
}

private static OperatingSystemMXBean getOSMXBeanForCpuMetrics() {
try {
return (OperatingSystemMXBean) ManagementFactory.getOperatingSystemMXBean();
} catch (ClassCastException ex) {
logger.warn("{}. Detected non-Supported JVM [{}]. CPU Metrics in the WebUI will not be available!", ex.getMessage(), System.getProperty("java.vm.name"));
}
return null;
}
}
// We create each CPU gauge using an anonymous inner class that fetches
// its metric from the relevant Java MX bean.

/**
* Creating an AverageSystemLoad Gauge
*/
@SuppressWarnings("restriction")
final class OperatingSystemLoad implements Gauge<Double> {
private OperatingSystemMXBean osMXBean;
public OperatingSystemLoad(OperatingSystemMXBean osBean) {
this.osMXBean = osBean;
}
Gauge<Double> osLoadAvgGauge = new Gauge<Double>() {
@Override
public Double getValue() {
return osMxBean.getSystemLoadAverage();
}
};

@Override
public Double getValue() {
return (osMXBean != null) ? osMXBean.getSystemLoadAverage() : null;
}
// Sun/Oracle runtimes only, c.f. DRILL-6702 and DRILL-8446.
Gauge<Double> procLoadAvgGauge = new Gauge<Double>() {
private boolean canUseSunInternalBean = true;

}
@Override
@SuppressWarnings("restriction")
public Double getValue() {
if (!canUseSunInternalBean) {
return null;
}

/**
* Creating an AverageDrillbitLoad Gauge
*/
@SuppressWarnings("restriction")
final class DrillbitProcessLoad implements Gauge<Double> {
private OperatingSystemMXBean osMXBean;
public DrillbitProcessLoad(OperatingSystemMXBean osBean) {
this.osMXBean = osBean;
}
// Make a single attempt to cast to the com.sun internal class. The mere
// mention of com.sun must happen inside a try block.
try {
return ((com.sun.management.OperatingSystemMXBean)osMxBean).getProcessCpuLoad();

@Override
public Double getValue() {
return (osMXBean != null) ? osMXBean.getProcessCpuLoad() : null;
}
} catch (NoClassDefFoundError | ClassCastException e) {
org.slf4j.LoggerFactory.getLogger(CpuGaugeSet.class).warn(
"The process load gauge is not supported on this Java runtime: {}",
System.getProperty("java.vm.name")
);
canUseSunInternalBean = false;
return null;
}
}
};

}
/**
* Creating an DrillbitUptime Gauge
*/
final class DrillbitUptime implements Gauge<Long> {
private RuntimeMXBean rtMXBean;
public DrillbitUptime(RuntimeMXBean osBean) {
this.rtMXBean = osBean;
}
Gauge<Long> uptimeGauge = new Gauge<Long>() {
@Override
public Long getValue() {
return runtimeMxBean.getUptime();
}
};

@Override
public Long getValue() {
return rtMXBean.getUptime();
return ImmutableMap.of(
"os.load.avg", osLoadAvgGauge,
"drillbit.load.avg", procLoadAvgGauge,
"drillbit.uptime", uptimeGauge
);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ public void testSplunkQueryWithUserTranslation() throws Exception {
.property(DrillProperties.PASSWORD, TEST_USER_1_PASSWORD)
.build();

String sql = "SELECT acceleration_id, action, add_offset, add_timestamp FROM ut_splunk._audit LIMIT 2";
String sql = "SELECT acceleration_id, action, add_offset, add_timestamp FROM ut_splunk._audit LIMIT 1";
RowSet results = client.queryBuilder().sql(sql).rowSet();
assertEquals(2, results.rowCount());
assertEquals(1, results.rowCount());
results.clear();
}

Expand Down