Skip to content

Commit

Permalink
cel: add response.backend_latency in CEL attributes (envoyproxy#36292)
Browse files Browse the repository at this point in the history
We will depend on CEL to get those information inside HTTP wasm
- unit tests added
- doc added
Signed-off-by: Xuyang Tao <[email protected]>
  • Loading branch information
TAOXUY authored Sep 25, 2024
1 parent 07a8c4a commit 029e808
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/root/intro/arch_overview/advanced/attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ Response attributes are only available after the request completes.
response.trailers, "map<string, string>", All response trailers indexed by the lower-cased trailer name
response.size, int, Size of the response body
response.total_size, int, Total size of the response including the approximate uncompressed size of the headers and the trailers
response.backend_latency, duration, Duration between the first byte sent to and the last byte received from the upstream backend

Connection attributes
---------------------
Expand Down
9 changes: 9 additions & 0 deletions source/extensions/filters/common/expr/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,15 @@ absl::optional<CelValue> ResponseWrapper::operator[](CelValue key) const {
return CelValue::CreateString(&details.value());
}
return {};
} else if (value == BackendLatency) {
Envoy::StreamInfo::TimingUtility timing(info_);
const auto last_upstream_rx_byte_received = timing.lastUpstreamRxByteReceived();
const auto first_upstream_tx_byte_sent = timing.firstUpstreamTxByteSent();
if (last_upstream_rx_byte_received.has_value() && first_upstream_tx_byte_sent.has_value()) {
return CelValue::CreateDuration(absl::FromChrono(last_upstream_rx_byte_received.value() -
first_upstream_tx_byte_sent.value()));
}
return {};
}
return {};
}
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/filters/common/expr/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "source/common/http/headers.h"
#include "source/common/runtime/runtime_features.h"
#include "source/common/singleton/const_singleton.h"
#include "source/common/stream_info/utility.h"

#include "eval/public/cel_value.h"
#include "eval/public/containers/container_backed_list_impl.h"
Expand Down Expand Up @@ -47,6 +48,7 @@ constexpr absl::string_view CodeDetails = "code_details";
constexpr absl::string_view Trailers = "trailers";
constexpr absl::string_view Flags = "flags";
constexpr absl::string_view GrpcStatus = "grpc_status";
constexpr absl::string_view BackendLatency = "backend_latency";

// Per-request or per-connection metadata
constexpr absl::string_view Metadata = "metadata";
Expand Down
8 changes: 8 additions & 0 deletions test/extensions/filters/common/expr/context_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,14 @@ TEST(Context, ResponseAttributes) {
EXPECT_FALSE(value.has_value());
}

{
info.setUpstreamInfo(std::make_shared<StreamInfo::UpstreamInfoImpl>());
StreamInfo::UpstreamTiming& upstream_timing = info.upstreamInfo()->upstreamTiming();
upstream_timing.onFirstUpstreamTxByteSent(info.timeSource());
upstream_timing.onLastUpstreamRxByteReceived(info.timeSource());
EXPECT_TRUE(response[CelValue::CreateStringView(BackendLatency)].has_value());
}

{
Http::TestResponseHeaderMapImpl header_map{{header_name, "a"}, {grpc_status, "7"}};
Http::TestResponseTrailerMapImpl trailer_map{{trailer_name, "b"}};
Expand Down

0 comments on commit 029e808

Please sign in to comment.