LCOV - code coverage report
Current view: top level - datadog - datadog_agent_config.cpp (source / functions) Hit Total Coverage
Test: filtered.info Lines: 90 92 97.8 %
Date: 2024-01-03 20:30:12 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "datadog_agent_config.h"
       2             : 
       3             : #include <algorithm>
       4             : #include <chrono>
       5             : #include <cstddef>
       6             : 
       7             : #include "default_http_client.h"
       8             : #include "environment.h"
       9             : #include "parse_util.h"
      10             : #include "threaded_event_scheduler.h"
      11             : 
      12             : namespace datadog {
      13             : namespace tracing {
      14             : 
      15         614 : Expected<HTTPClient::URL> DatadogAgentConfig::parse(StringView input) {
      16         614 :   const StringView separator = "://";
      17         614 :   const auto after_scheme = std::search(input.begin(), input.end(),
      18             :                                         separator.begin(), separator.end());
      19         614 :   if (after_scheme == input.end()) {
      20           1 :     std::string message;
      21           1 :     message += "Datadog Agent URL is missing the \"://\" separator: \"";
      22           1 :     append(message, input);
      23           1 :     message += '\"';
      24           1 :     return Error{Error::URL_MISSING_SEPARATOR, std::move(message)};
      25           1 :   }
      26             : 
      27         613 :   const StringView scheme = range(input.begin(), after_scheme);
      28             :   const StringView supported[] = {"http", "https", "unix", "http+unix",
      29         613 :                                   "https+unix"};
      30             :   const auto found =
      31         613 :       std::find(std::begin(supported), std::end(supported), scheme);
      32         613 :   if (found == std::end(supported)) {
      33           1 :     std::string message;
      34           1 :     message += "Unsupported URI scheme \"";
      35           1 :     append(message, scheme);
      36           1 :     message += "\" in Datadog Agent URL \"";
      37           1 :     append(message, input);
      38           1 :     message += "\". The following are supported:";
      39           6 :     for (const auto& supported_scheme : supported) {
      40           5 :       message += ' ';
      41           5 :       append(message, supported_scheme);
      42             :     }
      43           1 :     return Error{Error::URL_UNSUPPORTED_SCHEME, std::move(message)};
      44           1 :   }
      45             : 
      46             :   const StringView authority_and_path =
      47         612 :       range(after_scheme + separator.size(), input.end());
      48             :   // If the scheme is for unix domain sockets, then there's no way to
      49             :   // distinguish the path-to-socket from the path-to-resource.  Some
      50             :   // implementations require that the forward slashes in the path-to-socket
      51             :   // are URL-encoded.  However, URLs that we will be parsing designate the
      52             :   // location of the Datadog Agent service, and so do not have a resource
      53             :   // location.  Thus, if the scheme is for a unix domain socket, assume that
      54             :   // the entire part after the "://" is the path to the socket, and that
      55             :   // there is no resource path.
      56         612 :   if (scheme == "unix" || scheme == "http+unix" || scheme == "https+unix") {
      57           4 :     if (authority_and_path.empty() || authority_and_path[0] != '/') {
      58           1 :       std::string message;
      59             :       message +=
      60             :           "Unix domain socket paths for Datadog Agent must be absolute, i.e. "
      61             :           "must begin with a "
      62           1 :           "\"/\". The path \"";
      63           1 :       append(message, authority_and_path);
      64           1 :       message += "\" is not absolute. Error occurred for URL: \"";
      65           1 :       append(message, input);
      66           1 :       message += '\"';
      67           2 :       return Error{Error::URL_UNIX_DOMAIN_SOCKET_PATH_NOT_ABSOLUTE,
      68           2 :                    std::move(message)};
      69           1 :     }
      70           6 :     return HTTPClient::URL{std::string(scheme), std::string(authority_and_path),
      71           3 :                            ""};
      72             :   }
      73             : 
      74             :   // The scheme is either "http" or "https".  This means that the part after
      75             :   // the "://" could be <resource>/<path>, e.g. "localhost:8080/api/v1".
      76             :   // Again, though, we're only parsing URLs that designate the location of
      77             :   // the Datadog Agent service, and so they will not have a resource
      78             :   // location.  Still, let's parse it properly.
      79             :   const auto after_authority =
      80         608 :       std::find(authority_and_path.begin(), authority_and_path.end(), '/');
      81        3040 :   return HTTPClient::URL{
      82             :       std::string(scheme),
      83        1216 :       std::string(range(authority_and_path.begin(), after_authority)),
      84        1824 :       std::string(range(after_authority, authority_and_path.end()))};
      85             : }
      86             : 
      87         619 : Expected<FinalizedDatadogAgentConfig> finalize_config(
      88             :     const DatadogAgentConfig& config, const std::shared_ptr<Logger>& logger,
      89             :     const Clock& clock) {
      90         619 :   FinalizedDatadogAgentConfig result;
      91             : 
      92         619 :   result.clock = clock;
      93             : 
      94         619 :   if (!config.http_client) {
      95         208 :     result.http_client = default_http_client(logger, clock);
      96             :     // `default_http_client` might return a `Curl` instance depending on how
      97             :     // this library was built.  If it returns `nullptr`, then there's no
      98             :     // built-in default, and so the user must provide a value.
      99         208 :     if (!result.http_client) {
     100           0 :       return Error{Error::DATADOG_AGENT_NULL_HTTP_CLIENT,
     101           0 :                    "DatadogAgent: HTTP client cannot be null."};
     102             :     }
     103             :   } else {
     104         411 :     result.http_client = config.http_client;
     105             :   }
     106             : 
     107         619 :   if (!config.event_scheduler) {
     108         208 :     result.event_scheduler = std::make_shared<ThreadedEventScheduler>();
     109             :   } else {
     110         411 :     result.event_scheduler = config.event_scheduler;
     111             :   }
     112             : 
     113         619 :   if (config.flush_interval_milliseconds <= 0) {
     114           4 :     return Error{Error::DATADOG_AGENT_INVALID_FLUSH_INTERVAL,
     115             :                  "DatadogAgent: Flush interval must be a positive number of "
     116           2 :                  "milliseconds."};
     117             :   }
     118         617 :   result.flush_interval =
     119         617 :       std::chrono::milliseconds(config.flush_interval_milliseconds);
     120             : 
     121         617 :   int rc_poll_interval_seconds =
     122         617 :       config.remote_configuration_poll_interval_seconds;
     123             : 
     124         617 :   if (auto raw_rc_poll_interval_value =
     125         617 :           lookup(environment::DD_REMOTE_CONFIG_POLL_INTERVAL_SECONDS)) {
     126           2 :     auto res = parse_int(*raw_rc_poll_interval_value, 10);
     127           2 :     if (auto error = res.if_error()) {
     128           2 :       return error->with_prefix(
     129           1 :           "DatadogAgent: Remote Configuration poll interval error ");
     130             :     }
     131             : 
     132           1 :     rc_poll_interval_seconds = *res;
     133           2 :   }
     134             : 
     135         616 :   if (rc_poll_interval_seconds <= 0) {
     136           4 :     return Error{Error::DATADOG_AGENT_INVALID_REMOTE_CONFIG_POLL_INTERVAL,
     137             :                  "DatadogAgent: Remote Configuration poll interval must be a "
     138           2 :                  "positive number of seconds."};
     139             :   }
     140             : 
     141         614 :   result.remote_configuration_poll_interval =
     142         614 :       std::chrono::seconds(rc_poll_interval_seconds);
     143             : 
     144         614 :   auto env_host = lookup(environment::DD_AGENT_HOST);
     145         614 :   auto env_port = lookup(environment::DD_TRACE_AGENT_PORT);
     146             : 
     147         614 :   std::string configured_url = config.url;
     148         614 :   if (auto url_env = lookup(environment::DD_TRACE_AGENT_URL)) {
     149           5 :     assign(configured_url, *url_env);
     150         609 :   } else if (env_host || env_port) {
     151           5 :     configured_url.clear();
     152           5 :     configured_url += "http://";
     153           5 :     append(configured_url, env_host.value_or("localhost"));
     154           5 :     configured_url += ':';
     155           5 :     append(configured_url, env_port.value_or("8126"));
     156             :   }
     157             : 
     158         614 :   auto url = config.parse(configured_url);
     159         614 :   if (auto* error = url.if_error()) {
     160           3 :     return std::move(*error);
     161             :   }
     162         611 :   result.url = *url;
     163             : 
     164         611 :   return result;
     165         619 : }
     166             : 
     167             : }  // namespace tracing
     168             : }  // namespace datadog

Generated by: LCOV version 1.16