LCOV - code coverage report
Current view: top level - source/extensions/tracers/datadog - agent_http_client.cc (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 82 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 8 0.0 %

          Line data    Source code
       1             : #include "source/extensions/tracers/datadog/agent_http_client.h"
       2             : 
       3             : #include <cstddef>
       4             : #include <cstdint>
       5             : #include <memory>
       6             : #include <string>
       7             : 
       8             : #include "source/common/common/assert.h"
       9             : #include "source/common/http/message_impl.h"
      10             : #include "source/common/http/utility.h"
      11             : #include "source/extensions/tracers/datadog/dict_util.h"
      12             : #include "source/extensions/tracers/datadog/tracer_stats.h"
      13             : 
      14             : #include "absl/strings/str_format.h"
      15             : #include "datadog/dict_reader.h"
      16             : #include "datadog/dict_writer.h"
      17             : #include "datadog/error.h"
      18             : #include "datadog/json.hpp"
      19             : 
      20             : namespace Envoy {
      21             : namespace Extensions {
      22             : namespace Tracers {
      23             : namespace Datadog {
      24             : 
      25             : AgentHTTPClient::AgentHTTPClient(Upstream::ClusterManager& cluster_manager,
      26             :                                  const std::string& cluster, const std::string& reference_host,
      27             :                                  TracerStats& stats)
      28             :     : collector_cluster_(cluster_manager, cluster), cluster_(cluster),
      29           0 :       reference_host_(reference_host), stats_(stats) {}
      30             : 
      31           0 : AgentHTTPClient::~AgentHTTPClient() {
      32           0 :   for (const auto& [request_ptr, _] : handlers_) {
      33           0 :     RELEASE_ASSERT(request_ptr,
      34           0 :                    "null Http::AsyncClient::Request* in handler map of Datadog::AgentHTTPClient");
      35           0 :     request_ptr->cancel();
      36           0 :   }
      37           0 : }
      38             : 
      39             : // datadog::tracing::HTTPClient
      40             : 
      41             : datadog::tracing::Expected<void> AgentHTTPClient::post(const URL& url, HeadersSetter set_headers,
      42             :                                                        std::string body,
      43             :                                                        ResponseHandler on_response,
      44           0 :                                                        ErrorHandler on_error) {
      45           0 :   ENVOY_LOG(debug, "flushing traces");
      46             : 
      47           0 :   auto message = std::make_unique<Http::RequestMessageImpl>();
      48           0 :   Http::RequestHeaderMap& headers = message->headers();
      49           0 :   headers.setReferenceMethod(Http::Headers::get().MethodValues.Post);
      50           0 :   headers.setReferencePath(url.path);
      51           0 :   headers.setReferenceHost(reference_host_);
      52             : 
      53           0 :   RequestHeaderWriter writer{message->headers()};
      54           0 :   set_headers(writer);
      55             : 
      56           0 :   message->body().add(body);
      57           0 :   ENVOY_LOG(debug, "submitting trace(s) to {} with payload size {}", url.path, body.size());
      58             : 
      59           0 :   if (!collector_cluster_.threadLocalCluster().has_value()) {
      60           0 :     ENVOY_LOG(debug, "collector cluster '{}' does not exist", cluster_);
      61           0 :     stats_.reports_skipped_no_cluster_.inc();
      62           0 :     return datadog::tracing::nullopt;
      63           0 :   }
      64             : 
      65           0 :   Http::AsyncClient::Request* request =
      66           0 :       collector_cluster_.threadLocalCluster()->get().httpAsyncClient().send(
      67           0 :           std::move(message), *this,
      68           0 :           Http::AsyncClient::RequestOptions().setTimeout(std::chrono::milliseconds(1000)));
      69           0 :   if (!request) {
      70           0 :     stats_.reports_failed_.inc();
      71           0 :     return datadog::tracing::Error{datadog::tracing::Error::ENVOY_HTTP_CLIENT_FAILURE,
      72           0 :                                    "Failed to create request."};
      73           0 :   }
      74             : 
      75           0 :   handlers_.emplace(request, Handlers{std::move(on_response), std::move(on_error)});
      76           0 :   return datadog::tracing::nullopt;
      77           0 : }
      78             : 
      79           0 : void AgentHTTPClient::drain(std::chrono::steady_clock::time_point) {}
      80             : 
      81           0 : nlohmann::json AgentHTTPClient::config_json() const {
      82           0 :   return nlohmann::json::object({
      83           0 :       {"type", "Envoy::Extensions::Tracers::Datadog::AgentHTTPClient"},
      84           0 :   });
      85           0 : }
      86             : 
      87             : // Http::AsyncClient::Callbacks
      88             : 
      89             : void AgentHTTPClient::onSuccess(const Http::AsyncClient::Request& request,
      90           0 :                                 Http::ResponseMessagePtr&& response) {
      91           0 :   const std::uint64_t status = Http::Utility::getResponseStatus(response->headers());
      92           0 :   if (status != std::uint64_t(Http::Code::OK)) {
      93           0 :     stats_.reports_dropped_.inc();
      94           0 :   } else {
      95           0 :     ENVOY_LOG(debug, "traces successfully submitted to datadog agent");
      96           0 :     stats_.reports_sent_.inc();
      97           0 :   }
      98             : 
      99           0 :   auto found = handlers_.find(const_cast<Http::AsyncClient::Request*>(&request));
     100           0 :   if (found == handlers_.end()) {
     101           0 :     ENVOY_LOG(debug, "request at address 0x{} is not in the map of {} Handlers objects",
     102           0 :               absl::StrFormat("%p", &request), handlers_.size());
     103           0 :     return;
     104           0 :   }
     105             : 
     106           0 :   Handlers& handlers = found->second;
     107           0 :   ResponseHeaderReader reader{response->headers()};
     108           0 :   handlers.on_response(status, reader, response->bodyAsString());
     109             : 
     110           0 :   handlers_.erase(found);
     111           0 : }
     112             : 
     113             : void AgentHTTPClient::onFailure(const Http::AsyncClient::Request& request,
     114           0 :                                 Http::AsyncClient::FailureReason reason) {
     115           0 :   auto found = handlers_.find(const_cast<Http::AsyncClient::Request*>(&request));
     116             :   // If the request failed to start, then `post` never even registered the request.
     117           0 :   if (found == handlers_.end()) {
     118           0 :     return;
     119           0 :   }
     120             : 
     121           0 :   stats_.reports_failed_.inc();
     122             : 
     123           0 :   Handlers& handlers = found->second;
     124           0 :   std::string message = "Failed to send request to Datadog Agent: ";
     125           0 :   switch (reason) {
     126           0 :   case Http::AsyncClient::FailureReason::Reset:
     127           0 :     message += "The stream has been reset.";
     128           0 :     break;
     129           0 :   default:
     130           0 :     message += "Unknown error.";
     131           0 :   }
     132           0 :   handlers.on_error(datadog::tracing::Error{datadog::tracing::Error::ENVOY_HTTP_CLIENT_FAILURE,
     133           0 :                                             std::move(message)});
     134             : 
     135           0 :   handlers_.erase(found);
     136           0 : }
     137             : 
     138           0 : void AgentHTTPClient::onBeforeFinalizeUpstreamSpan(Tracing::Span&, const Http::ResponseHeaderMap*) {
     139           0 : }
     140             : 
     141             : } // namespace Datadog
     142             : } // namespace Tracers
     143             : } // namespace Extensions
     144             : } // namespace Envoy

Generated by: LCOV version 1.15