-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Benjamin Geisselmeier
committed
Apr 15, 2015
1 parent
177e236
commit cf8caa2
Showing
8 changed files
with
411 additions
and
0 deletions.
There are no files selected for viewing
123 changes: 123 additions & 0 deletions
123
src/main/java/org/levigo/jadice/server/converterclient/gui/clusterhealth/JmxHelper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package org.levigo.jadice.server.converterclient.gui.clusterhealth; | ||
|
||
import java.io.IOException; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
|
||
import javax.management.JMException; | ||
import javax.management.MBeanServerConnection; | ||
import javax.management.ObjectInstance; | ||
import javax.management.Query; | ||
import javax.management.remote.JMXConnector; | ||
import javax.management.remote.JMXConnectorFactory; | ||
import javax.management.remote.JMXServiceURL; | ||
|
||
import org.levigo.jadice.server.converterclient.Preferences; | ||
|
||
public class JmxHelper { | ||
|
||
private static final String SERVER_BEAN_CLASS = "com.levigo.jadice.server.core.JadiceServer"; | ||
|
||
private static final String STATISTICS_BEAN_CLASS = "com.levigo.jadice.server.core.ServerStatistics"; | ||
|
||
private JmxHelper() { | ||
// hidden constructor | ||
} | ||
|
||
public static JMXConnector createConnector(String jmxServiceUrl) throws JMException { | ||
try { | ||
JMXServiceURL jmxUrl = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://" + jmxServiceUrl + "/jmxrmi"); | ||
final Map<String, Object> env = new HashMap<>(); | ||
if (Preferences.jmxUsernameProperty().isNotEmpty().get()) { | ||
// See https://blogs.oracle.com/lmalventosa/entry/jmx_authentication_authorization | ||
String[] creds = { | ||
Preferences.jmxUsernameProperty().get(), Preferences.jmxPasswordProperty().get() | ||
}; | ||
env.put(JMXConnector.CREDENTIALS, creds); | ||
} | ||
return JMXConnectorFactory.connect(jmxUrl, env); | ||
} catch (IOException | IllegalArgumentException e) { | ||
throw wrap(e); | ||
} | ||
} | ||
|
||
private static <N extends Number> N retrieveNumericValue(MBeanServerConnection mbsc, String beanClassName, String attributeName, | ||
N fallbackValue, Function<String, N> parser) throws JMException { | ||
try { | ||
ObjectInstance bean = getBeanByClassName(beanClassName, mbsc); | ||
if (bean == null) { | ||
return fallbackValue; | ||
} | ||
final Object attribute = mbsc.getAttribute(bean.getObjectName(), attributeName); | ||
if (attribute == null) { | ||
return fallbackValue; | ||
} | ||
return parser.apply(attribute.toString()); | ||
} catch (IOException | NumberFormatException e) { | ||
throw wrap(e); | ||
} | ||
} | ||
|
||
public static ObjectInstance getJadiceServerBean(MBeanServerConnection mbsc) throws IOException { | ||
return JmxHelper.getBeanByClassName(SERVER_BEAN_CLASS, mbsc); | ||
} | ||
|
||
|
||
public static ObjectInstance getStatisticsBean(MBeanServerConnection mbsc) throws IOException { | ||
return getBeanByClassName(STATISTICS_BEAN_CLASS, mbsc); | ||
} | ||
|
||
|
||
public static ObjectInstance getBeanByClassName(String classname, MBeanServerConnection mbsc) throws IOException { | ||
final Set<ObjectInstance> beans = mbsc.queryMBeans(null, Query.isInstanceOf(Query.value(classname))); | ||
if (beans.size() != 1) { | ||
return null; | ||
} | ||
return beans.iterator().next(); | ||
} | ||
|
||
public static float getTotalFailureRate(MBeanServerConnection mbsc) throws JMException { | ||
return retrieveNumericValue(mbsc, STATISTICS_BEAN_CLASS, "TotalFailureRate", Float.NaN, Float::parseFloat); | ||
} | ||
|
||
public static float getRecentFailureRate(MBeanServerConnection mbsc) throws JMException { | ||
return retrieveNumericValue(mbsc, STATISTICS_BEAN_CLASS, "TotalFailureRate", Float.NaN, Float::parseFloat); | ||
} | ||
|
||
public static long getRecentAverageExecutionTime(MBeanServerConnection mbsc) throws JMException { | ||
return retrieveNumericValue(mbsc, STATISTICS_BEAN_CLASS, "RecentAverageExecutionTime", 0L, Long::parseLong); | ||
} | ||
|
||
public static long getAverageExecutionTime(MBeanServerConnection mbsc) throws JMException { | ||
return retrieveNumericValue(mbsc, STATISTICS_BEAN_CLASS, "AverageExecutionTime", 0L, Long::parseLong); | ||
} | ||
|
||
public static float getEfficiency10Min(MBeanServerConnection mbsc) throws JMException { | ||
return retrieveNumericValue(mbsc, STATISTICS_BEAN_CLASS, "Efficiency10Min", Float.NaN, Float::parseFloat); | ||
} | ||
|
||
public static boolean isRunning(MBeanServerConnection mbsc) throws JMException { | ||
try { | ||
final ObjectInstance bean = getJadiceServerBean(mbsc); | ||
if (bean == null) { | ||
return false; | ||
} | ||
return "true".equalsIgnoreCase(mbsc.getAttribute(bean.getObjectName(), "Running").toString()); | ||
} catch (IOException e) { | ||
throw wrap(e); | ||
} | ||
} | ||
|
||
private static JMException wrap(Exception e) throws JMException { | ||
if (e instanceof JMException) { | ||
return (JMException) e; | ||
} | ||
final JMException jmException = new JMException(e.getMessage()); | ||
jmException.initCause(e); | ||
return jmException; | ||
} | ||
|
||
|
||
} |
83 changes: 83 additions & 0 deletions
83
...in/java/org/levigo/jadice/server/converterclient/gui/clusterhealth/StatusControlDemo.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
/* | ||
* Copyright (c) 2013 by Gerrit Grunwald | ||
* | ||
* Licensed 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.levigo.jadice.server.converterclient.gui.clusterhealth; | ||
|
||
|
||
import java.util.Timer; | ||
import java.util.TimerTask; | ||
|
||
import javafx.application.Application; | ||
import javafx.collections.FXCollections; | ||
import javafx.collections.ObservableList; | ||
import javafx.scene.Scene; | ||
import javafx.scene.layout.Background; | ||
import javafx.scene.layout.BackgroundFill; | ||
import javafx.scene.layout.BorderPane; | ||
import javafx.scene.paint.Color; | ||
import javafx.stage.Stage; | ||
|
||
import org.controlsfx.control.GridView; | ||
|
||
|
||
/** | ||
* Created by User: hansolo Date: 31.08.13 Time: 08:37 | ||
*/ | ||
public class StatusControlDemo extends Application { | ||
|
||
private static final ClusterInstance instance1 = new ClusterInstance("localhost:61619", FXCollections.emptyObservableList()); | ||
private static final StatusControl control1 = new StatusControl(instance1); | ||
|
||
private static final ClusterInstance instance2 = new ClusterInstance("jadice-server:61619", FXCollections.emptyObservableList()); | ||
private static final StatusControl control2 = new StatusControl(instance2); | ||
|
||
private final Timer timer = new Timer(); | ||
|
||
@Override | ||
public void init() { | ||
timer.scheduleAtFixedRate(new TimerTask() { | ||
@Override | ||
public void run() { | ||
instance1.update(); | ||
instance2.update(); | ||
|
||
} | ||
}, 0, 5000); | ||
} | ||
|
||
@Override | ||
public void stop() throws Exception { | ||
timer.cancel(); | ||
} | ||
|
||
@Override | ||
public void start(Stage stage) { | ||
final ObservableList<StatusControl> items = FXCollections.observableArrayList(control1, control2); | ||
GridView<StatusControl> grid = new GridView<>(items); | ||
grid.setCellFactory(view -> new StatusControlGridCell()); | ||
grid.setCellWidth(350); | ||
grid.setCellHeight(30); | ||
grid.setVerticalCellSpacing(5); | ||
grid.setHorizontalCellSpacing(5); | ||
final BorderPane root = new BorderPane(grid); | ||
Scene scene = new Scene(root, 128, 128); | ||
root.setBackground(new Background(new BackgroundFill(Color.WHITE, null, null))); | ||
stage.setScene(scene); | ||
stage.show(); | ||
} | ||
|
||
public static void main(String[] args) { | ||
launch(args); | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...levigo/jadice/server/converterclient/gui/clusterhealth/rule/AverageExecutionTimeRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.levigo.jadice.server.converterclient.gui.clusterhealth.rule; | ||
|
||
import javax.management.JMException; | ||
import javax.management.MBeanServerConnection; | ||
|
||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.HealthStatus; | ||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.JmxHelper; | ||
|
||
public class AverageExecutionTimeRule implements Rule<Long> { | ||
|
||
private final long limit; | ||
|
||
public AverageExecutionTimeRule(long limit) { | ||
this.limit = limit; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Average execution time"; | ||
} | ||
|
||
@Override | ||
public EvaluationResult<Long> evaluate(MBeanServerConnection mbsc) { | ||
try { | ||
final long execTime = JmxHelper.getAverageExecutionTime(mbsc); | ||
if (execTime <= limit) { | ||
return new EvaluationResult<Long>(HealthStatus.GOOD, execTime); | ||
} else { | ||
return new EvaluationResult<Long>(HealthStatus.ATTENTION, execTime, getDescription() + ": " + execTime); | ||
} | ||
} catch (JMException e) { | ||
return new EvaluationResult<Long>(HealthStatus.FAILURE, -1L, e); | ||
} | ||
} | ||
} |
36 changes: 36 additions & 0 deletions
36
.../jadice/server/converterclient/gui/clusterhealth/rule/RecentAverageExecutionTimeRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package org.levigo.jadice.server.converterclient.gui.clusterhealth.rule; | ||
|
||
import javax.management.JMException; | ||
import javax.management.MBeanServerConnection; | ||
|
||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.HealthStatus; | ||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.JmxHelper; | ||
|
||
public class RecentAverageExecutionTimeRule implements Rule<Long> { | ||
|
||
private final long limit; | ||
|
||
public RecentAverageExecutionTimeRule(long limit) { | ||
this.limit = limit; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Average execution time"; | ||
} | ||
|
||
@Override | ||
public EvaluationResult<Long> evaluate(MBeanServerConnection mbsc) { | ||
try { | ||
final long execTime = JmxHelper.getRecentAverageExecutionTime(mbsc); | ||
if (execTime <= limit) { | ||
return new EvaluationResult<Long>(HealthStatus.GOOD, execTime); | ||
} else { | ||
return new EvaluationResult<Long>(HealthStatus.ATTENTION, execTime, getDescription() + ": " + execTime); | ||
} | ||
} catch (JMException e) { | ||
return new EvaluationResult<Long>(HealthStatus.FAILURE, -1L, e); | ||
} | ||
|
||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...org/levigo/jadice/server/converterclient/gui/clusterhealth/rule/RecentEfficiencyRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.levigo.jadice.server.converterclient.gui.clusterhealth.rule; | ||
|
||
import javax.management.JMException; | ||
import javax.management.MBeanServerConnection; | ||
|
||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.HealthStatus; | ||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.JmxHelper; | ||
|
||
public class RecentEfficiencyRule implements Rule<Float> { | ||
|
||
private final float limit; | ||
|
||
public RecentEfficiencyRule(float limit) { | ||
this.limit = limit; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Recent efficiency"; | ||
} | ||
|
||
@Override | ||
public EvaluationResult<Float> evaluate(MBeanServerConnection mbsc) { | ||
try { | ||
final float eff = JmxHelper.getEfficiency10Min(mbsc); | ||
if (eff <= limit) { | ||
return new EvaluationResult<Float>(HealthStatus.GOOD, eff); | ||
} else { | ||
return new EvaluationResult<Float>(HealthStatus.ATTENTION, eff, getDescription() + ": " + eff); | ||
} | ||
} catch (JMException e) { | ||
return new EvaluationResult<Float>(HealthStatus.FAILURE, Float.NaN, e); | ||
} | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
...rg/levigo/jadice/server/converterclient/gui/clusterhealth/rule/RecentFailureRateRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package org.levigo.jadice.server.converterclient.gui.clusterhealth.rule; | ||
|
||
import javax.management.JMException; | ||
import javax.management.MBeanServerConnection; | ||
|
||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.HealthStatus; | ||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.JmxHelper; | ||
|
||
public class RecentFailureRateRule implements Rule<Float> { | ||
|
||
private final float limit; | ||
|
||
public RecentFailureRateRule(float limit) { | ||
this.limit = limit; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Recent failure rate"; | ||
} | ||
|
||
@Override | ||
public EvaluationResult<Float> evaluate(MBeanServerConnection mbsc) { | ||
try { | ||
final float rate = JmxHelper.getRecentFailureRate(mbsc); | ||
if (rate <= limit) { | ||
return new EvaluationResult<Float>(HealthStatus.GOOD, rate); | ||
} else { | ||
return new EvaluationResult<Float>(HealthStatus.ATTENTION, rate, getDescription() + ": " + rate); | ||
} | ||
} catch (JMException e) { | ||
return new EvaluationResult<Float>(HealthStatus.FAILURE, Float.NaN, e); | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
...va/org/levigo/jadice/server/converterclient/gui/clusterhealth/rule/ServerRunningRule.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package org.levigo.jadice.server.converterclient.gui.clusterhealth.rule; | ||
|
||
import javax.management.JMException; | ||
import javax.management.MBeanServerConnection; | ||
|
||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.HealthStatus; | ||
import org.levigo.jadice.server.converterclient.gui.clusterhealth.JmxHelper; | ||
|
||
public class ServerRunningRule implements Rule<Boolean> { | ||
|
||
@Override | ||
public String getDescription() { | ||
return "Instance is running"; | ||
} | ||
|
||
@Override | ||
public EvaluationResult<Boolean> evaluate(MBeanServerConnection mbsc) { | ||
try { | ||
if (JmxHelper.isRunning(mbsc)) { | ||
return new EvaluationResult<Boolean>(HealthStatus.GOOD, true); | ||
} else { | ||
return new EvaluationResult<Boolean>(HealthStatus.FAILURE, false, getDescription() + ": false"); | ||
} | ||
} catch (JMException e) { | ||
return new EvaluationResult<Boolean>(HealthStatus.FAILURE, false, e); | ||
} | ||
} | ||
} |
Oops, something went wrong.