LCOV - code coverage report
Current view: top level - source/extensions/common/tap - tap_config_base.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 28 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 10 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <fstream>
       4             : 
       5             : #include "envoy/buffer/buffer.h"
       6             : #include "envoy/config/tap/v3/common.pb.h"
       7             : #include "envoy/data/tap/v3/common.pb.h"
       8             : #include "envoy/data/tap/v3/wrapper.pb.h"
       9             : 
      10             : #include "source/extensions/common/matcher/matcher.h"
      11             : #include "source/extensions/common/tap/tap.h"
      12             : 
      13             : namespace Envoy {
      14             : namespace Extensions {
      15             : namespace Common {
      16             : namespace Tap {
      17             : 
      18             : using Matcher = Envoy::Extensions::Common::Matcher::Matcher;
      19             : using MatcherPtr = Envoy::Extensions::Common::Matcher::MatcherPtr;
      20             : 
      21             : /**
      22             :  * Common utilities for tapping.
      23             :  */
      24             : class Utility {
      25             : public:
      26             :   /**
      27             :    * Add body data to a tapped body message, taking into account the maximum bytes to buffer.
      28             :    * @param output_body supplies the body message to buffer to.
      29             :    * @param max_buffered_bytes supplies the maximum bytes to store, if truncation occurs the
      30             :    *        truncation flag will be set.
      31             :    * @param data supplies the data to buffer.
      32             :    * @param buffer_start_offset supplies the offset within data to start buffering.
      33             :    * @param buffer_length_to_copy supplies the length of the data to buffer.
      34             :    * @return whether the buffered data was truncated or not.
      35             :    */
      36             :   static bool addBufferToProtoBytes(envoy::data::tap::v3::Body& output_body,
      37             :                                     uint32_t max_buffered_bytes, const Buffer::Instance& data,
      38             :                                     uint32_t buffer_start_offset, uint32_t buffer_length_to_copy);
      39             : 
      40             :   /**
      41             :    * Swap body as bytes to body as string if necessary in a trace wrapper.
      42             :    */
      43             :   static void bodyBytesToString(envoy::data::tap::v3::TraceWrapper& trace,
      44             :                                 envoy::config::tap::v3::OutputSink::Format sink_format);
      45             : 
      46             :   /**
      47             :    * Trim a container that contains buffer raw slices so that the slices start at an offset and
      48             :    * only contain a specific length. No slices are removed from the container, but their length
      49             :    * may be reduced to 0.
      50             :    * TODO(mattklein123): This is split out to ease testing and also because we should ultimately
      51             :    * move this directly into the buffer API. I would rather wait until the new buffer code merges
      52             :    * before we do that.
      53             :    */
      54           0 :   template <typename T> static void trimSlices(T& slices, uint32_t start_offset, uint32_t length) {
      55           0 :     for (auto& slice : slices) {
      56           0 :       const uint32_t start_offset_trim = std::min<uint32_t>(start_offset, slice.len_);
      57           0 :       slice.len_ -= start_offset_trim;
      58           0 :       start_offset -= start_offset_trim;
      59           0 :       if (slice.mem_ != nullptr) {
      60           0 :         slice.mem_ = static_cast<char*>(slice.mem_) + start_offset_trim;
      61           0 :       }
      62             : 
      63           0 :       const uint32_t final_length = std::min<uint32_t>(length, slice.len_);
      64           0 :       slice.len_ = final_length;
      65           0 :       length -= final_length;
      66           0 :     }
      67           0 :   }
      68             : };
      69             : 
      70             : /**
      71             :  * Base class for all tap configurations.
      72             :  * TODO(mattklein123): This class will handle common functionality such as rate limiting, etc.
      73             :  */
      74             : class TapConfigBaseImpl : public virtual TapConfig {
      75             : public:
      76             :   // A wrapper for a per tap sink handle and trace submission. If in the future we support
      77             :   // multiple sinks we can easily do it here.
      78             :   class PerTapSinkHandleManagerImpl : public PerTapSinkHandleManager {
      79             :   public:
      80             :     PerTapSinkHandleManagerImpl(TapConfigBaseImpl& parent, uint64_t trace_id)
      81             :         : parent_(parent),
      82           0 :           handle_(parent.sink_to_use_->createPerTapSinkHandle(trace_id, parent.sink_type_)) {}
      83             : 
      84             :     // PerTapSinkHandleManager
      85             :     void submitTrace(TraceWrapperPtr&& trace) override;
      86             : 
      87             :   private:
      88             :     TapConfigBaseImpl& parent_;
      89             :     PerTapSinkHandlePtr handle_;
      90             :   };
      91             : 
      92             :   // TapConfig
      93           0 :   PerTapSinkHandleManagerPtr createPerTapSinkHandleManager(uint64_t trace_id) override {
      94           0 :     return std::make_unique<PerTapSinkHandleManagerImpl>(*this, trace_id);
      95           0 :   }
      96           0 :   uint32_t maxBufferedRxBytes() const override { return max_buffered_rx_bytes_; }
      97           0 :   uint32_t maxBufferedTxBytes() const override { return max_buffered_tx_bytes_; }
      98           0 :   Matcher::MatchStatusVector createMatchStatusVector() const override {
      99           0 :     return Matcher::MatchStatusVector(matchers_.size());
     100           0 :   }
     101             :   const Matcher& rootMatcher() const override;
     102           0 :   bool streaming() const override { return streaming_; }
     103             : 
     104             : protected:
     105             :   TapConfigBaseImpl(const envoy::config::tap::v3::TapConfig& proto_config,
     106             :                     Common::Tap::Sink* admin_streamer, SinkContext context);
     107             : 
     108             : private:
     109             :   // This is the default setting for both RX/TX max buffered bytes. (This means that per tap, the
     110             :   // maximum amount that can be buffered is 2x this value).
     111             :   static constexpr uint32_t DefaultMaxBufferedBytes = 1024;
     112             : 
     113             :   const uint32_t max_buffered_rx_bytes_;
     114             :   const uint32_t max_buffered_tx_bytes_;
     115             :   const bool streaming_;
     116             :   Sink* sink_to_use_;
     117             :   SinkPtr sink_;
     118             :   envoy::config::tap::v3::OutputSink::Format sink_format_;
     119             :   envoy::config::tap::v3::OutputSink::OutputSinkTypeCase sink_type_;
     120             :   std::vector<MatcherPtr> matchers_;
     121             : };
     122             : 
     123             : /**
     124             :  * A tap sink that writes each tap trace to a discrete output file.
     125             :  */
     126             : class FilePerTapSink : public Sink {
     127             : public:
     128           0 :   FilePerTapSink(const envoy::config::tap::v3::FilePerTapSink& config) : config_(config) {}
     129             : 
     130             :   // Sink
     131             :   PerTapSinkHandlePtr
     132             :   createPerTapSinkHandle(uint64_t trace_id,
     133           0 :                          envoy::config::tap::v3::OutputSink::OutputSinkTypeCase) override {
     134           0 :     return std::make_unique<FilePerTapSinkHandle>(*this, trace_id);
     135           0 :   }
     136             : 
     137             : private:
     138             :   struct FilePerTapSinkHandle : public PerTapSinkHandle {
     139             :     FilePerTapSinkHandle(FilePerTapSink& parent, uint64_t trace_id)
     140           0 :         : parent_(parent), trace_id_(trace_id) {}
     141             : 
     142             :     // PerTapSinkHandle
     143             :     void submitTrace(TraceWrapperPtr&& trace,
     144             :                      envoy::config::tap::v3::OutputSink::Format format) override;
     145             : 
     146             :     FilePerTapSink& parent_;
     147             :     const uint64_t trace_id_;
     148             :     std::ofstream output_file_;
     149             :   };
     150             : 
     151             :   const envoy::config::tap::v3::FilePerTapSink config_;
     152             : };
     153             : 
     154             : } // namespace Tap
     155             : } // namespace Common
     156             : } // namespace Extensions
     157             : } // namespace Envoy

Generated by: LCOV version 1.15