Skip to content

Commit

Permalink
Child statistics pollers now poll all children by default (and not ju…
Browse files Browse the repository at this point in the history
…st the first one)
  • Loading branch information
psiniemi committed Jun 25, 2015
1 parent fa38664 commit a7d1f91
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 133 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.nitorcreations.willow.deployer.statistics;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;

import javax.inject.Inject;

import com.nitorcreations.willow.deployer.Main;

public abstract class AbstractChildStatisticsSender extends AbstractStatisticsSender {
@Inject
protected Main main;
protected List<String> configuredChildren = new ArrayList<String>();

@Override
public void setProperties(Properties properties) {
String nextChild = properties.getProperty("children[0]");
int i = 0;
while (nextChild != null) {
configuredChildren.add(nextChild);
nextChild = properties.getProperty("children[" + ++i + "]");
}
}
protected List<String> getChildren() {
if (configuredChildren.isEmpty()) {
return Arrays.asList(main.getChildNames());
} else {
return Collections.unmodifiableList(configuredChildren);
}
}

}
Original file line number Diff line number Diff line change
@@ -1,42 +1,36 @@
package com.nitorcreations.willow.deployer.statistics;

import java.io.IOException;
import java.util.Properties;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

import javax.inject.Inject;
import javax.management.MBeanServerConnection;
import javax.management.remote.JMXConnector;

import com.nitorcreations.willow.deployer.DeployerControl;
import com.nitorcreations.willow.deployer.Main;

/**
* Abstract base class for statistics senders that use JMX to connect to the child process.
*
* @author Mikko Tommila
*/
public abstract class AbstractJMXStatisticsSender extends AbstractStatisticsSender {

@Inject
protected Main main;

private String childName;
private long oldChildPid = -2;
private JMXConnector connector;
private MBeanServerConnection server;

protected AbstractJMXStatisticsSender() {
public abstract class AbstractJMXStatisticsSender extends AbstractChildStatisticsSender {
private static class MBeanConnectionInfo {
public JMXConnector connector = null;
public MBeanServerConnection server = null;
long childPid = -2;
}
protected Map<String, MBeanConnectionInfo> connections = new HashMap<>();

@Override
public void setProperties(Properties properties) {
childName = properties.getProperty("childName");
protected AbstractJMXStatisticsSender() {
}

@Override
public void stop() {
closeMBeanServerConnection();
for (String childName : connections.keySet()) {
closeMBeanServerConnection(childName);
}
super.stop();
}

Expand All @@ -45,66 +39,57 @@ public void stop() {
*
* @return MBean server connection.
*/
protected MBeanServerConnection getMBeanServerConnection() {
long childPid = main.getFirstJavaChildPid(getChildName());
if (childPid > 0 && childPid != oldChildPid && connector != null) {
protected MBeanServerConnection getMBeanServerConnection(String childName) {
MBeanConnectionInfo connInfo = connections.get(childName);
if (connInfo == null) {
connInfo = new MBeanConnectionInfo();
connections.put(childName, connInfo);
}
long childPid = main.getFirstJavaChildPid(childName);
if (childPid > 0 && childPid != connInfo.childPid && connInfo.connector != null) {
try {
connector.close();
connInfo.connector.close();
} catch (IOException e) {
logger.log(Level.FINE, "Failed to close JMXConnector", e);
}
connector = null;
server = null;
connInfo.connector = null;
connInfo.server = null;
}
if (childPid > 0) {
try {
if (connector == null) {
connector = DeployerControl.getJMXConnector(childPid);
if (connInfo.connector == null) {
connInfo.connector = DeployerControl.getJMXConnector(childPid);
}
if (connector != null && server == null) {
server = connector.getMBeanServerConnection();
oldChildPid = childPid;
if (connInfo.connector != null && connInfo.server == null) {
connInfo.server = connInfo.connector.getMBeanServerConnection();
connInfo.childPid = childPid;
}
} catch (IOException e) {
logger.log(Level.FINE, "Failed to get JMX connection", e);
try {
connector.close();
connInfo.connector.close();
} catch (Exception e2) {
logger.log(Level.FINE, "Failed to close JMXConnector", e2);
}
connector = null;
server = null;
connInfo.connector = null;
connInfo.server = null;
}
}
return server;
return connInfo.server;
}

/**
* Close the MBean server connection.
*/
protected void closeMBeanServerConnection() {
if (connector != null) {
protected void closeMBeanServerConnection(String childName) {
MBeanConnectionInfo connInfo = connections.get(childName);
if (connInfo != null && connInfo.connector != null) {
try {
connector.close();
connInfo.connector.close();
} catch (IOException e) {
logger.log(Level.FINE, "Failed to close JMXConnector", e);
}
connector = null;
}
}

/**
* Get the child name.
*
* @return The child name as configured, or the name of the first child by default.
*/
protected String getChildName() {
if (childName == null) {
String[] children = main.getChildNames();
if (children.length > 0) {
childName = children[0];
}
connInfo.connector = null;
}
return childName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,26 +121,29 @@ private OperationDesriptor getOperationDescriptor(MBeanServerConnection server,
}
@Override
public void execute() {
MBeanServerConnection server = getMBeanServerConnection();
long now = System.currentTimeMillis();
if (server != null && now > nextJmx) {
try {
Map<String, Object> map = new LinkedHashMap<>();
for (Entry<String, JMXReader> next : props.entrySet()) {
Object val = next.getValue().read(server);
if (val != null) {
map.put(next.getKey(), val.toString());
if (now > nextJmx) {
for (String childName : getChildren()) {
try {
Map<String, Object> map = new LinkedHashMap<>();
MBeanServerConnection server = getMBeanServerConnection(childName);
if (server == null) continue;
for (Entry<String, JMXReader> next : props.entrySet()) {
Object val = next.getValue().read(server);
if (val != null) {
map.put(next.getKey(), val.toString());
}
}
if (!map.isEmpty()) {
HashMessage msg = HashMessage.create(map);
msg.addTags("category_customjmx_" + childName);
transmitter.queue(msg);
}
} catch (IOException | ReflectionException | AttributeNotFoundException
| InstanceNotFoundException | IntrospectionException | MBeanException
| ClassNotFoundException e) {
logger.log(Level.WARNING, "Failed to get JMX statistics", e);
}
if (!map.isEmpty()) {
HashMessage msg = HashMessage.create(map);
msg.addTags("category_customjmx_" + getChildName());
transmitter.queue(msg);
}
} catch (IOException | ReflectionException | AttributeNotFoundException
| InstanceNotFoundException | IntrospectionException | MBeanException
| ClassNotFoundException e) {
logger.log(Level.WARNING, "Failed to get JMX statistics", e);
}
nextJmx = nextJmx + interval;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,18 @@ public void setProperties(Properties properties) {
}
@Override
public void execute() {
MBeanServerConnection server = getMBeanServerConnection();
long now = System.currentTimeMillis();
if (server != null && now > nextJmx) {
try {
JmxMessage msg = getJmxStats();
msg.addTags("category_jmx_" + getChildName());
transmitter.queue(msg);
} catch (IOException | MalformedObjectNameException | ReflectionException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstanceNotFoundException | MBeanException e) {
logger.log(Level.WARNING, "Failed to get JMX statistics", e);
if (now > nextJmx) {
for (String childName : getChildren()) {
try {
JmxMessage msg = getJmxStats(childName);
msg.addTags("category_jmx_" + childName);
transmitter.queue(msg);
} catch (IOException | MalformedObjectNameException | ReflectionException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstanceNotFoundException | MBeanException e) {
logger.log(Level.WARNING, "Failed to get JMX statistics", e);
}
nextJmx = nextJmx + conf.getIntervalJmx();
}
nextJmx = nextJmx + conf.getIntervalJmx();
}
try {
TimeUnit.MILLISECONDS.sleep(conf.shortest());
Expand All @@ -60,19 +61,19 @@ public void execute() {
}
}

public JmxMessage getJmxStats() throws MalformedObjectNameException, IOException, ReflectionException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstanceNotFoundException, MBeanException {
public JmxMessage getJmxStats(String childName) throws MalformedObjectNameException, IOException, ReflectionException, IllegalAccessException, InvocationTargetException, NoSuchMethodException, InstanceNotFoundException, MBeanException {
JmxMessage ret = new JmxMessage();
Set<String> poolNames = addGc(ret);
addPools(ret, poolNames);
addMemory(ret);
addCodeCache(ret);
addUptime(ret);
addClassloading(ret);
Set<String> poolNames = addGc(ret, childName);
addPools(ret, poolNames, childName);
addMemory(ret, childName);
addCodeCache(ret, childName);
addUptime(ret, childName);
addClassloading(ret, childName);
return ret;
}

private Set<String> addGc(JmxMessage ret) throws MalformedObjectNameException, IOException {
MBeanServerConnection server = getMBeanServerConnection();
private Set<String> addGc(JmxMessage ret, String childName) throws MalformedObjectNameException, IOException {
MBeanServerConnection server = getMBeanServerConnection(childName);
ObjectName query = new ObjectName("java.lang:type=GarbageCollector,*");
Set<ObjectInstance> gcs = server.queryMBeans(query, null);
LinkedHashSet<String> poolNames = new LinkedHashSet<String>();
Expand All @@ -96,8 +97,8 @@ private Set<String> addGc(JmxMessage ret) throws MalformedObjectNameException, I
return poolNames;
}

private void addPools(JmxMessage ret, Set<String> poolNames) throws MalformedObjectNameException, IOException {
MBeanServerConnection server = getMBeanServerConnection();
private void addPools(JmxMessage ret, Set<String> poolNames, String childName) throws MalformedObjectNameException, IOException {
MBeanServerConnection server = getMBeanServerConnection(childName);
for (String nextPool : poolNames) {
ObjectName query = new ObjectName("java.lang:type=MemoryPool,name=" + nextPool);
Set<ObjectInstance> memPool = server.queryMBeans(query, null);
Expand All @@ -111,8 +112,8 @@ private void addPools(JmxMessage ret, Set<String> poolNames) throws MalformedObj
}
}

private void addMemory(JmxMessage ret) throws MalformedObjectNameException, IOException {
MBeanServerConnection server = getMBeanServerConnection();
private void addMemory(JmxMessage ret, String childName) throws MalformedObjectNameException, IOException {
MBeanServerConnection server = getMBeanServerConnection(childName);
ObjectName query = new ObjectName("java.lang:type=Memory");
Set<ObjectInstance> mem = server.queryMBeans(query, null);
ObjectInstance next = mem.iterator().next();
Expand All @@ -124,8 +125,8 @@ private void addMemory(JmxMessage ret) throws MalformedObjectNameException, IOEx
}
}

private void addCodeCache(JmxMessage ret) throws IOException, MalformedObjectNameException {
MBeanServerConnection server = getMBeanServerConnection();
private void addCodeCache(JmxMessage ret, String childName) throws IOException, MalformedObjectNameException {
MBeanServerConnection server = getMBeanServerConnection(childName);
ObjectName query = new ObjectName("java.lang:type=MemoryPool,name=Code Cache");
Set<ObjectInstance> cc = server.queryMBeans(query, null);
ObjectInstance next = cc.iterator().next();
Expand All @@ -136,16 +137,16 @@ private void addCodeCache(JmxMessage ret) throws IOException, MalformedObjectNam
}
}

private void addUptime(JmxMessage ret) throws MalformedObjectNameException {
MBeanServerConnection server = getMBeanServerConnection();
private void addUptime(JmxMessage ret, String childName) throws MalformedObjectNameException {
MBeanServerConnection server = getMBeanServerConnection(childName);
ObjectName query = new ObjectName("java.lang:type=Runtime");
RuntimeMXBean runtimeBean = JMX.newMBeanProxy(server, query, RuntimeMXBean.class);
ret.setStartTime(runtimeBean.getStartTime());
ret.setUptime(runtimeBean.getUptime());
}

private void addClassloading(JmxMessage ret) throws MalformedObjectNameException {
MBeanServerConnection server = getMBeanServerConnection();
private void addClassloading(JmxMessage ret, String childName) throws MalformedObjectNameException {
MBeanServerConnection server = getMBeanServerConnection(childName);
ObjectName query = new ObjectName("java.lang:type=ClassLoading");
ClassLoadingMXBean clBean = JMX.newMBeanProxy(server, query, ClassLoadingMXBean.class);
ret.setLoadedClassCount(clBean.getLoadedClassCount());
Expand Down
Loading

0 comments on commit a7d1f91

Please sign in to comment.