LCOV - code coverage report
Current view: top level - source/common/http - codes.h (source / functions) Hit Total Coverage
Test: coverage.dat Lines: 5 6 83.3 %
Date: 2024-01-05 06:35:25 Functions: 5 6 83.3 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include <chrono>
       4             : #include <cstdint>
       5             : #include <string>
       6             : 
       7             : #include "envoy/http/codes.h"
       8             : #include "envoy/http/header_map.h"
       9             : #include "envoy/stats/scope.h"
      10             : 
      11             : #include "source/common/common/thread.h"
      12             : #include "source/common/stats/symbol_table.h"
      13             : 
      14             : namespace Envoy {
      15             : namespace Http {
      16             : 
      17             : struct CodeStats::ResponseStatInfo {
      18             :   Stats::Scope& global_scope_;
      19             :   Stats::Scope& cluster_scope_;
      20             :   Stats::StatName prefix_;
      21             :   uint64_t response_status_code_;
      22             :   bool internal_request_;
      23             :   Stats::StatName request_vhost_name_;
      24             :   Stats::StatName request_vcluster_name_;
      25             :   Stats::StatName request_route_name_;
      26             :   Stats::StatName from_zone_;
      27             :   Stats::StatName to_zone_;
      28             :   bool upstream_canary_;
      29             : };
      30             : 
      31             : struct CodeStats::ResponseTimingInfo {
      32             :   Stats::Scope& global_scope_;
      33             :   Stats::Scope& cluster_scope_;
      34             :   Stats::StatName prefix_;
      35             :   std::chrono::milliseconds response_time_;
      36             :   bool upstream_canary_;
      37             :   bool internal_request_;
      38             :   Stats::StatName request_vhost_name_;
      39             :   Stats::StatName request_vcluster_name_;
      40             :   Stats::StatName request_route_name_;
      41             :   Stats::StatName from_zone_;
      42             :   Stats::StatName to_zone_;
      43             : };
      44             : 
      45             : class CodeStatsImpl : public CodeStats {
      46             : public:
      47             :   explicit CodeStatsImpl(Stats::SymbolTable& symbol_table);
      48             : 
      49             :   // CodeStats
      50             :   void chargeBasicResponseStat(Stats::Scope& scope, Stats::StatName prefix, Code response_code,
      51             :                                bool exclude_http_code_stats) const override;
      52             :   void chargeResponseStat(const ResponseStatInfo& info,
      53             :                           bool exclude_http_code_stats) const override;
      54             :   void chargeResponseTiming(const ResponseTimingInfo& info) const override;
      55             : 
      56             : private:
      57             :   friend class CodeStatsTest;
      58             : 
      59             :   void writeCategory(const ResponseStatInfo& info, Stats::StatName rq_group,
      60             :                      Stats::StatName rq_code, Stats::StatName category) const;
      61             :   void incCounter(Stats::Scope& scope, const Stats::StatNameVec& names) const;
      62             :   void incCounter(Stats::Scope& scope, Stats::StatName a, Stats::StatName b) const;
      63             :   void recordHistogram(Stats::Scope& scope, const Stats::StatNameVec& names,
      64             :                        Stats::Histogram::Unit unit, uint64_t count) const;
      65             : 
      66             :   Stats::StatName upstreamRqGroup(Code response_code) const;
      67             :   Stats::StatName upstreamRqStatName(Code response_code) const;
      68             : 
      69             :   mutable Stats::StatNamePool stat_name_pool_;
      70             :   Stats::SymbolTable& symbol_table_;
      71             : 
      72             :   const Stats::StatName canary_;
      73             :   const Stats::StatName empty_; // Used for the group-name for invalid http codes.
      74             :   const Stats::StatName external_;
      75             :   const Stats::StatName internal_;
      76             :   const Stats::StatName upstream_;
      77             :   const Stats::StatName upstream_rq_1xx_;
      78             :   const Stats::StatName upstream_rq_2xx_;
      79             :   const Stats::StatName upstream_rq_3xx_;
      80             :   const Stats::StatName upstream_rq_4xx_;
      81             :   const Stats::StatName upstream_rq_5xx_;
      82             :   const Stats::StatName upstream_rq_unknown_;
      83             :   const Stats::StatName upstream_rq_completed_;
      84             :   const Stats::StatName upstream_rq_time_;
      85             :   const Stats::StatName vcluster_;
      86             :   const Stats::StatName vhost_;
      87             :   const Stats::StatName route_;
      88             :   const Stats::StatName zone_;
      89             : 
      90             :   // Use an array of atomic pointers to hold StatNameStorage objects for
      91             :   // every conceivable HTTP response code. In the hot-path we'll reference
      92             :   // these with a null-check, and if we need to allocate a symbol for a
      93             :   // new code, we'll take a mutex to avoid duplicate allocations and
      94             :   // subsequent leaks. This is similar in principle to a ReaderMutexLock,
      95             :   // but should be faster, as ReaderMutexLocks appear to be too expensive for
      96             :   // fine-grained controls. Another option would be to use a lock per
      97             :   // stat-name, which might have similar performance to atomics with default
      98             :   // barrier policy.
      99             :   //
     100             :   // We don't allocate these all up front during construction because
     101             :   // SymbolTable greedily encodes the first 128 names it discovers in one
     102             :   // byte. We don't want those high-value single-byte codes to go to fully
     103             :   // enumerating the 4 prefixes combined with HTTP codes that are seldom used,
     104             :   // so we allocate these on demand.
     105             :   //
     106             :   // There can be multiple symbol tables in a server. The one passed into the
     107             :   // Codes constructor should be the same as the one passed to
     108             :   // Stats::ThreadLocalStore. Note that additional symbol tables can be created
     109             :   // from IsolatedStoreImpl's default constructor.
     110             :   //
     111             :   // The Codes object is global to the server.
     112             : 
     113             :   static constexpr uint32_t NumHttpCodes = 500;
     114             :   static constexpr uint32_t HttpCodeOffset = 100; // code 100 is at index 0.
     115             :   mutable Thread::AtomicPtrArray<const uint8_t, NumHttpCodes,
     116             :                                  Thread::AtomicPtrAllocMode::DoNotDelete>
     117             :       rc_stat_names_;
     118             : };
     119             : 
     120             : /**
     121             :  * General utility routines for HTTP codes.
     122             :  */
     123             : class CodeUtility {
     124             : public:
     125             :   /**
     126             :    * Convert an HTTP response code to a descriptive string.
     127             :    * @param code supplies the code to convert.
     128             :    * @return const char* the string.
     129             :    */
     130             :   static const char* toString(Code code);
     131             : 
     132        1047 :   static bool is1xx(uint64_t code) { return code >= 100 && code < 200; }
     133         561 :   static bool is2xx(uint64_t code) { return code >= 200 && code < 300; }
     134         379 :   static bool is3xx(uint64_t code) { return code >= 300 && code < 400; }
     135         177 :   static bool is4xx(uint64_t code) { return code >= 400 && code < 500; }
     136         484 :   static bool is5xx(uint64_t code) { return code >= 500 && code < 600; }
     137             : 
     138           0 :   static bool isGatewayError(uint64_t code) { return code >= 502 && code < 505; }
     139             : 
     140             :   static std::string groupStringForResponseCode(Code response_code);
     141             : };
     142             : 
     143             : } // namespace Http
     144             : } // namespace Envoy

Generated by: LCOV version 1.15