Skip to content

Commit

Permalink
Enhancement to allow value conversions
Browse files Browse the repository at this point in the history
  • Loading branch information
coupacooke committed Mar 7, 2014
1 parent 19583ef commit 9aac3b5
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 6 deletions.
36 changes: 35 additions & 1 deletion src/main/java/org/datadog/jmxfetch/JMXAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.LinkedHashMap;
import java.util.List;

import javax.management.AttributeNotFoundException;
Expand All @@ -22,6 +23,7 @@ public abstract class JMXAttribute {
protected String domain;
protected String beanName;
protected String attributeName;
protected LinkedHashMap<Object,Object> valueConversions;
protected String[] tags;
protected Configuration matching_conf;
protected static final List<String> SIMPLE_TYPES = Arrays.asList("long", "java.lang.String", "int", "double");
Expand Down Expand Up @@ -125,7 +127,22 @@ protected static String convertMetricName(String metricName) {
return metricName;
}

protected double _getValueAsDouble(Object value) {
protected Object convertMetricValue(Object metricValue) {
Object converted = metricValue;

if (!getValueConversions().isEmpty()) {
converted = this.getValueConversions().get(metricValue);
if (converted == null && this.getValueConversions().get("default") != null) {
converted = this.getValueConversions().get("default");
}
}

return converted;
}

protected double _getValueAsDouble(Object metricValue) {
Object value = convertMetricValue(metricValue);

if (value instanceof String) {
return Double.parseDouble((String)value);

Expand Down Expand Up @@ -177,4 +194,21 @@ protected boolean matchBean(Configuration configuration) {
return true;
}

@SuppressWarnings("unchecked")
protected HashMap<Object, Object> getValueConversions() {
if (this.valueConversions == null) {
if (this.matching_conf.include.get("attribute") instanceof LinkedHashMap<?, ?>) {
LinkedHashMap<String, LinkedHashMap<Object, Object>> attribute = ((LinkedHashMap<String, LinkedHashMap<String, LinkedHashMap<Object, Object>>>)(this.matching_conf.include.get("attribute"))).get(this.attribute.getName());

if (attribute != null) {
this.valueConversions = attribute.get("values");
}
}
if (this.valueConversions == null) {
this.valueConversions = new LinkedHashMap<Object, Object>();
}
}

return this.valueConversions;
}
}
1 change: 1 addition & 0 deletions src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ private String _getMetricType() {

private double _getValue() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException, NumberFormatException {
Object value = this.getJmxValue();

return _getValueAsDouble(value);
}

Expand Down
50 changes: 47 additions & 3 deletions src/test/java/org/datadog/jmxfetch/AppTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ public void testApp() throws Exception {
App.doIteration(config);
LinkedList<HashMap<String, Object>> metrics = ((ConsoleReporter) config.reporter).getMetrics();

assertEquals(metrics.size(), 10); // 10 = 7 metrics from java.lang + the 2 gauges we are explicitly collecting + the 1 gauge that is implicitly collected, see jmx.yaml in the test/resources folder
assertEquals(metrics.size(), 12); // 11 = 7 metrics from java.lang + the 4 gauges we are explicitly collecting + the 1 gauge that is implicitly collected, see jmx.yaml in the test/resources folder

// We test for the presence and the value of the metrics we want to collect
boolean metric_100_present = false;
boolean metric_1000_present = false;
boolean converted_present = false;
boolean default_present = false;
boolean counter_absent = true;
boolean subattr_0_present = false;
boolean subattr_counter_absent = true;
Expand All @@ -112,6 +114,18 @@ else if (name.equals("jmx.org.datadog.jmxfetch.test.should_be1000")) {
metric_1000_present = true;
}

else if (name.equals("test.converted")) {
assertEquals(tags.length, 3);
assertEquals(value, 5.0);
converted_present = true;
}

else if (name.equals("test.defaulted")) {
assertEquals(tags.length, 3);
assertEquals(value, 32.0);
default_present = true;
}

else if (m.get("name").equals("test.counter")) {
counter_absent = false;

Expand All @@ -128,18 +142,22 @@ else if (m.get("name").equals("test.counter")) {

assertTrue(metric_100_present);
assertTrue(metric_1000_present);
assertTrue(converted_present);
assertTrue(default_present);
assertTrue(counter_absent);
assertTrue(subattr_0_present);
assertTrue(subattr_counter_absent);

// We run a second collection. The counter should now be present
App.doIteration(config);
metrics = ((ConsoleReporter) config.reporter).getMetrics();
assertEquals(metrics.size(), 12); // 12 = 7 metrics from java.lang + the 2 gauges we are explicitly collecting + 1 gauge implicitly collected + 2 counter, see jmx.yaml in the test/resources folder
assertEquals(metrics.size(), 14); // 14 = 7 metrics from java.lang + the 4 gauges we are explicitly collecting + 1 gauge implicitly collected + 2 counter, see jmx.yaml in the test/resources folder

// We test for the same metrics but this time, the counter should be here
metric_100_present = false;
metric_1000_present = false;
converted_present = false;
default_present = false;
counter_absent = true;

for (HashMap<String, Object> m : metrics) {
Expand Down Expand Up @@ -174,12 +192,23 @@ else if (m.get("name").equals("test.counter")) {
assertEquals(tags.length, 3);
assertEquals(value, 0.0); // We didn't increment the counter, hence a value of 0.0 is what we want
subattr_counter_absent = false;

} else if(name.equals("test.converted")) {
assertEquals(tags.length, 3);
assertEquals(value, 5.0); // We didn't increment the counter, hence a value of 0.0 is what we want
converted_present = true;

} else if(name.equals("test.defaulted")) {
assertEquals(tags.length, 3);
assertEquals(value, 32.0); // We didn't increment the counter, hence a value of 0.0 is what we want
default_present = true;
}

}

assertTrue(metric_100_present);
assertTrue(metric_1000_present);
assertTrue(converted_present);
assertFalse(counter_absent);
assertTrue(subattr_0_present);
assertFalse(subattr_counter_absent);
Expand All @@ -192,10 +221,12 @@ else if (m.get("name").equals("test.counter")) {

App.doIteration(config);
metrics = ((ConsoleReporter) config.reporter).getMetrics();
assertEquals(metrics.size(), 12); // 12 = 7 metrics from java.lang + the 2 gauges we are explicitly collecting + 1 gauge implicitly collected + 2 counter, see jmx.yaml in the test/resources folder
assertEquals(metrics.size(), 14); // 14 = 7 metrics from java.lang + the 4 gauges we are explicitly collecting + 1 gauge implicitly collected + 2 counter, see jmx.yaml in the test/resources folder

metric_100_present = false;
metric_1000_present = false;
converted_present = false;
default_present = false;
counter_absent = true;
HashMap<String, Integer> jvm_metrics = new HashMap<String, Integer>();
jvm_metrics.put("jvm.gc.cms.count", 2);
Expand Down Expand Up @@ -231,6 +262,16 @@ else if (m.get("name").equals("test.counter")) {
assertEquals(value, 0.0);
subattr_0_present = true;

} else if (name.equals("test.converted")) {
assertEquals(tags.length, 3);
assertEquals(value, 5.0);
converted_present = true;

} else if (name.equals("test.defaulted")) {
assertEquals(tags.length, 3);
assertEquals(value, 32.0);
default_present = true;

} else if(name.equals("subattr.counter")) {
assertEquals(tags.length, 3);
// The value should be a bit less than 1.0, as we incremented the counter by 5 and we slept for 5 seconds
Expand All @@ -249,6 +290,9 @@ else if (m.get("name").equals("test.counter")) {

assertTrue(metric_100_present);
assertTrue(metric_1000_present);
assertTrue(converted_present);
assertTrue(default_present);
assertTrue(metric_1000_present);
assertFalse(counter_absent);
assertTrue(subattr_0_present);
assertFalse(subattr_counter_absent);
Expand Down
11 changes: 10 additions & 1 deletion src/test/java/org/datadog/jmxfetch/SimpleTestJavaApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public class SimpleTestJavaApp implements SimpleTestJavaAppMBean {
private int should_be_100 = 100;
private int should_be_1000 = 1000;
private int should_be_counter = 0;
private String should_be_converted = "ShouldBe5";
private String should_be_defaulted = "DefaultMe";
private HashMap<String, Integer> hashmap = new HashMap<String, Integer>();;

SimpleTestJavaApp() {
Expand All @@ -25,7 +27,15 @@ public Double getShouldBe1000() {
public int getShouldBeCounter() {
return should_be_counter;
}

public String getShouldBeConverted() {
return should_be_converted;
}

public String getShouldBeDefaulted() {
return should_be_defaulted;
}

public void incrementCounter(int inc) {
should_be_counter += inc;
}
Expand All @@ -40,4 +50,3 @@ public HashMap<String, Integer> getHashmap() {


}

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ public interface SimpleTestJavaAppMBean {
int getShouldBe100();
Double getShouldBe1000();
int getShouldBeCounter();
String getShouldBeConverted();
String getShouldBeDefaulted();
HashMap<String, Integer> getHashmap();

}
12 changes: 11 additions & 1 deletion src/test/resources/jmx.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ instances:
Hashmap.thisiscounter:
metric_type: counter
alias: subattr.counter
ShouldBeConverted:
metric_type: gauge
alias: test.converted
values:
ShouldBe0: 0
ShouldBe5: 5
ShouldBeDefaulted:
metric_type: gauge
alias: test.defaulted
values:
default: 32
- include:
domain: org.datadog.jmxfetch.test

0 comments on commit 9aac3b5

Please sign in to comment.