diff --git a/docker/Dockerfile b/docker/Dockerfile
index 1084e9fe5..2afa02bd9 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -25,6 +25,9 @@ RUN chown -R wavefront:wavefront /var/spool/wavefront-proxy
RUN mkdir -p /var/log/wavefront
RUN chown -R wavefront:wavefront /var/log/wavefront
+# Temp fix for "MONIT-41551"
+RUN apt-get remove -y wget
+
# Run the agent
EXPOSE 3878
EXPOSE 2878
diff --git a/proxy/pom.xml b/proxy/pom.xml
index 4359a5b5c..082e91cd9 100644
--- a/proxy/pom.xml
+++ b/proxy/pom.xml
@@ -284,7 +284,7 @@
io.netty
netty-bom
- 4.1.92.Final
+ 4.1.100.Final
pom
import
@@ -369,7 +369,7 @@
org.apache.avro
avro
- 1.11.0
+ 1.11.3
io.opentelemetry
diff --git a/proxy/src/main/java/com/wavefront/agent/listeners/DataDogPortUnificationHandler.java b/proxy/src/main/java/com/wavefront/agent/listeners/DataDogPortUnificationHandler.java
index 80c5c7558..73522a448 100644
--- a/proxy/src/main/java/com/wavefront/agent/listeners/DataDogPortUnificationHandler.java
+++ b/proxy/src/main/java/com/wavefront/agent/listeners/DataDogPortUnificationHandler.java
@@ -49,10 +49,10 @@
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
-import io.netty.util.CharsetUtil;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -67,7 +67,7 @@
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
-import org.apache.http.entity.StringEntity;
+import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.util.EntityUtils;
import wavefront.report.ReportPoint;
@@ -216,7 +216,8 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
AtomicInteger pointsPerRequest = new AtomicInteger();
URI uri = new URI(request.uri());
HttpResponseStatus status = HttpResponseStatus.ACCEPTED;
- String requestBody = request.content().toString(CharsetUtil.UTF_8);
+ byte[] bodyBytes = new byte[request.content().readableBytes()];
+ request.content().readBytes(bodyBytes);
if (requestRelayClient != null && requestRelayTarget != null && request.method() == POST) {
Histogram requestRelayDuration =
@@ -226,10 +227,16 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
try {
String outgoingUrl = requestRelayTarget.replaceFirst("/*$", "") + request.uri();
HttpPost outgoingRequest = new HttpPost(outgoingUrl);
- if (request.headers().contains("Content-Type")) {
- outgoingRequest.addHeader("Content-Type", request.headers().get("Content-Type"));
- }
- outgoingRequest.setEntity(new StringEntity(requestBody));
+
+ request
+ .headers()
+ .forEach(
+ header -> {
+ if (!header.getKey().equalsIgnoreCase("Content-Length"))
+ outgoingRequest.addHeader(header.getKey(), header.getValue());
+ });
+
+ outgoingRequest.setEntity(new ByteArrayEntity(bodyBytes));
if (synchronousMode) {
if (logger.isLoggable(Level.FINE)) {
logger.fine("Relaying incoming HTTP request to " + outgoingUrl);
@@ -260,8 +267,10 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
httpStatusCounterCache.get(httpStatusCode).inc();
EntityUtils.consumeQuietly(response.getEntity());
} catch (IOException e) {
- logger.warning(
- "Unable to relay request to " + requestRelayTarget + ": " + e.getMessage());
+ logger.log(
+ Level.WARNING,
+ "Unable to relay request to " + requestRelayTarget + ": " + e.getMessage(),
+ e);
Metrics.newCounter(
new TaggedMetricName("listeners", "http-relay.failed", "port", handle))
.inc();
@@ -287,8 +296,6 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
switch (path) {
case "/api/v2/series/": // Check doc's on the beginning of this file
try {
- byte[] bodyBytes = new byte[request.content().readableBytes()];
- request.content().readBytes(bodyBytes);
AgentPayload.MetricPayload obj = AgentPayload.MetricPayload.parseFrom(bodyBytes);
reportMetrics(obj, pointsPerRequest, output::append);
} catch (IOException e) {
@@ -299,6 +306,7 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
break;
case "/api/v1/series/":
try {
+ String requestBody = new String(bodyBytes, StandardCharsets.UTF_8);
status =
reportMetrics(jsonParser.readTree(requestBody), pointsPerRequest, output::append);
} catch (Exception e) {
@@ -319,6 +327,7 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
return;
}
try {
+ String requestBody = new String(bodyBytes, StandardCharsets.UTF_8);
reportChecks(jsonParser.readTree(requestBody), pointsPerRequest, output::append);
} catch (Exception e) {
status = HttpResponseStatus.BAD_REQUEST;
@@ -334,6 +343,7 @@ protected void handleHttpMessage(final ChannelHandlerContext ctx, final FullHttp
case "/intake/":
try {
+ String requestBody = new String(bodyBytes, StandardCharsets.UTF_8);
status =
processMetadataAndSystemMetrics(
jsonParser.readTree(requestBody),
diff --git a/tests/datadog/Makefile b/tests/datadog/Makefile
new file mode 100644
index 000000000..e3a7ecc6d
--- /dev/null
+++ b/tests/datadog/Makefile
@@ -0,0 +1,15 @@
+all: testDD
+
+.check-env:
+ifndef WF_SERVER
+ $(error WF_SERVER is undefined)
+endif
+ifndef WF_TOKEN
+ $(error WF_TOKEN is undefined)
+endif
+ifndef DD_API_KEY
+ $(error DD_API_KEY is undefined)
+endif
+
+testDD: .check-env
+ WF_SERVER=${WF_SERVER} WF_TOKEN=${WF_TOKEN} DD_API_KEY=${DD_API_KEY} docker compose up --build --attach wf-proxy
diff --git a/tests/datadog/README.md b/tests/datadog/README.md
new file mode 100644
index 000000000..31f4e2780
--- /dev/null
+++ b/tests/datadog/README.md
@@ -0,0 +1,25 @@
+# "DataDog Agent -> WFProxy -> DataDog" Tests
+
+## Build Proxy
+
+On Proxy repo home run:
+
+```
+MVN_ARGS="-DskipTests" make build-jar docker
+```
+
+## Run test
+
+On `tests/datadog/` run:
+
+```
+WF_SERVER=nimba \
+WF_TOKEN=XXXXX \
+DD_API_KEY=XXXX \
+make
+```
+
+## Test if is working
+
+1. Go to you WF server, and serach for a metric `docker.cpu.usage`, you shoul get some series with a `dd_agent_version=7` tag, and other with a `dd_agent_version=6` tag.
+2. Do the same on your Datadog acount (the `dd_agent_version` will not be available)
diff --git a/tests/datadog/compose.yaml b/tests/datadog/compose.yaml
new file mode 100644
index 000000000..24f6c7a0a
--- /dev/null
+++ b/tests/datadog/compose.yaml
@@ -0,0 +1,42 @@
+services:
+ wf-proxy:
+ hostname: wf-proxy
+ build: ../../docker
+ environment:
+ WAVEFRONT_URL: https://${WF_SERVER}.wavefront.com/api/
+ WAVEFRONT_TOKEN: ${WF_TOKEN}
+ WAVEFRONT_PROXY_ARGS: >
+ --dataDogJsonPorts 2879,2880
+ --dataDogProcessSystemMetrics true
+ --dataDogProcessServiceChecks true
+ --dataDogRequestRelayTarget https://api.datadoghq.com
+ --preprocessorConfigFile /tmp/preprocessor_rules.yaml
+ volumes:
+ - ${PWD}/preprocessor_rules.yaml:/tmp/preprocessor_rules.yaml
+
+ ports:
+ - "2878:2878"
+ - "2879:2879"
+ - "2880:2880"
+
+ dd-agent-7:
+ hostname: dd-agent-7
+ image: gcr.io/datadoghq/agent:7
+ environment:
+ DD_DD_URL: http://host.docker.internal:2879
+ DD_API_KEY: ${DD_API_KEY}
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - /proc/:/host/proc/:ro
+ - /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
+
+ dd-agent-6:
+ hostname: dd-agent-6
+ image: gcr.io/datadoghq/agent:6
+ environment:
+ DD_DD_URL: http://host.docker.internal:2880
+ DD_API_KEY: ${DD_API_KEY}
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro
+ - /proc/:/host/proc/:ro
+ - /sys/fs/cgroup/:/host/sys/fs/cgroup:ro
diff --git a/tests/datadog/preprocessor_rules.yaml b/tests/datadog/preprocessor_rules.yaml
new file mode 100644
index 000000000..3b50e0bf4
--- /dev/null
+++ b/tests/datadog/preprocessor_rules.yaml
@@ -0,0 +1,11 @@
+'2879':
+ - rule : ddv7
+ action : addTag
+ tag : dd_agent_version
+ value : "7"
+
+'2880':
+ - rule : ddv6
+ action : addTag
+ tag : dd_agent_version
+ value : "6"