From f5f4649a818ca29897f081378d708033db20a984 Mon Sep 17 00:00:00 2001 From: fred zheng Date: Tue, 5 Jan 2021 04:49:58 -0800 Subject: [PATCH] skip NaN value in StatsDOutputWriter (#151) Skip `NaN` and `INF` values in StatsDOutputWriter --- .travis.yml | 1 + .../org/jmxtrans/agent/StatsDOutputWriter.java | 15 ++++++++++++--- .../jmxtrans/agent/StatsDOutputWriterTest.java | 16 ++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index ce775def..77173d81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: java sudo: false jdk: - oraclejdk8 + - openjdk11 - openjdk7 cache: directories: diff --git a/src/main/java/org/jmxtrans/agent/StatsDOutputWriter.java b/src/main/java/org/jmxtrans/agent/StatsDOutputWriter.java index 5c853ef2..31a975a9 100644 --- a/src/main/java/org/jmxtrans/agent/StatsDOutputWriter.java +++ b/src/main/java/org/jmxtrans/agent/StatsDOutputWriter.java @@ -131,6 +131,15 @@ public void writeInvocationResult(String invocationName, Object value) throws IO @Override public synchronized void writeQueryResult(String metricName, String metricType, Object value) throws IOException { + // statsd expects a number value for the metric. + // + // skip if value's string representation equals to "NaN" or "INF", which are meaningless values to statsd. + // passing the invalid values down will trigger error in downstream parsing applications. + String strValue = String.valueOf(value); + if (strValue.equals("NaN") || strValue.equals("INF")) { + return; + } + //DataDog statsd with tags (https://docs.datadoghq.com/guides/dogstatsd/), // metric.name:value|type|@sample_rate|#tag1:value,tag2 //Sysdig metric tags (https://support.sysdig.com/hc/en-us/articles/204376099-Metrics-integrations-StatsD-) @@ -142,7 +151,7 @@ public synchronized void writeQueryResult(String metricName, String metricType, .append(".") .append(metricName) .append(":") - .append(value) + .append(strValue) .append("|") .append(type) .append("|#") @@ -155,7 +164,7 @@ public synchronized void writeQueryResult(String metricName, String metricType, .append("#") .append(StringUtils2.join(Tag.convertTagsToStrings(tags), ",")) .append(":") - .append(value) + .append(strValue) .append("|") .append(type) .append("\n"); @@ -164,7 +173,7 @@ public synchronized void writeQueryResult(String metricName, String metricType, .append(".") .append(metricName) .append(":") - .append(value) + .append(strValue) .append("|") .append(type) .append("\n"); diff --git a/src/test/java/org/jmxtrans/agent/StatsDOutputWriterTest.java b/src/test/java/org/jmxtrans/agent/StatsDOutputWriterTest.java index bbd1a2db..6e32cba6 100644 --- a/src/test/java/org/jmxtrans/agent/StatsDOutputWriterTest.java +++ b/src/test/java/org/jmxtrans/agent/StatsDOutputWriterTest.java @@ -113,6 +113,22 @@ public void test_write_counter_metric_sysdig() throws IOException { } + @Test + public void test_skip_counter_with_NaN_value() throws IOException { + Map settings = new HashMap<>(); + settings.put(StatsDOutputWriter.SETTING_ROOT_PREFIX, "foo.bar"); + // No real connect is done. Config is here to please the postConstruct. + settings.put(StatsDOutputWriter.SETTING_HOST, "localhost"); + settings.put(StatsDOutputWriter.SETTING_PORT, "8125"); + + writer.postConstruct(settings); + writer.writeQueryResult("my-metric", "gauge", "NaN"); + Assert.assertNull(writer.receivedStat); + + writer.writeQueryResult("my-metric", "gauge", "INF"); + Assert.assertNull(writer.receivedStat); + } + /** * https://github.com/jmxtrans/jmxtrans-agent/issues/98 */