Skip to content

Commit

Permalink
add monotonic_count support (#203)
Browse files Browse the repository at this point in the history
  • Loading branch information
arbll authored Feb 13, 2019
1 parent a702da0 commit 75ef1bf
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 2 deletions.
1 change: 1 addition & 0 deletions src/main/java/org/datadog/jmxfetch/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,7 @@ private void fixBrokenInstances(Reporter reporter) {
for (Instance instance : brokenInstanceMap.values()) {
// Clearing rates aggregator so we won't compute wrong rates if we can reconnect
reporter.clearRatesAggregator(instance.getName());
reporter.clearCountersAggregator(instance.getName());

LOGGER.warn(
"Instance "
Expand Down
38 changes: 38 additions & 0 deletions src/main/java/org/datadog/jmxfetch/reporter/Reporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public abstract class Reporter {
private HashMap<String, Integer> serviceCheckCount;
private HashMap<String, HashMap<String, HashMap<String, Object>>> ratesAggregator =
new HashMap<String, HashMap<String, HashMap<String, Object>>>();
private HashMap<String, HashMap<String, Long>> countersAggregator =
new HashMap<String, HashMap<String, Long>>();

/** Reporter constructor. */
public Reporter() {
Expand All @@ -38,18 +40,31 @@ public void clearRatesAggregator(String instanceName) {
ratesAggregator.put(instanceName, new HashMap<String, HashMap<String, Object>>());
}

/** Clears the counter aggregator for the provided instance name. */
public void clearCountersAggregator(String instanceName) {
countersAggregator.put(instanceName, new HashMap<String, Long>());
}

/** Submits the metrics in the implementing reporter. */
public void sendMetrics(
LinkedList<HashMap<String, Object>> metrics,
String instanceName,
boolean canonicalRate) {
HashMap<String, HashMap<String, Object>> instanceRatesAggregator;
HashMap<String, Long> instanceCountersAggregator;

if (ratesAggregator.containsKey(instanceName)) {
instanceRatesAggregator = ratesAggregator.get(instanceName);
} else {
instanceRatesAggregator = new HashMap<String, HashMap<String, Object>>();
}

if (countersAggregator.containsKey(instanceName)) {
instanceCountersAggregator = countersAggregator.get(instanceName);
} else {
instanceCountersAggregator = new HashMap<String, Long>();
}

int loopCounter = App.getLoopCounter();

String sendingMessage =
Expand Down Expand Up @@ -85,6 +100,28 @@ public void sendMetrics(
// rates
if ("gauge".equals(metricType) || "histogram".equals(metricType)) {
sendMetricPoint(metricType, metricName, currentValue, tags);
} else if ("monotonic_count".equals(metricType)) {
String key = generateId(metric);
if (!instanceCountersAggregator.containsKey(key)) {
instanceCountersAggregator.put(key, currentValue.longValue());
continue;
}

long oldValue = instanceCountersAggregator.get(key);
long delta = currentValue.longValue() - oldValue;

if (Double.isNaN(delta) || Double.isInfinite(delta)) {
continue;
}

instanceCountersAggregator.put(key, currentValue.longValue());

if (delta < 0) {
LOGGER.info("Counter " + metricName + " has been reset - not submitting.");
continue;
}
sendMetricPoint(metricType, metricName, delta, tags);

} else { // The metric should be 'counter'
String key = generateId(metric);
if (!instanceRatesAggregator.containsKey(key)) {
Expand Down Expand Up @@ -118,6 +155,7 @@ public void sendMetrics(
}

ratesAggregator.put(instanceName, instanceRatesAggregator);
countersAggregator.put(instanceName, instanceCountersAggregator);
}

/** Submits service check. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ protected void sendMetricPoint(
this.statsDClient.stop();
init();
}
if (metricType.equals("histogram")) {
if (metricType.equals("monotonic_count")) {
statsDClient.count(metricName, (long) value, tags);
} else if (metricType.equals("histogram")) {
statsDClient.histogram(metricName, value, tags);
} else {
statsDClient.gauge(metricName, value, tags);
Expand Down
37 changes: 36 additions & 1 deletion src/test/java/org/datadog/jmxfetch/TestApp.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
Expand Down Expand Up @@ -716,7 +717,41 @@ public void testAppCanonicalRate() throws Exception {
assertCoverage();
}

/** Test JMX Service Discovery. */
/**
* Test counts.
*/
@Test
public void testAppCount() throws Exception {
// We expose a few metrics through JMX
SimpleTestJavaApp testApp = new SimpleTestJavaApp();
registerMBean( testApp, "org.datadog.jmxfetch.test:type=SimpleTestJavaApp");

initApplication("jmx_count.yaml");

// First collection should not contain our count
run();
metrics = getMetrics();
assertEquals(13, metrics.size());

// Since our count is still equal to 0, we should report a delta equal to 0
run();
metrics = getMetrics();
assertEquals(14, metrics.size());
assertMetric("test.counter", 0, Collections.<String>emptyList(), 3);

// For the 3rd collection we increment the count to 5 so we should get a +5 delta
testApp.incrementCounter(5);
run();
metrics = getMetrics();
assertEquals(14, metrics.size());
assertMetric("test.counter", 5, Collections.<String>emptyList(), 3);

assertCoverage();
}

/**
* Test JMX Service Discovery.
* */
@Test
public void testServiceDiscovery() throws Exception {
// We expose a few metrics through JMX
Expand Down
13 changes: 13 additions & 0 deletions src/test/resources/jmx_count.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
init_config:

instances:
- process_name_regex: .*surefire.*
refresh_beans: 4
name: jmx_test_instance
conf:
- include:
domain: org.datadog.jmxfetch.test
attribute:
ShouldBeCounter:
metric_type: monotonic_count
alias: test.counter

0 comments on commit 75ef1bf

Please sign in to comment.