Skip to content

Commit 5c2d558

Browse files
cozosBo Yang
authored andcommitted
Datadog StatsD Reporter (#40)
* Datadog statsd committer * Check if yaml value is blank
1 parent dabd557 commit 5c2d558

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed

pom.xml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,5 +352,39 @@
352352
</dependency>
353353
</dependencies>
354354
</profile>
355+
<profile>
356+
<id>datadog</id>
357+
<build>
358+
<plugins>
359+
<plugin>
360+
<groupId>org.codehaus.mojo</groupId>
361+
<artifactId>build-helper-maven-plugin</artifactId>
362+
<version>3.0.0</version>
363+
<executions>
364+
<execution>
365+
<id>add-source</id>
366+
<phase>generate-sources</phase>
367+
<goals>
368+
<goal>add-source</goal>
369+
</goals>
370+
<configuration>
371+
<sources>
372+
<source>src/main/java_datadog</source>
373+
</sources>
374+
</configuration>
375+
</execution>
376+
</executions>
377+
</plugin>
378+
</plugins>
379+
</build>
380+
<dependencies>
381+
<dependency>
382+
<groupId>com.datadoghq</groupId>
383+
<artifactId>java-dogstatsd-client</artifactId>
384+
<version>2.7</version>
385+
</dependency>
386+
</dependencies>
387+
</profile>
388+
355389
</profiles>
356390
</project>
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.uber.profiling.reporters;
2+
3+
import java.util.AbstractMap;
4+
import java.util.ArrayList;
5+
import java.util.Deque;
6+
import java.util.LinkedList;
7+
import java.util.List;
8+
import java.util.Map;
9+
10+
import org.apache.commons.lang3.StringUtils;
11+
12+
import com.timgroup.statsd.NonBlockingStatsDClient;
13+
import com.timgroup.statsd.StatsDClient;
14+
import com.uber.profiling.Reporter;
15+
import com.uber.profiling.util.AgentLogger;
16+
17+
public class DatadogOutputReporter implements Reporter {
18+
private static final AgentLogger logger = AgentLogger.getLogger(DatadogOutputReporter.class.getName());
19+
20+
private StatsDClient statsdClient = null;
21+
22+
private String prefix = "";
23+
private String hostname = "localhost";
24+
private int port = 8125;
25+
26+
@Override
27+
public void report(String profilerName, Map<String, Object> metrics) {
28+
ensureStatsdConn();
29+
30+
List<Map.Entry<String, Number>> individualMetrics = new ArrayList<>();
31+
Deque<Map.Entry<String, Object>> queue = new LinkedList<>(metrics.entrySet());
32+
while (!queue.isEmpty()) {
33+
Map.Entry<String, Object> entry = queue.pollLast();
34+
String key = entry.getKey();
35+
Object value = entry.getValue();
36+
37+
if (value instanceof Number) {
38+
// If it's a number, we can record the metric as is.
39+
individualMetrics.add(new AbstractMap.SimpleEntry<>(key, (Number)value));
40+
} else if (value instanceof Map) {
41+
// If it's a map, we'll want to get individual metrics out of the map.
42+
((Map) value).forEach((nestedKey, nestedValue) -> {
43+
String newMetricName = key + "." + nestedKey;
44+
45+
if (nestedValue instanceof Number) {
46+
individualMetrics.add(new AbstractMap.SimpleEntry<>(newMetricName, (Number)nestedValue));
47+
} else {
48+
queue.push(new AbstractMap.SimpleEntry<>(newMetricName, nestedValue));
49+
}
50+
});
51+
}
52+
}
53+
54+
for (Map.Entry<String, Number> entry : individualMetrics) {
55+
this.statsdClient.gauge(entry.getKey(), entry.getValue().doubleValue());
56+
}
57+
}
58+
59+
@Override
60+
public void close() {
61+
synchronized (this) {
62+
this.statsdClient.close();
63+
this.statsdClient = null;
64+
}
65+
}
66+
67+
private void ensureStatsdConn() {
68+
synchronized (this) {
69+
if (statsdClient == null) {
70+
statsdClient = new NonBlockingStatsDClient(prefix, hostname, port);
71+
}
72+
}
73+
}
74+
75+
// properties from yaml file
76+
@Override
77+
public void updateArguments(Map<String, List<String>> connectionProperties) {
78+
for (Map.Entry<String, List<String>> entry : connectionProperties.entrySet()) {
79+
String key = entry.getKey();
80+
List<String> value = entry.getValue();
81+
if (StringUtils.isNotEmpty(key) && value != null && !value.isEmpty()) {
82+
String stringValue = value.get(0);
83+
if (StringUtils.isBlank(stringValue)) {
84+
break;
85+
}
86+
87+
switch (key) {
88+
case "datadog.statsd.prefix":
89+
logger.info("Got value for prefix = " + stringValue);
90+
this.prefix = stringValue;
91+
break;
92+
case "datadog.statsd.hostname":
93+
logger.info("Got value for hostname = " + stringValue);
94+
this.hostname = stringValue;
95+
break;
96+
case "datadog.statsd.port":
97+
logger.info("Got value for port = " + stringValue);
98+
this.port = Integer.parseInt(stringValue);
99+
break;
100+
}
101+
}
102+
}
103+
}
104+
}
105+

0 commit comments

Comments
 (0)