From 50cdd7f126f99da5e732dbde611c8d6f26181da2 Mon Sep 17 00:00:00 2001 From: Yann MAHE Date: Tue, 28 Feb 2017 17:32:14 -0500 Subject: [PATCH] [attribute][tabular] tag substitution on any field Support tag substitution for any field of a CompositeData attribute. --- .../org/datadog/jmxfetch/JMXAttribute.java | 3 +- .../datadog/jmxfetch/JMXComplexAttribute.java | 8 +- .../datadog/jmxfetch/JMXSimpleAttribute.java | 6 +- .../datadog/jmxfetch/JMXTabularAttribute.java | 77 ++++++++++--------- .../java/org/datadog/jmxfetch/TestApp.java | 6 +- .../java/org/datadog/jmxfetch/TestCommon.java | 19 ++--- 6 files changed, 57 insertions(+), 62 deletions(-) diff --git a/src/main/java/org/datadog/jmxfetch/JMXAttribute.java b/src/main/java/org/datadog/jmxfetch/JMXAttribute.java index c65aedeed..55fb01c3f 100644 --- a/src/main/java/org/datadog/jmxfetch/JMXAttribute.java +++ b/src/main/java/org/datadog/jmxfetch/JMXAttribute.java @@ -98,7 +98,6 @@ private void applyTagsBlackList() { private void addAdditionalTags() { Filter include = this.matchingConf.getInclude(); if (include != null) { - for (Map.Entry tag : include.getAdditionalTags().entrySet()) { this.defaultTagsList.add(tag.getKey() + ":" + this.replaceByAlias(tag.getValue())); } @@ -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) { diff --git a/src/main/java/org/datadog/jmxfetch/JMXComplexAttribute.java b/src/main/java/org/datadog/jmxfetch/JMXComplexAttribute.java index 9d414ea67..1afd6ed88 100644 --- a/src/main/java/org/datadog/jmxfetch/JMXComplexAttribute.java +++ b/src/main/java/org/datadog/jmxfetch/JMXComplexAttribute.java @@ -65,7 +65,7 @@ public LinkedList> getMetrics() metric.put("tags", getTags()); } - metric.put("value", getValue(subAttribute)); + metric.put("value", castToDouble(getValue(subAttribute))); metrics.add(metric); } @@ -73,7 +73,7 @@ public LinkedList> getMetrics() } - private double getValue(String subAttribute) throws AttributeNotFoundException, InstanceNotFoundException, + private Object getValue(String subAttribute) throws AttributeNotFoundException, InstanceNotFoundException, MBeanException, ReflectionException, IOException { Object value = this.getJmxValue(); @@ -81,11 +81,11 @@ private double getValue(String subAttribute) throws AttributeNotFoundException, 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 data = (HashMap) value; - return getValueAsDouble(data.get(subAttribute)); + return data.get(subAttribute); } throw new NumberFormatException(); } diff --git a/src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java b/src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java index 508a0c110..ddd67db7d 100644 --- a/src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java +++ b/src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java @@ -29,7 +29,7 @@ public LinkedList> getMetrics() throws AttributeNotFound HashMap metric = new HashMap(); metric.put("alias", getAlias()); - metric.put("value", getValue()); + metric.put("value", castToDouble(getValue())); metric.put("tags", getTags()); metric.put("metric_type", getMetricType()); LinkedList> metrics = new LinkedList>(); @@ -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(); } } diff --git a/src/main/java/org/datadog/jmxfetch/JMXTabularAttribute.java b/src/main/java/org/datadog/jmxfetch/JMXTabularAttribute.java index a23d4c0b7..5474f2feb 100644 --- a/src/main/java/org/datadog/jmxfetch/JMXTabularAttribute.java +++ b/src/main/java/org/datadog/jmxfetch/JMXTabularAttribute.java @@ -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> subAttributes = new HashMap>(); - 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()); - } - } else { - subAttributes.put(key, new HashMap()); + TabularData data = (TabularData) value; + for (Object rowKey : data.keySet()) { + Collection keys = (Collection) rowKey; + CompositeData compositeData = data.get(keys.toArray()); + String pathKey = getMultiKey(keys); + HashMap> subAttributes = new HashMap>(); + 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()); } + } else { + subAttributes.put(key, new HashMap()); } - 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 tagsList = new ArrayList(); - Map attributeParams = getAttributesFor(key); + String fullMetricKey = getAttributeName() + "." + subAttribute; + Map attributeParams = getAttributesFor(fullMetricKey); if (attributeParams != null) { Map 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)); @@ -122,7 +119,7 @@ public LinkedList> getMetrics() throws AttributeNotFound HashMap 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) { @@ -130,10 +127,10 @@ public LinkedList> getMetrics() throws AttributeNotFound } 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>()); @@ -164,7 +161,7 @@ private List> 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 { @@ -181,14 +178,14 @@ public int compare(HashMap o1, HashMap 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; @@ -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(); } diff --git a/src/test/java/org/datadog/jmxfetch/TestApp.java b/src/test/java/org/datadog/jmxfetch/TestApp.java index e43e86675..5864686fd 100644 --- a/src/test/java/org/datadog/jmxfetch/TestApp.java +++ b/src/test/java/org/datadog/jmxfetch/TestApp.java @@ -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(); @@ -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); @@ -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); diff --git a/src/test/java/org/datadog/jmxfetch/TestCommon.java b/src/test/java/org/datadog/jmxfetch/TestCommon.java index 8fa2a5ce4..7a6bd3fe9 100644 --- a/src/test/java/org/datadog/jmxfetch/TestCommon.java +++ b/src/test/java/org/datadog/jmxfetch/TestCommon.java @@ -181,7 +181,7 @@ protected LinkedList> getServiceChecks(){ * * @return fail if the metric was not found */ - public void assertMetric(String name, Number value, Number lowerBound, Number upperBound, List commonTags, List additionalTags, int countTags, String metricType, String keyTag){ + public void assertMetric(String name, Number value, Number lowerBound, Number upperBound, List commonTags, List additionalTags, int countTags, String metricType){ List tags = new ArrayList(commonTags); tags.addAll(additionalTags); @@ -189,9 +189,8 @@ public void assertMetric(String name, Number value, Number lowerBound, Number up String mName = (String) (m.get("name")); Double mValue = (Double) (m.get("value")); Set mTags = new HashSet(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); @@ -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 commonTags, List 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 commonTags, List additionalTags, int countTags){ - assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags, null, null); - } - - public void assertMultiMetric(String name, Number value, List commonTags, List 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 commonTags, List 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 commonTags, List 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 commonTags, List 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 tags, int countTags){