Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[attribute] add TabularData support #128

Merged
merged 7 commits into from
Mar 3, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/main/java/org/datadog/jmxfetch/Instance.java
Original file line number Diff line number Diff line change
@@ -26,6 +26,7 @@ public class Instance {
"java.util.concurrent.atomic.AtomicInteger", "java.util.concurrent.atomic.AtomicLong",
"java.lang.Object", "java.lang.Boolean", "boolean", "java.lang.Number");
private final static List<String> COMPOSED_TYPES = Arrays.asList("javax.management.openmbean.CompositeData", "java.util.HashMap", "java.util.Map");
private final static List<String> MULTI_TYPES = Arrays.asList("javax.management.openmbean.TabularData");
private final static int MAX_RETURNED_METRICS = 350;
private final static int DEFAULT_REFRESH_BEANS_PERIOD = 600;
public static final String PROCESS_NAME_REGEX = "process_name_regex";
@@ -248,8 +249,11 @@ private void getMatchingAttributes() {
LOGGER.debug(ATTRIBUTE + beanName + " : " + attributeInfo + " has attributeInfo simple type");
jmxAttribute = new JMXSimpleAttribute(attributeInfo, beanName, instanceName, connection, tags, cassandraAliasing);
} else if (COMPOSED_TYPES.contains(attributeType)) {
LOGGER.debug(ATTRIBUTE + beanName + " : " + attributeInfo + " has attributeInfo complex type");
LOGGER.debug(ATTRIBUTE + beanName + " : " + attributeInfo + " has attributeInfo composite type");
jmxAttribute = new JMXComplexAttribute(attributeInfo, beanName, instanceName, connection, tags);
} else if (MULTI_TYPES.contains(attributeType)) {
LOGGER.debug(ATTRIBUTE + beanName + " : " + attributeInfo + " has attributeInfo tabular type");
jmxAttribute = new JMXTabularAttribute(attributeInfo, beanName, instanceName, connection, tags);
} else {
try {
LOGGER.debug(ATTRIBUTE + beanName + " : " + attributeInfo + " has an unsupported type: " + attributeType);
5 changes: 2 additions & 3 deletions src/main/java/org/datadog/jmxfetch/JMXAttribute.java
Original file line number Diff line number Diff line change
@@ -28,7 +28,7 @@ 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());
protected final static Logger LOGGER = Logger.getLogger(JMXAttribute.class.getName());
private static final List<String> 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]+)";
@@ -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()));
}
@@ -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) {
9 changes: 4 additions & 5 deletions src/main/java/org/datadog/jmxfetch/JMXComplexAttribute.java
Original file line number Diff line number Diff line change
@@ -65,27 +65,26 @@ 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)) || ("java.util.Map".equals(attributeType))) {
Map<String, Object> data = (Map<String, Object>) value;
return getValueAsDouble(data.get(subAttribute));
return data.get(subAttribute);
}
throw new NumberFormatException();
}
6 changes: 3 additions & 3 deletions src/main/java/org/datadog/jmxfetch/JMXSimpleAttribute.java
Original file line number Diff line number Diff line change
@@ -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>>();
@@ -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();
}
}
296 changes: 296 additions & 0 deletions src/main/java/org/datadog/jmxfetch/JMXTabularAttribute.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,296 @@
package org.datadog.jmxfetch;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.management.AttributeNotFoundException;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanAttributeInfo;
import javax.management.MBeanException;
import javax.management.ObjectName;
import javax.management.openmbean.CompositeData;
import javax.management.openmbean.InvalidKeyException;
import javax.management.openmbean.TabularData;
import javax.management.ReflectionException;

public class JMXTabularAttribute extends JMXAttribute {
private String instanceName;
private HashMap<String, HashMap<String, HashMap<String, Object>>> subAttributeList;

public JMXTabularAttribute(MBeanAttributeInfo attribute, ObjectName beanName, String instanceName,
Connection connection, HashMap<String, String> instanceTags) {
super(attribute, beanName, instanceName, connection, instanceTags, false);
subAttributeList = new HashMap<String, HashMap<String, HashMap<String, Object>>>();
}

private String getMultiKey(Collection keys) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (Object key : keys) {
if (!first) { sb.append(","); }
// I hope these have sane toString() methods
sb.append(key.toString());
first = false;
}
return sb.toString();
}

private void populateSubAttributeList(Object value) {
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);
}
}

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

String[] tags = new String[tagsList.size()];
tags = tagsList.toArray(tags);
return tags;
}

private Map<String, ?> getAttributesFor(String key) {
Filter include = getMatchingConf().getInclude();
if (include != null) {
Object includeAttribute = include.getAttribute();
if (includeAttribute instanceof LinkedHashMap<?, ?>) {
return (Map<String, ?>) ((Map)includeAttribute).get(key);
}
}
return null;
}

@Override
public LinkedList<HashMap<String, Object>> getMetrics() throws AttributeNotFoundException,
InstanceNotFoundException, MBeanException, ReflectionException, IOException {
LinkedList<HashMap<String, Object>> metrics = new LinkedList<HashMap<String, Object>>();
HashMap<String, LinkedList<HashMap<String, Object>>> subMetrics = new HashMap<String,
LinkedList<HashMap<String, Object>>>();

for (String dataKey : subAttributeList.keySet()) {
HashMap<String, HashMap<String, Object>> subSub = subAttributeList.get(dataKey);
for (String metricKey : subSub.keySet()) {
String fullMetricKey = getAttributeName() + "." + metricKey;

HashMap<String, Object> metric = subSub.get(metricKey);

if (metric.get(ALIAS) == null) {
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(dataKey, metricKey));
}

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

if(!subMetrics.containsKey(fullMetricKey)) {
subMetrics.put(fullMetricKey, new LinkedList<HashMap<String, Object>>());
}
subMetrics.get(fullMetricKey).add(metric);
}
}

for (String key : subMetrics.keySet()) {
// only add explicitly included metrics
if (getAttributesFor(key) != null) {
metrics.addAll(sortAndFilter(key, subMetrics.get(key)));
}
}

return metrics;
}

private List<HashMap<String, Object>> sortAndFilter(String metricKey, LinkedList<HashMap<String, Object>>
metrics) {
Map<String, ?> attributes = getAttributesFor(metricKey);
if (!attributes.containsKey("limit")) {
return metrics;
}
Integer limit = (Integer) attributes.get("limit");
if (metrics.size() <= limit) {
return metrics;
}
MetricComparator comp = new MetricComparator();
Collections.sort(metrics, comp);
String sort = (String) attributes.get("sort");
if (sort == null || sort.equals("desc")) {
metrics.subList(0, limit).clear();
} else {
metrics.subList(metrics.size() - limit, metrics.size()).clear();
}
return metrics;
}

private class MetricComparator implements Comparator<HashMap<String, Object>> {
public int compare(HashMap<String, Object> o1, HashMap<String, Object> o2) {
Double v1 = (Double) o1.get("value");
Double v2 = (Double) o2.get("value");
return v1.compareTo(v2);
}
}

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

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

TabularData data = (TabularData) value;
for (Object rowKey : data.keySet()) {
Collection keys = (Collection) rowKey;
String pathKey = getMultiKey(keys);
if (key.equals(pathKey)) {
CompositeData compositeData = data.get(keys.toArray());
if (subAttribute.contains(".")) {
// walk down the path
Object o;
for (String subPathKey : subAttribute.split("\\.")) {
o = compositeData.get(subPathKey);
if (o instanceof CompositeData) {
compositeData = (CompositeData) o;
} else {
return compositeData.get(subPathKey);
}
}
} else {
return compositeData.get(subAttribute);
}
}
}
}
catch (InvalidKeyException e){
LOGGER.warn("`"+getAttribute().getName()+"` attribute does not have a `"+subAttribute+"` key.");
return null;
}

throw new NumberFormatException();
}

private Object getMetricType(String subAttribute) {
String subAttributeName = getAttribute().getName() + "." + subAttribute;
String metricType = null;

Filter include = getMatchingConf().getInclude();
if (include.getAttribute() instanceof LinkedHashMap<?, ?>) {
LinkedHashMap<String, LinkedHashMap<String, String>> attribute = (LinkedHashMap<String,
LinkedHashMap<String, String>>) (include.getAttribute());
metricType = attribute.get(subAttributeName).get(METRIC_TYPE);
if (metricType == null) {
metricType = attribute.get(subAttributeName).get("type");
}
}

if (metricType == null) {
metricType = "gauge";
}

return metricType;
}

@Override
public boolean match(Configuration configuration) {
if (!matchDomain(configuration)
|| !matchBean(configuration)
|| excludeMatchDomain(configuration)
|| excludeMatchBean(configuration)) {
return false;
}

try {
populateSubAttributeList(getJmxValue());
} catch (Exception e) {
return false;
}

return matchAttribute(configuration);//TODO && !excludeMatchAttribute(configuration);
}

private boolean matchSubAttribute(Filter params, String subAttributeName, boolean matchOnEmpty) {
if ((params.getAttribute() instanceof LinkedHashMap<?, ?>)
&& ((LinkedHashMap<String, Object>) (params.getAttribute())).containsKey(subAttributeName)) {
return true;
} else if ((params.getAttribute() instanceof ArrayList<?>
&& ((ArrayList<String>) (params.getAttribute())).contains(subAttributeName))) {
return true;
} else if (params.getAttribute() == null) {
return matchOnEmpty;
}
return false;
}

private boolean matchAttribute(Configuration configuration) {
if (matchSubAttribute(configuration.getInclude(), getAttributeName(), true)) {
return true;
}

Iterator<String> it1 = subAttributeList.keySet().iterator();
while (it1.hasNext()) {
String key = it1.next();
HashMap<String, HashMap<String, Object>> subSub = subAttributeList.get(key);
Iterator<String> it2 = subSub.keySet().iterator();
while (it2.hasNext()) {
String subKey = it2.next();
if (!matchSubAttribute(configuration.getInclude(), getAttributeName() + "." + subKey, true)) {
it2.remove();
}
}
if (subSub.size() <= 0) {
it1.remove();
}
}

return subAttributeList.size() > 0;
}
}
58 changes: 57 additions & 1 deletion src/test/java/org/datadog/jmxfetch/SimpleTestJavaApp.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
package org.datadog.jmxfetch;

import javax.management.openmbean.CompositeData;
import javax.management.openmbean.CompositeDataSupport;
import javax.management.openmbean.CompositeType;
import javax.management.openmbean.OpenDataException;
import javax.management.openmbean.OpenType;
import javax.management.openmbean.SimpleType;
import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
@@ -30,12 +39,18 @@ public class SimpleTestJavaApp implements SimpleTestJavaAppMBean {
private final HashMap<String, Integer> hashmap = new HashMap<String, Integer>();
private final Object object1337 = new Double(13.37);
private final BigDecimal numberBig = new BigDecimal(123456788901234567890.0);

private final TabularData tabulardata;
private final CompositeType compositetype;

SimpleTestJavaApp() {
hashmap.put("thisis0", 0);
hashmap.put("thisis10", 10);
hashmap.put("thisiscounter", 0);
compositetype = buildCompositeType();
tabulardata = buildTabularType();
if (tabulardata != null) {
tabulardata.put(buildCompositeData(1));
}
}

public int getShouldBe100() {
@@ -111,4 +126,45 @@ public float getPrimitiveFloat(){
public Float getInstanceFloat(){
return instanceFloat;
}

private TabularData buildTabularType() {
try {
CompositeType rowType = buildCompositeType();
TabularType tabularType = new TabularType("myTabularType", "My tabular type", rowType,
new String[]{"foo"});
return new TabularDataSupport(tabularType);
} catch (OpenDataException e) {
return null;
}
}

private CompositeType buildCompositeType() {
try {
return new CompositeType("myCompositeType", "My composite type",
new String[]{"foo", "bar", "toto"},
new String[]{"Description of `foo`", "Description of `bar`", "Description of `toto`"},
new OpenType[]{SimpleType.STRING, SimpleType.INTEGER, SimpleType.STRING});
} catch (OpenDataException e) {
return null;
}
}

private CompositeData buildCompositeData(Integer i) {
try {
return new CompositeDataSupport(compositetype,
new String[]{"foo", "bar", "toto"},
new Object[]{i.toString(), i, "tata"});
} catch (OpenDataException e) {
return null;
}
}

public void populateTabularData(int count) {
tabulardata.clear();
for (Integer i = 1; i <= count; i++) {
tabulardata.put(buildCompositeData(i));
}
}

public TabularData getTabulardata() { return tabulardata; }
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.datadog.jmxfetch;

import javax.management.openmbean.TabularData;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
@@ -36,4 +37,5 @@ public interface SimpleTestJavaAppMBean {

Float getInstanceFloat();

TabularData getTabulardata();
}
27 changes: 21 additions & 6 deletions src/test/java/org/datadog/jmxfetch/TestApp.java
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -437,7 +438,10 @@ public void testApp() throws Exception {
run();
LinkedList<HashMap<String, Object>> metrics = getMetrics();

assertEquals(27, metrics.size()); // 27 = 13 metrics from java.lang + the 5 gauges we are explicitly collecting + the 9 gauges that is implicitly collected, see jmx.yaml in the test/resources folder
// 28 = 13 metrics from java.lang + the 5 gauges we are explicitly collecting + 9 gauges implicitly collected
// + 1 multi-value, see jmx.yaml in the test/resources folder
assertEquals(28, metrics.size());


// We test for the presence and the value of the metrics we want to collect
List<String> commonTags = Arrays.asList(
@@ -459,12 +463,17 @@ 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("foo:1", "toto:tata"), 7);

assertCoverage();

// We run a second collection. The counter should now be present
run();
metrics = getMetrics();
assertEquals(29, metrics.size()); // 29 = 13 metrics from java.lang + the 5 gauges we are explicitly collecting + 9 gauges implicitly collected + 2 counter, see jmx.yaml in the test/resources folder
// 30 = 13 metrics from java.lang + the 5 gauges we are explicitly collecting + 9 gauges implicitly collected
// + 1 multi-value + 2 counter, see jmx.yaml in the test/resources folder
assertEquals(30, metrics.size());


// We test for the same metrics but this time, the counter should be here
// Previous metrics
@@ -482,6 +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("foo:1", "toto:tata"), 7);

// Counters
assertMetric("subattr.counter", 0.0, commonTags, 5);
@@ -492,10 +502,14 @@ public void testApp() throws Exception {
Thread.sleep(5000);
testApp.incrementCounter(5);
testApp.incrementHashMapCounter(5);
testApp.populateTabularData(2);

run();
metrics = getMetrics();
assertEquals(metrics.size(), 29); // 28 = 13 metrics from java.lang + the 5 gauges we are explicitly collecting + 9 gauges implicitly collected + 2 counter, see jmx.yaml in the test/resources folder
// 31 = 13 metrics from java.lang + the 5 gauges we are explicitly collecting + 9 gauges implicitly collected
// + 2 multi-value + 2 counter, see jmx.yaml in the test/resources folder
assertEquals(30, metrics.size());


// Previous metrics
assertMetric("this.is.100", 100.0, commonTags, 8);
@@ -512,10 +526,11 @@ 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", 2.0, commonTags, Arrays.asList("foo:2", "toto:tata"), 7);

// Counter
assertMetric("subattr.counter", 0.98, 1, commonTags, 5);
assertMetric("test.counter", 0.98, 1, commonTags, 5);
// Counter (verify rate metrics within range)
assertMetric("subattr.counter", 0.95, 1, commonTags, 5);
assertMetric("test.counter", 0.95, 1, commonTags, 5);
assertCoverage();
}
/**
4 changes: 2 additions & 2 deletions src/test/java/org/datadog/jmxfetch/TestCommon.java
Original file line number Diff line number Diff line change
@@ -223,15 +223,15 @@ public void assertMetric(String name, Number value, Number lowerBound, Number up
}

public void assertMetric(String name, Number value, List<String> commonTags, List<String> additionalTags, int countTags){
assertMetric(name, value, -1, -1, commonTags, additionalTags, countTags);
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);
}

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);
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);
9 changes: 9 additions & 0 deletions src/test/resources/jmx.yaml
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@ init_config:

instances:
- process_name_regex: .*surefire.*
refresh_beans: 4
name: jmx_test_instance
tags:
env: stage
@@ -40,5 +41,13 @@ instances:
alias: test.defaulted
values:
default: 32
Tabulardata.foo:
metric_type: gauge
alias: multiattr.foo
tags:
foo: $foo
toto: $toto
limit: 1
sort: desc
- include:
domain: org.datadog.jmxfetch.test