LCOV - code coverage report
Current view: top level - source/common/stats - stat_merger.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 1 1 100.0 %
Date: 2024-01-05 06:35:25 Functions: 1 1 100.0 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "envoy/stats/store.h"
       4             : 
       5             : #include "source/common/protobuf/protobuf.h"
       6             : #include "source/common/stats/symbol_table.h"
       7             : 
       8             : #include "absl/container/flat_hash_map.h"
       9             : 
      10             : namespace Envoy {
      11             : namespace Stats {
      12             : 
      13             : // Responsible for the sensible merging of two instances of the same stat from two different
      14             : // (typically hot restart parent+child) Envoy processes.
      15             : class StatMerger {
      16             : public:
      17             :   using DynamicsMap = absl::flat_hash_map<std::string, DynamicSpans>;
      18             : 
      19             :   // Holds state needed to construct StatName with mixed dynamic/symbolic
      20             :   // components, based on a map.
      21             :   class DynamicContext {
      22             :   public:
      23             :     DynamicContext(SymbolTable& symbol_table)
      24         247 :         : symbol_table_(symbol_table), symbolic_pool_(symbol_table), dynamic_pool_(symbol_table) {}
      25             : 
      26             :     /**
      27             :      * Generates a StatName with mixed dynamic/symbolic components based on
      28             :      * the string and the dynamic_map obtained from encodeSegments.
      29             :      *
      30             :      * @param name The string corresponding to the desired StatName.
      31             :      * @param map a map indicating which spans of tokens in the stat-name are dynamic.
      32             :      * @return the generated StatName, valid as long as the DynamicContext.
      33             :      */
      34             :     StatName makeDynamicStatName(const std::string& name, const DynamicsMap& map);
      35             : 
      36             :   private:
      37             :     SymbolTable& symbol_table_;
      38             :     StatNamePool symbolic_pool_;
      39             :     StatNameDynamicPool dynamic_pool_;
      40             :     SymbolTable::StoragePtr storage_ptr_;
      41             :   };
      42             : 
      43             :   StatMerger(Stats::Store& target_store);
      44             :   ~StatMerger();
      45             : 
      46             :   /**
      47             :    * Merge the values of stats_proto into stats_store. Counters are always
      48             :    * straightforward addition, while gauges default to addition but have
      49             :    * exceptions.
      50             :    *
      51             :    * @param counter_deltas map of counter changes from parent
      52             :    * @param gauges map of gauge changes from parent
      53             :    * @param dynamics information about which segments of the names are dynamic.
      54             :    */
      55             :   void mergeStats(const Protobuf::Map<std::string, uint64_t>& counter_deltas,
      56             :                   const Protobuf::Map<std::string, uint64_t>& gauges,
      57             :                   const DynamicsMap& dynamics = DynamicsMap());
      58             : 
      59             :   /**
      60             :    * Indicates that a gauge's value from the hot-restart parent should be
      61             :    * retained, combining it with the child data. By default, data is transferred
      62             :    * from parent gauges only during the hot-restart process, but the parent
      63             :    * contribution is subtracted from the child when the parent terminates. This
      64             :    * makes sense for gauges such as active connection counts, but is not
      65             :    * appropriate for server.hot_restart_generation.
      66             :    *
      67             :    * This function must be called immediately prior to destruction of the
      68             :    * StatMerger instance.
      69             :    *
      70             :    * @param gauge_name The gauge to be retained.
      71             :    */
      72             :   void retainParentGaugeValue(Stats::StatName gauge_name);
      73             : 
      74             : private:
      75             :   void mergeCounters(const Protobuf::Map<std::string, uint64_t>& counter_deltas,
      76             :                      const DynamicsMap& dynamics_map);
      77             :   void mergeGauges(const Protobuf::Map<std::string, uint64_t>& gauges,
      78             :                    const DynamicsMap& dynamics_map);
      79             : 
      80             :   StatNameHashSet parent_gauges_;
      81             :   // A stats Scope for our in-the-merging-process counters to live in. Scopes conceptually hold
      82             :   // shared_ptrs to the stats that live in them, with the question of which stats are living in a
      83             :   // given scope determined by which stat names have been accessed via that scope. E.g., if you
      84             :   // access a stat named "some.shared" directly through the ordinary store, and then access a
      85             :   // stat named "shared" in a scope configured with the prefix "some.", there is now a single
      86             :   // stat named some.shared pointed to by both. As another example, if you access the stat
      87             :   // "single" in the "some" scope, there will be a stat named "some.single" pointed to by just
      88             :   // that scope. Now, if you delete the scope, some.shared will stick around, but some.single
      89             :   // will be destroyed.
      90             :   //
      91             :   // All of that is relevant here because it is used to get a certain desired behavior.
      92             :   // Specifically, stats must be kept up to date with values from the parent throughout hot
      93             :   // restart, but once the restart completes, they must be dropped without a trace if the child has
      94             :   // not taken action (independent of the hot restart stat merging) that would lead to them getting
      95             :   // created in the store. By storing these stats in a scope (with an empty prefix), we can
      96             :   // preserve all stats throughout the hot restart. Then, when the restart completes, dropping
      97             :   // the scope will drop exactly those stats whose names have not already been accessed through
      98             :   // another store/scope.
      99             :   ScopeSharedPtr temp_scope_;
     100             : };
     101             : 
     102             : } // namespace Stats
     103             : } // namespace Envoy

Generated by: LCOV version 1.15