LCOV - code coverage report
Current view: top level - source/server/admin - stats_render.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 0 2 0.0 %
Date: 2024-01-05 06:35:25 Functions: 0 2 0.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "envoy/common/optref.h"
       4             : #include "envoy/server/admin.h"
       5             : #include "envoy/stats/stats.h"
       6             : 
       7             : #include "source/common/buffer/buffer_impl.h"
       8             : #include "source/common/json/json_streamer.h"
       9             : #include "source/server/admin/stats_params.h"
      10             : #include "source/server/admin/utils.h"
      11             : 
      12             : namespace Envoy {
      13             : namespace Server {
      14             : 
      15             : // Abstract class for rendering stats. Every method is called "generate"
      16             : // differing only by the data type, to facilitate templatized call-sites.
      17             : //
      18             : // There are currently Json and Text implementations of this interface, and in
      19             : // #19546 an HTML version will be added to provide a hierarchical view.
      20             : class StatsRender {
      21             : public:
      22           0 :   virtual ~StatsRender() = default;
      23             : 
      24             :   // Writes a fragment for a numeric value, for counters and gauges.
      25             :   virtual void generate(Buffer::Instance& response, const std::string& name, uint64_t value) PURE;
      26             : 
      27             :   // Writes a json fragment for a textual value, for text readouts.
      28             :   virtual void generate(Buffer::Instance& response, const std::string& name,
      29             :                         const std::string& value) PURE;
      30             : 
      31             :   // Writes a histogram value.
      32             :   virtual void generate(Buffer::Instance& response, const std::string& name,
      33             :                         const Stats::ParentHistogram& histogram) PURE;
      34             : 
      35             :   // Completes rendering any buffered data.
      36             :   virtual void finalize(Buffer::Instance& response) PURE;
      37             : 
      38             :   // Indicates that no stats for a particular type have been found.
      39           0 :   virtual void noStats(Buffer::Instance&, absl::string_view) {}
      40             : };
      41             : 
      42             : // Implements the Render interface for simple textual representation of stats.
      43             : class StatsTextRender : public StatsRender {
      44             : public:
      45             :   explicit StatsTextRender(const StatsParams& params);
      46             : 
      47             :   // StatsRender
      48             :   void generate(Buffer::Instance& response, const std::string& name, uint64_t value) override;
      49             :   void generate(Buffer::Instance& response, const std::string& name,
      50             :                 const std::string& value) override;
      51             :   void generate(Buffer::Instance& response, const std::string& name,
      52             :                 const Stats::ParentHistogram& histogram) override;
      53             :   void finalize(Buffer::Instance&) override;
      54             : 
      55             : private:
      56             :   // Computes disjoint buckets as text and adds them to the response buffer.
      57             :   void addDisjointBuckets(const std::string& name, const Stats::ParentHistogram& histogram,
      58             :                           Buffer::Instance& response);
      59             : 
      60             :   void addDetail(const std::vector<Stats::ParentHistogram::Bucket>& buckets,
      61             :                  Buffer::Instance& response);
      62             : 
      63             :   const Utility::HistogramBucketsMode histogram_buckets_mode_;
      64             : };
      65             : 
      66             : // Implements the Render interface for json output.
      67             : class StatsJsonRender : public StatsRender {
      68             : public:
      69             :   StatsJsonRender(Http::ResponseHeaderMap& response_headers, Buffer::Instance& response,
      70             :                   const StatsParams& params);
      71             : 
      72             :   // StatsRender
      73             :   void generate(Buffer::Instance& response, const std::string& name, uint64_t value) override;
      74             :   void generate(Buffer::Instance& response, const std::string& name,
      75             :                 const std::string& value) override;
      76             :   void generate(Buffer::Instance&, const std::string& name,
      77             :                 const Stats::ParentHistogram& histogram) override;
      78             :   void finalize(Buffer::Instance& response) override;
      79             : 
      80             :   /**
      81             :    * Streams the supported percentiles into a JSON array. Note that no histogram
      82             :    * context is provided for this; this is a static property of the binary.
      83             :    *
      84             :    * @param array the json streaming array array to stream into.
      85             :    */
      86             :   static void populateSupportedPercentiles(Json::Streamer::Array& array);
      87             : 
      88             :   /**
      89             :    * Streams detail about the provided histogram into the provided JSON map.
      90             :    *
      91             :    * @param name the name of the histogram (usually the same as histogram.name(),
      92             :    *             but is passed in explicitly because it may already have been
      93             :    *             computed when filtering stats, and it is somewhat expensive
      94             :    *             to compute the name.
      95             :    * @param histogram the histogram to stream
      96             :    * @param map the json map to stream into.
      97             :    *
      98             :    */
      99             :   static void generateHistogramDetail(const std::string& name,
     100             :                                       const Stats::ParentHistogram& histogram,
     101             :                                       Json::Streamer::Map& map);
     102             : 
     103             : private:
     104             :   // Collects the buckets from the specified histogram.
     105             :   void collectBuckets(const std::string& name, const Stats::ParentHistogram& histogram,
     106             :                       const std::vector<uint64_t>& interval_buckets,
     107             :                       const std::vector<uint64_t>& cumulative_buckets);
     108             : 
     109             :   static void populateBucketsVerbose(const std::vector<Stats::ParentHistogram::Bucket>& buckets,
     110             :                                      Json::Streamer::Map& map);
     111             :   void renderHistogramStart();
     112             :   static void populatePercentiles(const Stats::ParentHistogram& histogram,
     113             :                                   Json::Streamer::Map& map);
     114             : 
     115             :   // This function irons out an API mistake made when defining the StatsRender
     116             :   // interface. The issue is that callers can provide a response buffer when
     117             :   // constructing a StatsRender instance, but can switch to a different response
     118             :   // buffer when rendering specific values.
     119             :   //
     120             :   // The problem comes with JSON histograms where each histogram is nested in a
     121             :   // structure with other histograms, so if you switch buffers you need to
     122             :   // ensure the pending bytes in the previous buffer is fully
     123             :   // drained. Unfortunately this buffer-switching is used in practice.
     124             :   void drainIfNeeded(Buffer::Instance& response);
     125             : 
     126             :   const Utility::HistogramBucketsMode histogram_buckets_mode_;
     127             :   std::string name_buffer_;  // Used for Json::sanitize for names.
     128             :   std::string value_buffer_; // Used for Json::sanitize for text-readout values.
     129             :   bool histograms_initialized_{false};
     130             : 
     131             :   // Captures the hierarchy of maps and arrays used to render scalar stats and
     132             :   // histograms in various formats. This is separated in its own structure to
     133             :   // facilitate clearing these structures in the reverse order of how they were
     134             :   // created during finalize().
     135             :   //
     136             :   // Another option to consider: flattening the member variables of JsonContext
     137             :   // into StatsJsonRender, and ensure that Render objects are always destructed
     138             :   // before the output stream is considered complete.
     139             :   struct JsonContext {
     140             :     explicit JsonContext(Buffer::Instance& response);
     141             :     Json::Streamer streamer_;
     142             :     Json::Streamer::MapPtr stats_map_;
     143             :     Json::Streamer::ArrayPtr stats_array_;
     144             :     Json::Streamer::MapPtr histogram_map1_;
     145             :     Json::Streamer::MapPtr histogram_map2_;
     146             :     Json::Streamer::ArrayPtr histogram_array_;
     147             :   };
     148             :   std::unique_ptr<JsonContext> json_;
     149             :   Buffer::Instance& response_;
     150             : };
     151             : 
     152             : } // namespace Server
     153             : } // namespace Envoy

Generated by: LCOV version 1.15