diff --git a/api/envoy/config/accesslog/v3/accesslog.proto b/api/envoy/config/accesslog/v3/accesslog.proto index ad129a3ed64be..bb53286380c98 100644 --- a/api/envoy/config/accesslog/v3/accesslog.proto +++ b/api/envoy/config/accesslog/v3/accesslog.proto @@ -246,6 +246,7 @@ message ResponseFlagFilter { in: "DT" in: "UPE" in: "NC" + in: "OM" } } }]; diff --git a/api/envoy/config/accesslog/v4alpha/accesslog.proto b/api/envoy/config/accesslog/v4alpha/accesslog.proto index 7559a3b82c79f..3e0c7f53598cc 100644 --- a/api/envoy/config/accesslog/v4alpha/accesslog.proto +++ b/api/envoy/config/accesslog/v4alpha/accesslog.proto @@ -245,6 +245,7 @@ message ResponseFlagFilter { in: "DT" in: "UPE" in: "NC" + in: "OM" } } }]; diff --git a/api/envoy/data/accesslog/v3/accesslog.proto b/api/envoy/data/accesslog/v3/accesslog.proto index 98bdd1d6e8322..c53ae0d6ab852 100644 --- a/api/envoy/data/accesslog/v3/accesslog.proto +++ b/api/envoy/data/accesslog/v3/accesslog.proto @@ -186,7 +186,7 @@ message AccessLogCommon { } // Flags indicating occurrences during request/response processing. -// [#next-free-field: 26] +// [#next-free-field: 27] message ResponseFlags { option (udpa.annotations.versioning).previous_message_type = "envoy.data.accesslog.v2.ResponseFlags"; @@ -281,6 +281,9 @@ message ResponseFlags { // Indicates no cluster was found for the request. bool no_cluster_found = 25; + + // Indicates overload manager terminated the request. + bool overload_manager = 26; } // Properties of a negotiated TLS connection. diff --git a/docs/root/configuration/observability/access_log/usage.rst b/docs/root/configuration/observability/access_log/usage.rst index ef4e0ec9b0103..6e461d8e3ffe8 100644 --- a/docs/root/configuration/observability/access_log/usage.rst +++ b/docs/root/configuration/observability/access_log/usage.rst @@ -323,6 +323,7 @@ The following command operators are supported: * **DPE**: The downstream request had an HTTP protocol error. * **UPE**: The upstream response had an HTTP protocol error. * **UMSDR**: The upstream request reached to max stream duration. + * **OM**: Overload Manager terminated the request. %ROUTE_NAME% Name of the route. diff --git a/docs/root/version_history/current.rst b/docs/root/version_history/current.rst index 2b4e64afe0fc7..ac42da130e895 100644 --- a/docs/root/version_history/current.rst +++ b/docs/root/version_history/current.rst @@ -78,6 +78,7 @@ Removed Config or Runtime New Features ------------ +* access_log: added the new response flag for :ref:`overload manager termination `. The response flag will be set when the http stream is terminated by overload manager. * admission control: added :ref:`admission control ` option that when average RPS of the sampling window is below this threshold, the filter will not throttle requests. Added :ref:`admission control ` option to set an upper limit on the probability of rejection. * bandwidth_limit: added new :ref:`HTTP bandwidth limit filter `. * bootstrap: added :ref:`dns_resolution_config ` to aggregate all of the DNS resolver configuration in a single message. By setting one such configuration option *no_default_search_domain* as true the DNS resolver will not use the default search domains. And by setting the configuration *resolvers* we can specify the external DNS servers to be used for external DNS query. diff --git a/envoy/http/codec.h b/envoy/http/codec.h index 606fe1d5bde46..3674fd88c3123 100644 --- a/envoy/http/codec.h +++ b/envoy/http/codec.h @@ -284,7 +284,9 @@ enum class StreamResetReason { // Either there was an early TCP error for a CONNECT request or the peer reset with CONNECT_ERROR ConnectError, // Received payload did not conform to HTTP protocol. - ProtocolError + ProtocolError, + // If the stream was locally reset by the Overload Manager. + OverloadManager }; /** diff --git a/envoy/stream_info/stream_info.h b/envoy/stream_info/stream_info.h index d409aecb89103..2b146b6e421a0 100644 --- a/envoy/stream_info/stream_info.h +++ b/envoy/stream_info/stream_info.h @@ -86,8 +86,10 @@ enum ResponseFlag { UpstreamProtocolError = 0x800000, // No cluster found for a given request. NoClusterFound = 0x1000000, + // Overload Manager terminated the stream. + OverloadManager = 0x2000000, // ATTENTION: MAKE SURE THIS REMAINS EQUAL TO THE LAST FLAG. - LastFlag = NoClusterFound, + LastFlag = OverloadManager, }; /** diff --git a/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto b/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto index dc3e611b6c1a0..2161f80478c23 100644 --- a/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto +++ b/generated_api_shadow/envoy/config/accesslog/v3/accesslog.proto @@ -247,6 +247,7 @@ message ResponseFlagFilter { in: "DT" in: "UPE" in: "NC" + in: "OM" } } }]; diff --git a/generated_api_shadow/envoy/config/accesslog/v4alpha/accesslog.proto b/generated_api_shadow/envoy/config/accesslog/v4alpha/accesslog.proto index 7559a3b82c79f..3e0c7f53598cc 100644 --- a/generated_api_shadow/envoy/config/accesslog/v4alpha/accesslog.proto +++ b/generated_api_shadow/envoy/config/accesslog/v4alpha/accesslog.proto @@ -245,6 +245,7 @@ message ResponseFlagFilter { in: "DT" in: "UPE" in: "NC" + in: "OM" } } }]; diff --git a/generated_api_shadow/envoy/data/accesslog/v3/accesslog.proto b/generated_api_shadow/envoy/data/accesslog/v3/accesslog.proto index 98bdd1d6e8322..c53ae0d6ab852 100644 --- a/generated_api_shadow/envoy/data/accesslog/v3/accesslog.proto +++ b/generated_api_shadow/envoy/data/accesslog/v3/accesslog.proto @@ -186,7 +186,7 @@ message AccessLogCommon { } // Flags indicating occurrences during request/response processing. -// [#next-free-field: 26] +// [#next-free-field: 27] message ResponseFlags { option (udpa.annotations.versioning).previous_message_type = "envoy.data.accesslog.v2.ResponseFlags"; @@ -281,6 +281,9 @@ message ResponseFlags { // Indicates no cluster was found for the request. bool no_cluster_found = 25; + + // Indicates overload manager terminated the request. + bool overload_manager = 26; } // Properties of a negotiated TLS connection. diff --git a/source/common/http/conn_pool_base.cc b/source/common/http/conn_pool_base.cc index e071614787b34..74c2709a98627 100644 --- a/source/common/http/conn_pool_base.cc +++ b/source/common/http/conn_pool_base.cc @@ -154,6 +154,7 @@ void MultiplexedActiveClientBase::onStreamReset(Http::StreamResetReason reason) break; case StreamResetReason::LocalReset: case StreamResetReason::ProtocolError: + case StreamResetReason::OverloadManager: parent_.host()->cluster().stats().upstream_rq_tx_reset_.inc(); break; case StreamResetReason::RemoteReset: diff --git a/source/common/http/utility.cc b/source/common/http/utility.cc index b8b3d9f0e1b16..50d2123b5a835 100644 --- a/source/common/http/utility.cc +++ b/source/common/http/utility.cc @@ -847,6 +847,8 @@ const std::string Utility::resetReasonToString(const Http::StreamResetReason res return "remote error with CONNECT request"; case Http::StreamResetReason::ProtocolError: return "protocol error"; + case Http::StreamResetReason::OverloadManager: + return "overload manager reset"; } NOT_REACHED_GCOVR_EXCL_LINE; diff --git a/source/common/router/router.cc b/source/common/router/router.cc index b6f478620560a..259e105a1af90 100644 --- a/source/common/router/router.cc +++ b/source/common/router/router.cc @@ -1144,6 +1144,8 @@ Filter::streamResetReasonToResponseFlag(Http::StreamResetReason reset_reason) { return StreamInfo::ResponseFlag::UpstreamRemoteReset; case Http::StreamResetReason::ProtocolError: return StreamInfo::ResponseFlag::UpstreamProtocolError; + case Http::StreamResetReason::OverloadManager: + return StreamInfo::ResponseFlag::OverloadManager; } NOT_REACHED_GCOVR_EXCL_LINE; diff --git a/source/common/stream_info/utility.cc b/source/common/stream_info/utility.cc index 8ea8da5158b48..bda0687672900 100644 --- a/source/common/stream_info/utility.cc +++ b/source/common/stream_info/utility.cc @@ -21,7 +21,7 @@ const std::string ResponseFlagUtils::toShortString(const StreamInfo& stream_info } absl::flat_hash_map ResponseFlagUtils::getFlagMap() { - static_assert(ResponseFlag::LastFlag == 0x1000000, + static_assert(ResponseFlag::LastFlag == 0x2000000, "A flag has been added. Add the new flag to ALL_RESPONSE_STRING_FLAGS."); absl::flat_hash_map res; for (auto [str, flag] : ResponseFlagUtils::ALL_RESPONSE_STRING_FLAGS) { diff --git a/source/common/stream_info/utility.h b/source/common/stream_info/utility.h index 9e946af380986..f6c39b8bd25a5 100644 --- a/source/common/stream_info/utility.h +++ b/source/common/stream_info/utility.h @@ -44,6 +44,7 @@ class ResponseFlagUtils { constexpr static absl::string_view DURATION_TIMEOUT = "DT"; constexpr static absl::string_view UPSTREAM_PROTOCOL_ERROR = "UPE"; constexpr static absl::string_view NO_CLUSTER_FOUND = "NC"; + constexpr static absl::string_view OVERLOAD_MANAGER = "OM"; static constexpr std::array ALL_RESPONSE_STRING_FLAGS{ FlagStringAndEnum{FAILED_LOCAL_HEALTH_CHECK, ResponseFlag::FailedLocalHealthCheck}, @@ -74,6 +75,7 @@ class ResponseFlagUtils { FlagStringAndEnum{DURATION_TIMEOUT, ResponseFlag::DurationTimeout}, FlagStringAndEnum{UPSTREAM_PROTOCOL_ERROR, ResponseFlag::UpstreamProtocolError}, FlagStringAndEnum{NO_CLUSTER_FOUND, ResponseFlag::NoClusterFound}, + FlagStringAndEnum{OVERLOAD_MANAGER, ResponseFlag::OverloadManager}, }; private: diff --git a/source/extensions/access_loggers/grpc/grpc_access_log_utils.cc b/source/extensions/access_loggers/grpc/grpc_access_log_utils.cc index 3d924c0cd47cb..845412359782b 100644 --- a/source/extensions/access_loggers/grpc/grpc_access_log_utils.cc +++ b/source/extensions/access_loggers/grpc/grpc_access_log_utils.cc @@ -37,7 +37,7 @@ void Utility::responseFlagsToAccessLogResponseFlags( envoy::data::accesslog::v3::AccessLogCommon& common_access_log, const StreamInfo::StreamInfo& stream_info) { - static_assert(StreamInfo::ResponseFlag::LastFlag == 0x1000000, + static_assert(StreamInfo::ResponseFlag::LastFlag == 0x2000000, "A flag has been added. Fix this code."); if (stream_info.hasResponseFlag(StreamInfo::ResponseFlag::FailedLocalHealthCheck)) { @@ -140,6 +140,10 @@ void Utility::responseFlagsToAccessLogResponseFlags( if (stream_info.hasResponseFlag(StreamInfo::ResponseFlag::NoClusterFound)) { common_access_log.mutable_response_flags()->set_no_cluster_found(true); } + + if (stream_info.hasResponseFlag(StreamInfo::ResponseFlag::OverloadManager)) { + common_access_log.mutable_response_flags()->set_overload_manager(true); + } } void Utility::extractCommonAccessLogProperties( diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index a6461165fde22..427392a2df98b 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -989,6 +989,7 @@ name: accesslog - DT - UPE - NC + - OM typed_config: "@type": type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog path: /dev/null diff --git a/test/common/http/utility_test.cc b/test/common/http/utility_test.cc index 32149b467c395..18fe7de3c6ca5 100644 --- a/test/common/http/utility_test.cc +++ b/test/common/http/utility_test.cc @@ -870,6 +870,8 @@ TEST(HttpUtility, ResetReasonToString) { Utility::resetReasonToString(Http::StreamResetReason::RemoteRefusedStreamReset)); EXPECT_EQ("remote error with CONNECT request", Utility::resetReasonToString(Http::StreamResetReason::ConnectError)); + EXPECT_EQ("overload manager reset", + Utility::resetReasonToString(Http::StreamResetReason::OverloadManager)); } class TestConfig : public Router::RouteSpecificFilterConfig { diff --git a/test/extensions/access_loggers/grpc/grpc_access_log_utils_test.cc b/test/extensions/access_loggers/grpc/grpc_access_log_utils_test.cc index 53b655b54c778..c91799947621c 100644 --- a/test/extensions/access_loggers/grpc/grpc_access_log_utils_test.cc +++ b/test/extensions/access_loggers/grpc/grpc_access_log_utils_test.cc @@ -47,6 +47,7 @@ TEST(UtilityResponseFlagsToAccessLogResponseFlagsTest, All) { common_access_log_expected.mutable_response_flags()->set_duration_timeout(true); common_access_log_expected.mutable_response_flags()->set_upstream_protocol_error(true); common_access_log_expected.mutable_response_flags()->set_no_cluster_found(true); + common_access_log_expected.mutable_response_flags()->set_overload_manager(true); EXPECT_EQ(common_access_log_expected.DebugString(), common_access_log.DebugString()); }