Skip to content

Commit

Permalink
[attribute][tabular] tag substitution on any field
Browse files Browse the repository at this point in the history
Support tag substitution for any field of a CompositeData attribute.
  • Loading branch information
yannmh committed Mar 1, 2017
1 parent dfdedc1 commit 50cdd7f
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 62 deletions.
3 changes: 1 addition & 2 deletions src/main/java/org/datadog/jmxfetch/JMXAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ private void applyTagsBlackList() {
private void addAdditionalTags() {
Filter include = this.matchingConf.getInclude();
if (include != null) {

for (Map.Entry<String, String> tag : include.getAdditionalTags().entrySet()) {
this.defaultTagsList.add(tag.getKey() + ":" + this.replaceByAlias(tag.getValue()));
}
Expand Down Expand Up @@ -254,7 +253,7 @@ Object convertMetricValue(Object metricValue) {
return converted;
}

double getValueAsDouble(Object metricValue) {
double castToDouble(Object metricValue) {
Object value = convertMetricValue(metricValue);

if (value instanceof String) {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/org/datadog/jmxfetch/JMXComplexAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,27 +65,27 @@ public LinkedList<HashMap<String, Object>> getMetrics()
metric.put("tags", getTags());
}

metric.put("value", getValue(subAttribute));
metric.put("value", castToDouble(getValue(subAttribute)));
metrics.add(metric);

}
return metrics;

}

private double getValue(String subAttribute) throws AttributeNotFoundException, InstanceNotFoundException,
private Object getValue(String subAttribute) throws AttributeNotFoundException, InstanceNotFoundException,
MBeanException, ReflectionException, IOException {

Object value = this.getJmxValue();
String attributeType = getAttribute().getType();

if ("javax.management.openmbean.CompositeData".equals(attributeType)) {
CompositeData data = (CompositeData) value;
return getValueAsDouble(data.get(subAttribute));
return data.get(subAttribute);

} else if ("java.util.HashMap".equals(attributeType)) {
HashMap<String, Object> data = (HashMap<String, Object>) value;
return getValueAsDouble(data.get(subAttribute));
return data.get(subAttribute);
}
throw new NumberFormatException();
}
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public LinkedList<HashMap<String, Object>> getMetrics() throws AttributeNotFound
HashMap<String, Object> metric = new HashMap<String, Object>();

metric.put("alias", getAlias());
metric.put("value", getValue());
metric.put("value", castToDouble(getValue()));
metric.put("tags", getTags());
metric.put("metric_type", getMetricType());
LinkedList<HashMap<String, Object>> metrics = new LinkedList<HashMap<String, Object>>();
Expand Down Expand Up @@ -98,8 +98,8 @@ private String getMetricType() {
return metricType;
}

private double getValue() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException,
private Object getValue() throws AttributeNotFoundException, InstanceNotFoundException, MBeanException,
ReflectionException, IOException, NumberFormatException {
return getValueAsDouble(this.getJmxValue());
return this.getJmxValue();
}
}
77 changes: 39 additions & 38 deletions src/main/java/org/datadog/jmxfetch/JMXTabularAttribute.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,49 +44,46 @@ private String getMultiKey(Collection keys) {
}

private void populateSubAttributeList(Object value) {
String attributeType = getAttribute().getType();
if ("javax.management.openmbean.TabularData".equals(attributeType)) {
TabularData data = (TabularData) value;
for (Object rowKey : data.keySet()) {
Collection keys = (Collection) rowKey;
CompositeData compositeData = data.get(keys.toArray());
String pathKey = getMultiKey(keys);
HashMap<String, HashMap<String, Object>> subAttributes = new HashMap<String, HashMap<String, Object>>();
for (String key : compositeData.getCompositeType().keySet()) {
if (compositeData.get(key) instanceof CompositeData) {
for (String subKey : ((CompositeData) compositeData.get(key)).getCompositeType().keySet()) {
subAttributes.put(key + "." + subKey, new HashMap<String, Object>());
}
} else {
subAttributes.put(key, new HashMap<String, Object>());
TabularData data = (TabularData) value;
for (Object rowKey : data.keySet()) {
Collection keys = (Collection) rowKey;
CompositeData compositeData = data.get(keys.toArray());
String pathKey = getMultiKey(keys);
HashMap<String, HashMap<String, Object>> subAttributes = new HashMap<String, HashMap<String, Object>>();
for (String key : compositeData.getCompositeType().keySet()) {
if (compositeData.get(key) instanceof CompositeData) {
for (String subKey : ((CompositeData) compositeData.get(key)).getCompositeType().keySet()) {
subAttributes.put(key + "." + subKey, new HashMap<String, Object>());
}
} else {
subAttributes.put(key, new HashMap<String, Object>());
}
subAttributeList.put(pathKey, subAttributes);
}
subAttributeList.put(pathKey, subAttributes);
}
}

protected String convertMetricName(String key, String metricName) {
// replace known keys
metricName = metricName.replace("$key", key);
return convertMetricName(metricName);
}

protected String[] getTags(String key, String keyValue) {
protected String[] getTags(String key, String subAttribute) throws AttributeNotFoundException,
InstanceNotFoundException, MBeanException, ReflectionException, IOException {
List<String> tagsList = new ArrayList<String>();
Map<String, ?> attributeParams = getAttributesFor(key);
String fullMetricKey = getAttributeName() + "." + subAttribute;
Map<String, ?> attributeParams = getAttributesFor(fullMetricKey);
if (attributeParams != null) {
Map<String, String> yamlTags = (Map) attributeParams.get("tags");
if (yamlTags != null) {
for (String tagName : yamlTags.keySet()) {
String tag = tagName;
String value = yamlTags.get(tagName);
if (value.equals("$key")) {
value = keyValue;
Object resolvedValue;

if (value.startsWith("$")){
resolvedValue = getValue(key, value.substring(1));
if (resolvedValue != null){
value = (String) resolvedValue;
}
}

tagsList.add(tag + ":" + value);
}
}
}
String[] defaultTags = super.getTags();
tagsList.addAll(Arrays.asList(defaultTags));
Expand Down Expand Up @@ -122,18 +119,18 @@ public LinkedList<HashMap<String, Object>> getMetrics() throws AttributeNotFound
HashMap<String, Object> metric = subSub.get(metricKey);

if (metric.get(ALIAS) == null) {
metric.put(ALIAS, convertMetricName(dataKey, getAlias(metricKey)));
metric.put(ALIAS, convertMetricName(getAlias(metricKey)));
}

if (metric.get(METRIC_TYPE) == null) {
metric.put(METRIC_TYPE, getMetricType(metricKey));
}

if (metric.get("tags") == null) {
metric.put("tags", getTags(fullMetricKey, dataKey));
metric.put("tags", getTags(dataKey, metricKey));
}

metric.put("value", getValue(dataKey, metricKey));
metric.put("value", castToDouble(getValue(dataKey, metricKey)));

if(!subMetrics.containsKey(fullMetricKey)) {
subMetrics.put(fullMetricKey, new LinkedList<HashMap<String, Object>>());
Expand Down Expand Up @@ -164,7 +161,7 @@ private List<HashMap<String, Object>> sortAndFilter(String metricKey, LinkedList
}
MetricComparator comp = new MetricComparator();
Collections.sort(metrics, comp);
String sort = (String) attributes.get("limit_sort");
String sort = (String) attributes.get("sort");
if (sort == null || sort.equals("desc")) {
metrics.subList(0, limit).clear();
} else {
Expand All @@ -181,14 +178,14 @@ public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
}
}

private double getValue(String key, String subAttribute) throws AttributeNotFoundException,
private Object getValue(String key, String subAttribute) throws AttributeNotFoundException,
InstanceNotFoundException,
MBeanException, ReflectionException, IOException {

Object value = this.getJmxValue();
String attributeType = getAttribute().getType();
try{
Object value = this.getJmxValue();
String attributeType = getAttribute().getType();

if ("javax.management.openmbean.TabularData".equals(attributeType)) {
TabularData data = (TabularData) value;
for (Object rowKey : data.keySet()) {
Collection keys = (Collection) rowKey;
Expand All @@ -203,15 +200,19 @@ private double getValue(String key, String subAttribute) throws AttributeNotFoun
if (o instanceof CompositeData) {
compositeData = (CompositeData) o;
} else {
return getValueAsDouble(compositeData.get(subPathKey));
return compositeData.get(subPathKey);
}
}
} else {
return getValueAsDouble(compositeData.get(subAttribute));
return compositeData.get(subAttribute);
}
}
}
}
catch (Exception e){
return null;
}

throw new NumberFormatException();
}

Expand Down
6 changes: 3 additions & 3 deletions src/test/java/org/datadog/jmxfetch/TestApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ public void testApp() throws Exception {
assertMetric("jmx.org.datadog.jmxfetch.test.object1337", 13.37, commonTags, 5);
assertMetric("jmx.org.datadog.jmxfetch.test.primitive_float", 123.4f, commonTags, 5);
assertMetric("jmx.org.datadog.jmxfetch.test.instance_float", 567.8f, commonTags, 5);
assertMetric("multiattr.foo", 1.0, commonTags, Arrays.asList("KeyName:1"), 6);
assertMetric("multiattr.foo", 1.0, commonTags, Arrays.asList("foo:1", "toto:tata"), 7);

assertCoverage();

Expand Down Expand Up @@ -491,7 +491,7 @@ public void testApp() throws Exception {
assertMetric("jmx.org.datadog.jmxfetch.test.object1337", 13.37, commonTags, 5);
assertMetric("jmx.org.datadog.jmxfetch.test.primitive_float", 123.4f, commonTags, 5);
assertMetric("jmx.org.datadog.jmxfetch.test.instance_float", 567.8f, commonTags, 5);
assertMetric("multiattr.foo", 1.0, commonTags, Arrays.asList("KeyName:1"), 6);
assertMetric("multiattr.foo", 1.0, commonTags, Arrays.asList("foo:1", "toto:tata"), 7);

// Counters
assertMetric("subattr.counter", 0.0, commonTags, 5);
Expand Down Expand Up @@ -526,7 +526,7 @@ public void testApp() throws Exception {
assertMetric("jmx.org.datadog.jmxfetch.test.object1337", 13.37, commonTags, 5);
assertMetric("jmx.org.datadog.jmxfetch.test.primitive_float", 123.4f, commonTags, 5);
assertMetric("jmx.org.datadog.jmxfetch.test.instance_float", 567.8f, commonTags, 5);
assertMultiMetric("multiattr.foo", 2.0, commonTags, Arrays.asList("KeyName:2"), 6, "KeyName:2");
assertMetric("multiattr.foo", 2.0, commonTags, Arrays.asList("foo:2", "toto:tata"), 7);

// Counter (verify rate metrics within range)
assertMetric("subattr.counter", 0.95, 1, commonTags, 5);
Expand Down
19 changes: 7 additions & 12 deletions src/test/java/org/datadog/jmxfetch/TestCommon.java
Original file line number Diff line number Diff line change
Expand Up @@ -181,17 +181,16 @@ protected LinkedList<HashMap<String, Object>> getServiceChecks(){
*
* @return fail if the metric was not found
*/
public void assertMetric(String name, Number value, Number lowerBound, Number upperBound, List<String> commonTags, List<String> additionalTags, int countTags, String metricType, String keyTag){
public void assertMetric(String name, Number value, Number lowerBound, Number upperBound, List<String> commonTags, List<String> additionalTags, int countTags, String metricType){
List<String> tags = new ArrayList<String>(commonTags);
tags.addAll(additionalTags);

for (HashMap<String, Object> m: metrics) {
String mName = (String) (m.get("name"));
Double mValue = (Double) (m.get("value"));
Set<String> mTags = new HashSet<String>(Arrays.asList((String[]) (m.get("tags"))));
boolean keyMatch = keyTag == null || mTags.contains(keyTag);

if (mName.equals(name) && keyMatch) {
if (mName.equals(name)) {

if (!value.equals(-1)){
assertEquals((Double)value.doubleValue(), mValue);
Expand Down Expand Up @@ -220,26 +219,22 @@ public void assertMetric(String name, Number value, Number lowerBound, Number up
}

public void assertMetric(String name, Number value, Number lowerBound, Number upperBound, List<String> commonTags, List<String> additionalTags, int countTags) {
assertMetric(name, value, lowerBound, upperBound, commonTags, additionalTags, countTags, null, null);
assertMetric(name, value, lowerBound, upperBound, commonTags, additionalTags, countTags, null);
}

public void assertMetric(String name, Number value, List<String> commonTags, List<String> additionalTags, int countTags){
assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags, null, null);
}

public void assertMultiMetric(String name, Number value, List<String> commonTags, List<String> additionalTags, int countTags, String keyTag){
assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags, null, keyTag);
assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags, null);
}

public void assertMetric(String name, Number value, List<String> commonTags, List<String> additionalTags, int countTags, String metricType){
assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags, metricType, null);
assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags, metricType);
}

public void assertMetric(String name, Number lowerBound, Number upperBound, List<String> commonTags, List<String> additionalTags, int countTags){
assertMetric(name, -1, lowerBound, upperBound, commonTags, additionalTags, countTags, null, null);
assertMetric(name, -1, lowerBound, upperBound, commonTags, additionalTags, countTags, null);
}
public void assertMetric(String name, Number lowerBound, Number upperBound, List<String> commonTags, List<String> additionalTags, int countTags, String metricType){
assertMetric(name, -1, lowerBound, upperBound, commonTags, additionalTags, countTags, metricType, null);
assertMetric(name, -1, lowerBound, upperBound, commonTags, additionalTags, countTags, metricType);
}

public void assertMetric(String name, Number value, List<String> tags, int countTags){
Expand Down

0 comments on commit 50cdd7f

Please sign in to comment.