LCOV - code coverage report
Current view: top level - source/extensions/tracers/xray - tracer.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 47 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 33 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <string>
       4             : #include <utility>
       5             : #include <vector>
       6             : 
       7             : #include "envoy/common/time.h"
       8             : #include "envoy/tracing/tracer.h"
       9             : 
      10             : #include "source/common/common/empty_string.h"
      11             : #include "source/common/common/hex.h"
      12             : #include "source/common/common/random_generator.h"
      13             : #include "source/common/http/codes.h"
      14             : #include "source/common/protobuf/utility.h"
      15             : #include "source/common/tracing/common_values.h"
      16             : #include "source/common/tracing/trace_context_impl.h"
      17             : #include "source/extensions/tracers/xray/daemon_broker.h"
      18             : #include "source/extensions/tracers/xray/sampling_strategy.h"
      19             : #include "source/extensions/tracers/xray/xray_configuration.h"
      20             : 
      21             : #include "absl/container/flat_hash_map.h"
      22             : #include "absl/strings/string_view.h"
      23             : 
      24             : namespace Envoy {
      25             : namespace Extensions {
      26             : namespace Tracers {
      27             : namespace XRay {
      28             : 
      29             : constexpr absl::string_view SpanClientIp = "client_ip";
      30             : constexpr absl::string_view SpanXForwardedFor = "x_forwarded_for";
      31             : constexpr absl::string_view Subsegment = "subsegment";
      32             : 
      33             : const Tracing::TraceContextHandler& xRayTraceHeader();
      34             : const Tracing::TraceContextHandler& xForwardedForHeader();
      35             : 
      36             : class Span : public Tracing::Span, Logger::Loggable<Logger::Id::config> {
      37             : public:
      38             :   /**
      39             :    * Creates a new Span.
      40             :    *
      41             :    * @param time_source A time source to get the span end time
      42             :    * @param random random generator for generating unique child span ids
      43             :    * @param broker Facilitates communication with the X-Ray daemon.
      44             :    */
      45             :   Span(TimeSource& time_source, Random::RandomGenerator& random, DaemonBroker& broker)
      46             :       : time_source_(time_source), random_(random), broker_(broker),
      47           0 :         id_(Hex::uint64ToHex(random_.random())) {}
      48             : 
      49             :   /**
      50             :    * Sets the Span's trace ID.
      51             :    */
      52           0 :   void setTraceId(absl::string_view trace_id) { trace_id_ = std::string(trace_id); };
      53             : 
      54             :   /**
      55             :    * Gets the Span's trace ID.
      56             :    */
      57           0 :   const std::string& traceId() const { return trace_id_; }
      58             : 
      59             :   /**
      60             :    * Completes the current span, serialize it and send it to the X-Ray daemon.
      61             :    */
      62             :   void finishSpan() override;
      63             : 
      64             :   /**
      65             :    * Sets the current operation name on the Span.
      66             :    * This information will be included in the X-Ray span's metadata.
      67             :    */
      68           0 :   void setOperation(absl::string_view operation) override {
      69           0 :     operation_name_ = std::string(operation);
      70           0 :   }
      71             : 
      72             :   /**
      73             :    * Sets the current direction on the Span.
      74             :    * This information will be included in the X-Ray span's annotation.
      75             :    */
      76           0 :   void setDirection(absl::string_view direction) { direction_ = std::string(direction); }
      77             : 
      78             :   /**
      79             :    * Sets the name of the Span.
      80             :    */
      81           0 :   void setName(absl::string_view name) { name_ = std::string(name); }
      82             : 
      83             :   /**
      84             :    * Sets the origin of the Span.
      85             :    */
      86           0 :   void setOrigin(absl::string_view origin) { origin_ = std::string(origin); }
      87             : 
      88             :   /**
      89             :    * Gets the origin of the Span.
      90             :    */
      91           0 :   const std::string& origin() { return origin_; }
      92             : 
      93             :   /**
      94             :    * Adds a key-value pair to either the Span's annotations or metadata.
      95             :    * An allowlist of keys are added to the annotations, everything else is added to the metadata.
      96             :    */
      97             :   void setTag(absl::string_view name, absl::string_view value) override;
      98             : 
      99             :   /**
     100             :    * Sets the ID of the parent segment. This is different from the Trace ID.
     101             :    * The parent ID is used if the request originated from an instrumented application.
     102             :    * For more information see:
     103             :    * https://docs.aws.amazon.com/xray/latest/devguide/xray-concepts.html#xray-concepts-tracingheader
     104             :    */
     105           0 :   void setParentId(absl::string_view parent_segment_id) {
     106           0 :     parent_segment_id_ = std::string(parent_segment_id);
     107           0 :   }
     108             : 
     109             :   /**
     110             :    * Sets the type of the Span. In X-Ray, an independent subsegment has a type of "subsegment".
     111             :    * https://docs.aws.amazon.com/xray/latest/devguide/xray-api-segmentdocuments.html#api-segmentdocuments-subsegments
     112             :    */
     113           0 :   void setType(absl::string_view type) { type_ = std::string(type); }
     114             : 
     115             :   /**
     116             :    * Sets the aws metadata field of the Span.
     117             :    */
     118           0 :   void setAwsMetadata(const absl::flat_hash_map<std::string, ProtobufWkt::Value>& aws_metadata) {
     119           0 :     aws_metadata_ = aws_metadata;
     120           0 :   }
     121             : 
     122             :   /*
     123             :    * Adds to the http request annotation field of the Span.
     124             :    */
     125           0 :   void addToHttpRequestAnnotations(absl::string_view key, const ProtobufWkt::Value& value) {
     126           0 :     http_request_annotations_.emplace(std::string(key), value);
     127           0 :   }
     128             : 
     129             :   /*
     130             :    * Check if key is set in http request annotation field of a Span.
     131             :    */
     132           0 :   bool hasKeyInHttpRequestAnnotations(absl::string_view key) {
     133           0 :     return http_request_annotations_.find(key) != http_request_annotations_.end();
     134           0 :   }
     135             : 
     136             :   /*
     137             :    * Adds to the http response annotation field of the Span.
     138             :    */
     139           0 :   void addToHttpResponseAnnotations(absl::string_view key, const ProtobufWkt::Value& value) {
     140           0 :     http_response_annotations_.emplace(std::string(key), value);
     141           0 :   }
     142             : 
     143             :   /**
     144             :    * Sets the recording start time of the traced operation/request.
     145             :    */
     146           0 :   void setStartTime(Envoy::SystemTime start_time) { start_time_ = start_time; }
     147             : 
     148             :   /**
     149             :    * Marks the span as either "sampled" or "not-sampled".
     150             :    * By default, Spans are "sampled".
     151             :    * This is handy in cases where the sampling decision has already been determined either by Envoy
     152             :    * or by a downstream service.
     153             :    */
     154           0 :   void setSampled(bool sampled) override { sampled_ = sampled; };
     155             : 
     156             :   /**
     157             :    * Sets the server error as true for the traced operation/request.
     158             :    */
     159           0 :   void setServerError() { server_error_ = true; };
     160             : 
     161             :   /**
     162             :    * Sets the http response status code for the traced operation/request.
     163             :    */
     164           0 :   void setResponseStatusCode(uint64_t status_code) { response_status_code_ = status_code; };
     165             : 
     166             :   /**
     167             :    * Adds X-Ray trace header to the set of outgoing headers.
     168             :    */
     169             :   void injectContext(Tracing::TraceContext& trace_context,
     170             :                      const Upstream::HostDescriptionConstSharedPtr&) override;
     171             : 
     172             :   /**
     173             :    * Gets the start time of this Span.
     174             :    */
     175           0 :   Envoy::SystemTime startTime() const { return start_time_; }
     176             : 
     177             :   /**
     178             :    * Gets this Span's ID.
     179             :    */
     180           0 :   const std::string& id() const { return id_; }
     181             : 
     182             :   /**
     183             :    * Gets this Span's parent ID.
     184             :    */
     185           0 :   const std::string& parentId() const { return parent_segment_id_; }
     186             : 
     187             :   /**
     188             :    * Gets this Span's direction.
     189             :    */
     190           0 :   const std::string& direction() const { return direction_; }
     191             : 
     192             :   /**
     193             :    * Gets this Span's type.
     194             :    */
     195           0 :   const std::string& type() const { return type_; }
     196             : 
     197             :   /**
     198             :    * Gets this Span's name.
     199             :    */
     200           0 :   const std::string& name() const { return name_; }
     201             : 
     202             :   /**
     203             :    * Determines whether this span is sampled.
     204             :    */
     205           0 :   bool sampled() const { return sampled_; }
     206             : 
     207             :   /**
     208             :    * Determines if a server error occurred (response status code was 5XX Server Error).
     209             :    */
     210           0 :   bool serverError() const { return server_error_; }
     211             : 
     212             :   /**
     213             :    * Determines if a client error occurred (response status code was 4XX Client Error).
     214             :    */
     215           0 :   bool clientError() const { return Http::CodeUtility::is4xx(response_status_code_); }
     216             : 
     217             :   /**
     218             :    * Determines if a request was throttled (response status code was 429 Too Many Requests).
     219             :    */
     220           0 :   bool isThrottled() const {
     221           0 :     return Http::Code::TooManyRequests == static_cast<Http::Code>(response_status_code_);
     222           0 :   }
     223             : 
     224             :   /**
     225             :    * Not used by X-Ray because the Spans are "logged" (serialized) to the X-Ray daemon.
     226             :    */
     227           0 :   void log(Envoy::SystemTime, const std::string&) override {}
     228             : 
     229             :   // X-Ray doesn't support baggage, so noop these OpenTracing functions.
     230           0 :   void setBaggage(absl::string_view, absl::string_view) override {}
     231           0 :   std::string getBaggage(absl::string_view) override { return EMPTY_STRING; }
     232             : 
     233             :   // TODO: This method is unimplemented for X-Ray.
     234           0 :   std::string getTraceIdAsHex() const override { return EMPTY_STRING; };
     235             : 
     236             :   /**
     237             :    * Creates a child span.
     238             :    * In X-Ray terms this creates a sub-segment and sets its parent ID to the current span's ID.
     239             :    * @param operation_name The span of the child span.
     240             :    * @param start_time The time at which this child span started.
     241             :    */
     242             :   Tracing::SpanPtr spawnChild(const Tracing::Config&, const std::string& operation_name,
     243             :                               Envoy::SystemTime start_time) override;
     244             : 
     245             : private:
     246             :   Envoy::TimeSource& time_source_;
     247             :   Random::RandomGenerator& random_;
     248             :   DaemonBroker& broker_;
     249             :   Envoy::SystemTime start_time_;
     250             :   std::string operation_name_;
     251             :   std::string direction_;
     252             :   std::string id_;
     253             :   std::string trace_id_;
     254             :   std::string parent_segment_id_;
     255             :   std::string name_;
     256             :   std::string origin_;
     257             :   std::string type_;
     258             :   absl::flat_hash_map<std::string, ProtobufWkt::Value> aws_metadata_;
     259             :   absl::flat_hash_map<std::string, ProtobufWkt::Value> http_request_annotations_;
     260             :   absl::flat_hash_map<std::string, ProtobufWkt::Value> http_response_annotations_;
     261             :   absl::flat_hash_map<std::string, std::string> custom_annotations_;
     262             :   bool server_error_{false};
     263             :   uint64_t response_status_code_{0};
     264             :   bool sampled_{true};
     265             : };
     266             : 
     267             : using SpanPtr = std::unique_ptr<Span>;
     268             : 
     269             : class Tracer {
     270             : public:
     271             :   Tracer(absl::string_view segment_name, absl::string_view origin,
     272             :          const absl::flat_hash_map<std::string, ProtobufWkt::Value>& aws_metadata,
     273             :          DaemonBrokerPtr daemon_broker, TimeSource& time_source, Random::RandomGenerator& random)
     274             :       : segment_name_(segment_name), origin_(origin), aws_metadata_(aws_metadata),
     275           0 :         daemon_broker_(std::move(daemon_broker)), time_source_(time_source), random_(random) {}
     276             :   /**
     277             :    * Starts a tracing span for X-Ray
     278             :    */
     279             :   Tracing::SpanPtr startSpan(const Tracing::Config&, const std::string& operation_name,
     280             :                              Envoy::SystemTime start_time,
     281             :                              const absl::optional<XRayHeader>& xray_header,
     282             :                              const absl::optional<absl::string_view> client_ip);
     283             :   /**
     284             :    * Creates a Span that is marked as not-sampled.
     285             :    * This is useful when the sampling decision is done in Envoy's X-Ray and we want to avoid
     286             :    * overruling that decision in the upstream service in case that service itself uses X-Ray for
     287             :    * tracing. Also at the same time if X-Ray header is set then preserve its value.
     288             :    */
     289             :   XRay::SpanPtr createNonSampledSpan(const absl::optional<XRayHeader>& xray_header) const;
     290             : 
     291             : private:
     292             :   const std::string segment_name_;
     293             :   const std::string origin_;
     294             :   const absl::flat_hash_map<std::string, ProtobufWkt::Value> aws_metadata_;
     295             :   const DaemonBrokerPtr daemon_broker_;
     296             :   Envoy::TimeSource& time_source_;
     297             :   Random::RandomGenerator& random_;
     298             : };
     299             : 
     300             : using TracerPtr = std::unique_ptr<Tracer>;
     301             : 
     302             : } // namespace XRay
     303             : } // namespace Tracers
     304             : } // namespace Extensions
     305             : } // namespace Envoy

Generated by: LCOV version 1.15