From aef47d25b21a17abf87745b32cf8cdf59928e87b Mon Sep 17 00:00:00 2001 From: Thibault Nadin Date: Thu, 6 Aug 2026 11:07:42 +0200 Subject: [PATCH 1/2] Submit eval metrics through the shared HTTP clients --- .../datadog/trace/llmobs/EvalProcessingWorker.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java b/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java index 15e207428f2..643f001e0f7 100644 --- a/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java +++ b/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java @@ -53,6 +53,7 @@ public EvalProcessingWorker( Headers headers; HttpUrl submissionUrl; + OkHttpClient httpClient; if (isAgentless) { submissionUrl = HttpUrl.get( @@ -63,6 +64,7 @@ public EvalProcessingWorker( + "/" + EVAL_METRIC_API_PATH); headers = Headers.of(DD_API_KEY_HEADER_NAME, config.getApiKey()); + httpClient = sco.getIntakeHttpClient(); } else { submissionUrl = HttpUrl.get( @@ -70,10 +72,14 @@ public EvalProcessingWorker( + DDAgentFeaturesDiscovery.V2_EVP_PROXY_ENDPOINT + EVAL_METRIC_API_PATH); headers = Headers.of(EVP_SUBDOMAIN_HEADER_NAME, EVAL_METRIC_API_DOMAIN); + // For a UDS or named pipe Agent, `agentUrl` is only a placeholder and the socket transport + // lives on the shared client, so a client of our own would never reach the Agent. + httpClient = sco.agentHttpClient; } EvalSerializingHandler serializingHandler = - new EvalSerializingHandler(queue, flushInterval, timeUnit, submissionUrl, headers); + new EvalSerializingHandler( + queue, flushInterval, timeUnit, submissionUrl, headers, httpClient); this.serializerThread = newAgentThread(LLMOBS_EVALS_PROCESSOR, serializingHandler); } @@ -116,12 +122,13 @@ public EvalSerializingHandler( final long flushInterval, final TimeUnit timeUnit, final HttpUrl submissionUrl, - final Headers headers) { + final Headers headers, + final OkHttpClient httpClient) { this.queue = queue; this.moshi = new Moshi.Builder().add(LLMObsEval.class, new LLMObsEval.Adapter()).build(); this.evalJsonAdapter = moshi.adapter(LLMObsEval.Request.class); - this.httpClient = new OkHttpClient(); + this.httpClient = httpClient; this.submissionUrl = submissionUrl; this.headers = headers; From 7153e5c0a16284d90dfc715019f1df7b34ee9f16 Mon Sep 17 00:00:00 2001 From: Thibault Nadin Date: Tue, 11 Aug 2026 14:16:59 +0200 Subject: [PATCH 2/2] Keep HTTPS eval submissions off the cleartext intake client --- .../java/datadog/trace/llmobs/EvalProcessingWorker.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java b/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java index 643f001e0f7..486364c531e 100644 --- a/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java +++ b/dd-java-agent/agent-llmobs/src/main/java/datadog/trace/llmobs/EvalProcessingWorker.java @@ -64,7 +64,13 @@ public EvalProcessingWorker( + "/" + EVAL_METRIC_API_PATH); headers = Headers.of(DD_API_KEY_HEADER_NAME, config.getApiKey()); - httpClient = sco.getIntakeHttpClient(); + // The shared intake client is cleartext-only once the flag is enabled for another backend + // intake, and OkHttp then rejects our HTTPS submissions, so keep a client of our own rather + // than share one that cannot reach the eval intake. + httpClient = + config.isForceClearTextHttpForIntakeClient() + ? OkHttpUtils.buildHttpClient(submissionUrl, sco.httpClientTimeout) + : sco.getIntakeHttpClient(); } else { submissionUrl = HttpUrl.get(