Lines
100 %
Functions
#pragma once
#include <chrono>
#include <cstdint>
#include <string>
#include "envoy/http/codes.h"
#include "envoy/http/header_map.h"
#include "envoy/stats/scope.h"
#include "source/common/common/thread.h"
#include "source/common/stats/symbol_table.h"
namespace Envoy {
namespace Http {
struct CodeStats::ResponseStatInfo {
Stats::Scope& global_scope_;
Stats::Scope& cluster_scope_;
Stats::StatName prefix_;
uint64_t response_status_code_;
bool internal_request_;
Stats::StatName request_vhost_name_;
Stats::StatName request_vcluster_name_;
Stats::StatName request_route_name_;
Stats::StatName from_zone_;
Stats::StatName to_zone_;
bool upstream_canary_;
};
struct CodeStats::ResponseTimingInfo {
std::chrono::milliseconds response_time_;
class CodeStatsImpl : public CodeStats {
public:
explicit CodeStatsImpl(Stats::SymbolTable& symbol_table);
// CodeStats
void chargeBasicResponseStat(Stats::Scope& scope, Stats::StatName prefix, Code response_code,
bool exclude_http_code_stats) const override;
void chargeResponseStat(const ResponseStatInfo& info,
void chargeResponseTiming(const ResponseTimingInfo& info) const override;
private:
friend class CodeStatsTest;
void writeCategory(const ResponseStatInfo& info, Stats::StatName rq_group,
Stats::StatName rq_code, Stats::StatName category) const;
void incCounter(Stats::Scope& scope, const Stats::StatNameVec& names) const;
void incCounter(Stats::Scope& scope, Stats::StatName a, Stats::StatName b) const;
void recordHistogram(Stats::Scope& scope, const Stats::StatNameVec& names,
Stats::Histogram::Unit unit, uint64_t count) const;
Stats::StatName upstreamRqGroup(Code response_code) const;
Stats::StatName upstreamRqStatName(Code response_code) const;
mutable Stats::StatNamePool stat_name_pool_;
Stats::SymbolTable& symbol_table_;
const Stats::StatName canary_;
const Stats::StatName empty_; // Used for the group-name for invalid http codes.
const Stats::StatName external_;
const Stats::StatName internal_;
const Stats::StatName upstream_;
const Stats::StatName upstream_rq_1xx_;
const Stats::StatName upstream_rq_2xx_;
const Stats::StatName upstream_rq_3xx_;
const Stats::StatName upstream_rq_4xx_;
const Stats::StatName upstream_rq_5xx_;
const Stats::StatName upstream_rq_unknown_;
const Stats::StatName upstream_rq_completed_;
const Stats::StatName upstream_rq_time_;
const Stats::StatName vcluster_;
const Stats::StatName vhost_;
const Stats::StatName route_;
const Stats::StatName zone_;
// Use an array of atomic pointers to hold StatNameStorage objects for
// every conceivable HTTP response code. In the hot-path we'll reference
// these with a null-check, and if we need to allocate a symbol for a
// new code, we'll take a mutex to avoid duplicate allocations and
// subsequent leaks. This is similar in principle to a ReaderMutexLock,
// but should be faster, as ReaderMutexLocks appear to be too expensive for
// fine-grained controls. Another option would be to use a lock per
// stat-name, which might have similar performance to atomics with default
// barrier policy.
//
// We don't allocate these all up front during construction because
// SymbolTable greedily encodes the first 128 names it discovers in one
// byte. We don't want those high-value single-byte codes to go to fully
// enumerating the 4 prefixes combined with HTTP codes that are seldom used,
// so we allocate these on demand.
// There can be multiple symbol tables in a server. The one passed into the
// Codes constructor should be the same as the one passed to
// Stats::ThreadLocalStore. Note that additional symbol tables can be created
// from IsolatedStoreImpl's default constructor.
// The Codes object is global to the server.
static constexpr uint32_t NumHttpCodes = 500;
static constexpr uint32_t HttpCodeOffset = 100; // code 100 is at index 0.
mutable Thread::AtomicPtrArray<const uint8_t, NumHttpCodes,
Thread::AtomicPtrAllocMode::DoNotDelete>
rc_stat_names_;
/**
* General utility routines for HTTP codes.
*/
class CodeUtility {
* Convert an HTTP response code to a descriptive string.
* @param code supplies the code to convert.
* @return const char* the string.
static const char* toString(Code code);
static bool is1xx(uint64_t code) { return code >= 100 && code < 200; }
static bool is2xx(uint64_t code) { return code >= 200 && code < 300; }
static bool is3xx(uint64_t code) { return code >= 300 && code < 400; }
static bool is4xx(uint64_t code) { return code >= 400 && code < 500; }
static bool is5xx(uint64_t code) { return code >= 500 && code < 600; }
static bool isGatewayError(uint64_t code) { return code >= 502 && code < 505; }
static std::string groupStringForResponseCode(Code response_code);
} // namespace Http
} // namespace Envoy