Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions source/common/http/codes.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ class CodeStatsImpl : public CodeStats {
bool exclude_http_code_stats) const override;
void chargeResponseTiming(const ResponseTimingInfo& info) const override;

static constexpr uint32_t HttpCodeOffset = 100; // code 100 is at index 0.
static constexpr uint32_t NumHttpCodes = 500;
private:
friend class CodeStatsTest;

Expand Down Expand Up @@ -110,8 +112,6 @@ class CodeStatsImpl : public CodeStats {
//
// 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_;
Expand All @@ -134,6 +134,7 @@ class CodeUtility {
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 isValid(uint64_t code) { return code >= 100 && code < 600; }

static bool isGatewayError(uint64_t code) { return code >= 502 && code < 505; }

Expand Down
42 changes: 41 additions & 1 deletion source/common/http/conn_manager_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#include "envoy/type/v3/percent.pb.h"

#include "source/common/http/date_provider.h"
#include "source/common/http/codes.h"
#include "source/common/common/enum_to_int.h"
#include "source/common/local_reply/local_reply.h"
#include "source/common/network/utility.h"
#include "source/common/stats/symbol_table.h"
Expand Down Expand Up @@ -71,9 +73,15 @@ namespace Http {
COUNTER(downstream_rq_header_timeout) \
COUNTER(downstream_rq_too_large) \
COUNTER(downstream_rq_total) \
COUNTER(downstream_rq_unknown) \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of this counter?

COUNTER(downstream_rq_tx_reset) \
COUNTER(downstream_rq_max_duration_reached) \
COUNTER(downstream_rq_ws_on_non_ws_route) \
COUNTER(via_upstream_downstream_rq_1xx) \
COUNTER(via_upstream_downstream_rq_2xx) \
COUNTER(via_upstream_downstream_rq_3xx) \
COUNTER(via_upstream_downstream_rq_4xx) \
COUNTER(via_upstream_downstream_rq_5xx) \
COUNTER(rs_too_large) \
GAUGE(downstream_cx_active, Accumulate) \
GAUGE(downstream_cx_http1_active, Accumulate) \
Expand All @@ -96,17 +104,49 @@ struct ConnectionManagerNamedStats {
};

struct ConnectionManagerStats {
// Use a single constexpr for array size.
static constexpr uint32_t kHttpCodeOffset = Envoy::Http::CodeStatsImpl::HttpCodeOffset;
static constexpr uint32_t kArraySize = Envoy::Http::CodeStatsImpl::NumHttpCodes - kHttpCodeOffset;

ConnectionManagerStats(ConnectionManagerNamedStats&& named_stats, const std::string& prefix,
Stats::Scope& scope)
: named_(std::move(named_stats)), prefix_(prefix),
prefix_stat_name_storage_(prefix, scope.symbolTable()), scope_(scope) {}
prefix_stat_name_storage_(prefix, scope.symbolTable()), scope_(scope),
stat_name_pool_(scope.symbolTable()) {
// Optionally pre-initialize common codes.
downstreamRqCounter(Http::Code::OK);
downstreamRqCounter(Http::Code::NotFound);
downstreamRqCounter(Http::Code::ServiceUnavailable);
}

Stats::StatName prefixStatName() const { return prefix_stat_name_storage_.statName(); }

// Returns a reference to the counter for a given HTTP code, using atomic pointer array
Stats::Counter& downstreamRqCounter(Http::Code code) const {
const uint32_t rc_index = static_cast<uint32_t>(code) - kHttpCodeOffset;
if (rc_index >= kArraySize) {
return named_.downstream_rq_unknown_;
}

auto* counter_ptr = downstream_rc_counters_.get(rc_index, [this, code]() -> Stats::Counter* {
return &scope_.counterFromStatName(
stat_name_pool_.add(absl::StrCat(prefix_, "downstream_rq_", enumToInt(code)))
);
});
if (counter_ptr == nullptr) {
ENVOY_LOG_MISC(critical, "Null counter for HTTP code {}, using downstream_rq_unknown", enumToInt(code));
return named_.downstream_rq_unknown_;
}
return *counter_ptr;
}

ConnectionManagerNamedStats named_;
std::string prefix_;
Stats::StatNameManagedStorage prefix_stat_name_storage_;
Stats::Scope& scope_;

mutable Stats::StatNamePool stat_name_pool_;
mutable Thread::AtomicPtrArray<Stats::Counter, kArraySize, Thread::AtomicPtrAllocMode::DoNotDelete> downstream_rc_counters_;
};

/**
Expand Down
18 changes: 18 additions & 0 deletions source/common/http/conn_manager_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,9 @@ void ConnectionManagerImpl::ActiveStream::chargeStats(const ResponseHeaderMap& h
return;
}

if (CodeUtility::isValid(response_code)) {
connection_manager_.stats_.downstreamRqCounter(static_cast<Http::Code>(response_code)).inc();
}
connection_manager_.stats_.named_.downstream_rq_completed_.inc();
connection_manager_.listener_stats_.downstream_rq_completed_.inc();
if (CodeUtility::is1xx(response_code)) {
Expand All @@ -1036,6 +1039,21 @@ void ConnectionManagerImpl::ActiveStream::chargeStats(const ResponseHeaderMap& h
connection_manager_.stats_.named_.downstream_rq_5xx_.inc();
connection_manager_.listener_stats_.downstream_rq_5xx_.inc();
}

if (response_code_details.has_value() &&
response_code_details == Envoy::StreamInfo::ResponseCodeDetails::get().ViaUpstream) {
if (CodeUtility::is1xx(response_code)) {
connection_manager_.stats_.named_.via_upstream_downstream_rq_1xx_.inc();
} else if (CodeUtility::is2xx(response_code)) {
connection_manager_.stats_.named_.via_upstream_downstream_rq_2xx_.inc();
} else if (CodeUtility::is3xx(response_code)) {
connection_manager_.stats_.named_.via_upstream_downstream_rq_3xx_.inc();
} else if (CodeUtility::is4xx(response_code)) {
connection_manager_.stats_.named_.via_upstream_downstream_rq_4xx_.inc();
} else if (CodeUtility::is5xx(response_code)) {
connection_manager_.stats_.named_.via_upstream_downstream_rq_5xx_.inc();
}
}
}

const Network::Connection* ConnectionManagerImpl::ActiveStream::connection() {
Expand Down