diff --git a/src/main/java/org/datadog/jmxfetch/Filter.java b/src/main/java/org/datadog/jmxfetch/Filter.java index f72fa16fe..3d74ad06c 100644 --- a/src/main/java/org/datadog/jmxfetch/Filter.java +++ b/src/main/java/org/datadog/jmxfetch/Filter.java @@ -11,6 +11,7 @@ class Filter { Pattern domainRegex; ArrayList beanRegexes = null; ArrayList excludeTags = null; + HashMap additionalTags = null; /** * A simple class to manipulate include/exclude filter elements more easily @@ -121,6 +122,20 @@ public ArrayList getExcludeTags() { return this.excludeTags; } + public HashMap getAdditionalTags() { + // Return additional tags + + if (this.additionalTags == null) { + if (filter.get("tags") == null){ + this.additionalTags = new HashMap(); + } else { + this.additionalTags = (HashMap)filter.get("tags"); + } + } + + return this.additionalTags; + } + public String getDomain() { return (String) filter.get("domain"); } diff --git a/src/main/java/org/datadog/jmxfetch/JMXAttribute.java b/src/main/java/org/datadog/jmxfetch/JMXAttribute.java index 990d0ad5a..c65aedeed 100644 --- a/src/main/java/org/datadog/jmxfetch/JMXAttribute.java +++ b/src/main/java/org/datadog/jmxfetch/JMXAttribute.java @@ -29,7 +29,8 @@ public abstract class JMXAttribute { protected static final String ALIAS = "alias"; protected static final String METRIC_TYPE = "metric_type"; private final static Logger LOGGER = Logger.getLogger(JMXAttribute.class.getName()); - private static final List EXCLUDED_BEAN_PARAMS = Arrays.asList("domain", "domain_regex", "bean_name", "bean", "bean_regex", "attribute", "exclude_tags"); + private static final List EXCLUDED_BEAN_PARAMS = Arrays.asList("domain", "domain_regex", "bean_name", "bean", + "bean_regex", "attribute", "exclude_tags", "tags"); private static final String FIRST_CAP_PATTERN = "(.)([A-Z][a-z]+)"; private static final String ALL_CAP_PATTERN = "([a-z0-9])([A-Z])"; private static final String METRIC_REPLACEMENT = "([^a-zA-Z0-9_.]+)|(^[^a-zA-Z]+)"; @@ -91,6 +92,19 @@ private void applyTagsBlackList() { } } + /** + * Add alias tag from the 'tag_alias' configuration list + */ + 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())); + } + } + } + public static HashMap getBeanParametersHash(String beanParametersString) { String[] beanParameters = beanParametersString.split(","); HashMap beanParamsMap = new HashMap(beanParameters.length); @@ -368,8 +382,11 @@ public Configuration getMatchingConf() { public void setMatchingConf(Configuration matchingConf) { this.matchingConf = matchingConf; - // Now that we have the matchingConf, we can filter out excluded tags - applyTagsBlackList(); + // Now that we have the matchingConf we can: + // - add additional tags + this.addAdditionalTags(); + // - filter out excluded tags + this.applyTagsBlackList(); } MBeanAttributeInfo getAttribute() { @@ -454,12 +471,7 @@ private String getCassandraAlias() { * returns a metric name `my.metric.bar.toto` */ private String getUserAlias(LinkedHashMap> attribute, String fullAttributeName){ - String alias = attribute.get(fullAttributeName).get(ALIAS); - - // Bean parameters - for (Map.Entry param : beanParameters.entrySet()) { - alias = alias.replace("$" + param.getKey(), param.getValue()); - } + String alias = this.replaceByAlias(attribute.get(fullAttributeName).get(ALIAS)); // Attribute & domain alias = alias.replace("$attribute", fullAttributeName); @@ -468,6 +480,14 @@ private String getUserAlias(LinkedHashMap> return alias; } + private String replaceByAlias(String alias){ + // Bean parameters + for (Map.Entry param : beanParameters.entrySet()) { + alias = alias.replace("$" + param.getKey(), param.getValue()); + } + return alias; + } + /** * Overload `getAlias` method. * diff --git a/src/test/java/org/datadog/jmxfetch/TestApp.java b/src/test/java/org/datadog/jmxfetch/TestApp.java index c4ff381f8..f9f474cb7 100644 --- a/src/test/java/org/datadog/jmxfetch/TestApp.java +++ b/src/test/java/org/datadog/jmxfetch/TestApp.java @@ -391,6 +391,37 @@ public void testExcludeTags() throws Exception { assertMetric("test1.histogram", 424242, commonTags, 2, "histogram"); } + @Test + public void testAdditionalTags() throws Exception { + // We expose a few metrics through JMX + SimpleTestJavaApp testApp = new SimpleTestJavaApp(); + registerMBean(testApp, "org.datadog.jmxfetch.test:type=SimpleTestJavaApp,name=testName"); + + // We do a first collection + initApplication("jmx_additional_tags.yml"); + run(); + LinkedList> metrics = getMetrics(); + + // We test for the presence and the value of the metrics we want to collect. + // Tags "type", "newTag" and "env" should be excluded + List commonTags = Arrays.asList( + "instance:jmx_test_instance", + "jmx_domain:org.datadog.jmxfetch.test", + "type:SimpleTestJavaApp", + "name:testName", + "simple:SimpleTestJavaApp", + "raw_value:value", + "unknown_tag:$does-not-exist", + "multiple:SimpleTestJavaApp-testName"); + + // 15 = 13 metrics from java.lang + the 2 collected (gauge and histogram) + assertEquals(15, metrics.size()); + + // There should only left 2 tags per metric + assertMetric("test1.gauge", 1000.0, commonTags, 8, "gauge"); + assertMetric("test1.histogram", 424242, commonTags, 8, "histogram"); + } + /** * FIXME: Split this test in multiple sub-tests. */ diff --git a/src/test/resources/jmx_additional_tags.yml b/src/test/resources/jmx_additional_tags.yml new file mode 100644 index 000000000..f6e4ea8c0 --- /dev/null +++ b/src/test/resources/jmx_additional_tags.yml @@ -0,0 +1,20 @@ +init_config: + +instances: + - process_name_regex: .*surefire.* + name: jmx_test_instance + conf: + - include: + domain: org.datadog.jmxfetch.test + tags: + simple: $type + raw_value: value + unknown_tag: $does-not-exist + multiple: $type-$name + attribute: + ShouldBe1000: + metric_type: gauge + alias: test1.gauge + Int424242: + metric_type: histogram + alias: test1.histogram