Skip to content

Commit d20cd6d

Browse files
JimmyCYJistio-merge-robot
authored andcommitted
Support Mixer HTTP filter to report sent.bytes and received.bytes attributes (#1372)
Automatic merge from submit-queue. Support Mixer HTTP filter to report sent.bytes and received.bytes attributes **What this PR does / why we need it**:Support Mixer HTTP filter to send attributes "sent.bytes" and "received.bytes" in Report() calls. "sent.bytes" records total response sent in bytes, including response headers, body, and trailers. "received.bytes" records total request received in bytes, including request headers, body, and trailers. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #1370 **Special notes for your reviewer**: **Release note**: ```release-note NONE ```
1 parent a4c5ae5 commit d20cd6d

File tree

8 files changed

+110
-22
lines changed

8 files changed

+110
-22
lines changed

include/istio/control/http/report_data.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ class ReportData {
3434

3535
// Get additional report info.
3636
struct ReportInfo {
37-
uint64_t send_bytes;
38-
uint64_t received_bytes;
37+
uint64_t response_totle_size;
38+
uint64_t request_totle_size;
39+
uint64_t request_body_size;
40+
uint64_t response_body_size;
3941
std::chrono::nanoseconds duration;
4042
int response_code;
4143
};

src/envoy/http/mixer/filter.cc

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ void Filter::ReadPerRouteConfig(
107107

108108
FilterHeadersStatus Filter::decodeHeaders(HeaderMap& headers, bool) {
109109
ENVOY_LOG(debug, "Called Mixer::Filter : {}", __func__);
110+
received_bytes_ += headers.byteSize();
110111

111112
::istio::control::http::Controller::PerRouteConfig config;
112113
auto route = decoder_callbacks_->route();
@@ -135,14 +136,16 @@ FilterHeadersStatus Filter::decodeHeaders(HeaderMap& headers, bool) {
135136
FilterDataStatus Filter::decodeData(Buffer::Instance& data, bool end_stream) {
136137
ENVOY_LOG(debug, "Called Mixer::Filter : {} ({}, {})", __func__,
137138
data.length(), end_stream);
139+
received_bytes_ += data.length();
138140
if (state_ == Calling) {
139141
return FilterDataStatus::StopIterationAndWatermark;
140142
}
141143
return FilterDataStatus::Continue;
142144
}
143145

144-
FilterTrailersStatus Filter::decodeTrailers(HeaderMap&) {
146+
FilterTrailersStatus Filter::decodeTrailers(HeaderMap& trailers) {
145147
ENVOY_LOG(debug, "Called Mixer::Filter : {}", __func__);
148+
received_bytes_ += trailers.byteSize();
146149
if (state_ == Calling) {
147150
return FilterTrailersStatus::StopIteration;
148151
}
@@ -182,6 +185,35 @@ void Filter::completeCheck(const Status& status) {
182185
}
183186
}
184187

188+
// Http::StreamEncoderFilter
189+
FilterHeadersStatus Filter::encode100ContinueHeaders(Http::HeaderMap& headers) {
190+
ENVOY_LOG(debug, "Called Mixer::Filter : {}", __func__);
191+
sent_bytes_ += headers.byteSize();
192+
return FilterHeadersStatus::Continue;
193+
}
194+
195+
FilterHeadersStatus Filter::encodeHeaders(Http::HeaderMap& headers, bool) {
196+
ENVOY_LOG(debug, "Called Mixer::Filter : {}", __func__);
197+
sent_bytes_ += headers.byteSize();
198+
return Http::FilterHeadersStatus::Continue;
199+
}
200+
201+
FilterDataStatus Filter::encodeData(Buffer::Instance& data, bool) {
202+
ENVOY_LOG(debug, "Called Mixer::Filter : {}", __func__);
203+
sent_bytes_ += data.length();
204+
return Http::FilterDataStatus::Continue;
205+
}
206+
207+
FilterTrailersStatus Filter::encodeTrailers(Http::HeaderMap& trailers) {
208+
sent_bytes_ += trailers.byteSize();
209+
return Http::FilterTrailersStatus::Continue;
210+
}
211+
212+
void Filter::setEncoderFilterCallbacks(
213+
StreamEncoderFilterCallbacks& callbacks) {
214+
encoder_callbacks_ = &callbacks;
215+
}
216+
185217
void Filter::onDestroy() {
186218
ENVOY_LOG(debug, "Called Mixer::Filter : {} state: {}", __func__, state_);
187219
if (state_ != Calling) {
@@ -212,7 +244,8 @@ void Filter::log(const HeaderMap* request_headers,
212244
CheckData check_data(*request_headers, nullptr);
213245
handler_->ExtractRequestAttributes(&check_data);
214246
}
215-
ReportData report_data(response_headers, request_info);
247+
ReportData report_data(response_headers, request_info, sent_bytes_,
248+
received_bytes_);
216249
handler_->Report(&report_data);
217250
}
218251

src/envoy/http/mixer/filter.h

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Envoy {
2424
namespace Http {
2525
namespace Mixer {
2626

27-
class Filter : public Http::StreamDecoderFilter,
27+
class Filter : public Http::StreamFilter,
2828
public AccessLog::Instance,
2929
public Logger::Loggable<Logger::Id::filter> {
3030
public:
@@ -33,9 +33,20 @@ class Filter : public Http::StreamDecoderFilter,
3333
// Implementing virtual functions for StreamDecoderFilter
3434
FilterHeadersStatus decodeHeaders(HeaderMap& headers, bool) override;
3535
FilterDataStatus decodeData(Buffer::Instance& data, bool end_stream) override;
36-
FilterTrailersStatus decodeTrailers(HeaderMap&) override;
36+
FilterTrailersStatus decodeTrailers(HeaderMap& trailers) override;
3737
void setDecoderFilterCallbacks(
3838
StreamDecoderFilterCallbacks& callbacks) override;
39+
40+
// Http::StreamEncoderFilter
41+
FilterHeadersStatus encode100ContinueHeaders(
42+
Http::HeaderMap& headers) override;
43+
FilterHeadersStatus encodeHeaders(HeaderMap& headers, bool) override;
44+
FilterDataStatus encodeData(Buffer::Instance& data, bool) override;
45+
FilterTrailersStatus encodeTrailers(HeaderMap& trailers) override;
46+
void setEncoderFilterCallbacks(
47+
StreamEncoderFilterCallbacks& callbacks) override;
48+
49+
// Http::StreamFilterBase
3950
void onDestroy() override;
4051

4152
// This is the callback function when Check is done.
@@ -67,8 +78,16 @@ class Filter : public Http::StreamDecoderFilter,
6778
// Point to the request HTTP headers
6879
HeaderMap* headers_;
6980

70-
// The filter callback.
71-
StreamDecoderFilterCallbacks* decoder_callbacks_;
81+
// Total number of bytes received, including request headers, body, and
82+
// trailers.
83+
uint64_t received_bytes_{0};
84+
// Total number of bytes sent, including response headers, body, and trailers.
85+
uint64_t sent_bytes_{0};
86+
87+
// The stream decoder filter callback.
88+
StreamDecoderFilterCallbacks* decoder_callbacks_{nullptr};
89+
// The stream encoder filter callback.
90+
StreamEncoderFilterCallbacks* encoder_callbacks_{nullptr};
7291
};
7392

7493
} // namespace Mixer

src/envoy/http/mixer/report_data.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@ const std::set<std::string> ResponseHeaderExclusives = {};
3232
class ReportData : public ::istio::control::http::ReportData {
3333
const HeaderMap *headers_;
3434
const RequestInfo::RequestInfo &info_;
35+
uint64_t sent_bytes_;
36+
uint64_t received_bytes_;
3537

3638
public:
37-
ReportData(const HeaderMap *headers, const RequestInfo::RequestInfo &info)
38-
: headers_(headers), info_(info) {}
39+
ReportData(const HeaderMap *headers, const RequestInfo::RequestInfo &info,
40+
uint64_t sent_bytes, uint64_t received_bytes)
41+
: headers_(headers),
42+
info_(info),
43+
sent_bytes_(sent_bytes),
44+
received_bytes_(received_bytes) {}
3945

4046
std::map<std::string, std::string> GetResponseHeaders() const override {
4147
if (headers_) {
@@ -46,8 +52,10 @@ class ReportData : public ::istio::control::http::ReportData {
4652

4753
void GetReportInfo(
4854
::istio::control::http::ReportData::ReportInfo *data) const override {
49-
data->received_bytes = info_.bytesReceived();
50-
data->send_bytes = info_.bytesSent();
55+
data->request_body_size = info_.bytesReceived();
56+
data->response_body_size = info_.bytesSent();
57+
data->response_totle_size = sent_bytes_;
58+
data->request_totle_size = received_bytes_;
5159
data->duration =
5260
info_.requestComplete().value_or(std::chrono::nanoseconds{0});
5361
// responseCode is for the backend response. If it is not valid, the request

src/istio/control/attribute_names.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,17 @@ const char AttributeName::kRequestMethod[] = "request.method";
2828
const char AttributeName::kRequestPath[] = "request.path";
2929
const char AttributeName::kRequestReferer[] = "request.referer";
3030
const char AttributeName::kRequestScheme[] = "request.scheme";
31-
const char AttributeName::kRequestSize[] = "request.size";
31+
const char AttributeName::kRequestBodySize[] = "request.size";
32+
const char AttributeName::kRequestTotleSize[] = "request.totle_size";
3233
const char AttributeName::kRequestTime[] = "request.time";
3334
const char AttributeName::kRequestUserAgent[] = "request.useragent";
3435
const char AttributeName::kRequestApiKey[] = "request.api_key";
3536

3637
const char AttributeName::kResponseCode[] = "response.code";
3738
const char AttributeName::kResponseDuration[] = "response.duration";
3839
const char AttributeName::kResponseHeaders[] = "response.headers";
39-
const char AttributeName::kResponseSize[] = "response.size";
40+
const char AttributeName::kResponseBodySize[] = "response.size";
41+
const char AttributeName::kResponseTotleSize[] = "response.totle_size";
4042
const char AttributeName::kResponseTime[] = "response.time";
4143

4244
// TCP attributes

src/istio/control/attribute_names.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,21 @@ struct AttributeName {
3434
static const char kRequestPath[];
3535
static const char kRequestReferer[];
3636
static const char kRequestScheme[];
37-
static const char kRequestSize[];
37+
static const char kRequestBodySize[];
38+
// Total size of request received, including request headers, body, and
39+
// trailers.
40+
static const char kRequestTotleSize[];
3841
static const char kRequestTime[];
3942
static const char kRequestUserAgent[];
4043
static const char kRequestApiKey[];
4144

4245
static const char kResponseCode[];
4346
static const char kResponseDuration[];
4447
static const char kResponseHeaders[];
45-
static const char kResponseSize[];
48+
static const char kResponseBodySize[];
49+
// Total size of response sent, including response headers, body, and
50+
// trailers.
51+
static const char kResponseTotleSize[];
4652
static const char kResponseTime[];
4753

4854
// TCP attributes

src/istio/control/http/attributes_builder.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,10 @@ void AttributesBuilder::ExtractReportAttributes(ReportData *report_data) {
180180

181181
ReportData::ReportInfo info;
182182
report_data->GetReportInfo(&info);
183-
builder.AddInt64(AttributeName::kRequestSize, info.received_bytes);
184-
builder.AddInt64(AttributeName::kResponseSize, info.send_bytes);
183+
builder.AddInt64(AttributeName::kRequestBodySize, info.request_body_size);
184+
builder.AddInt64(AttributeName::kResponseBodySize, info.response_body_size);
185+
builder.AddInt64(AttributeName::kRequestTotleSize, info.request_totle_size);
186+
builder.AddInt64(AttributeName::kResponseTotleSize, info.response_totle_size);
185187
builder.AddDuration(AttributeName::kResponseDuration, info.duration);
186188
if (!request_->check_status.ok()) {
187189
builder.AddInt64(

src/istio/control/http/attributes_builder_test.cc

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,18 @@ attributes {
222222
int64_value: 200
223223
}
224224
}
225+
attributes {
226+
key: "response.totle_size"
227+
value {
228+
int64_value: 120
229+
}
230+
}
231+
attributes {
232+
key: "request.totle_size"
233+
value {
234+
int64_value: 240
235+
}
236+
}
225237
attributes {
226238
key: "response.time"
227239
value {
@@ -423,8 +435,10 @@ TEST(AttributesBuilderTest, TestReportAttributes) {
423435
}));
424436
EXPECT_CALL(mock_data, GetReportInfo(_))
425437
.WillOnce(Invoke([](ReportData::ReportInfo *info) {
426-
info->received_bytes = 100;
427-
info->send_bytes = 200;
438+
info->request_body_size = 100;
439+
info->response_body_size = 200;
440+
info->response_totle_size = 120;
441+
info->request_totle_size = 240;
428442
info->duration = std::chrono::nanoseconds(1);
429443
info->response_code = 404;
430444
}));
@@ -463,8 +477,10 @@ TEST(AttributesBuilderTest, TestReportAttributesWithDestIP) {
463477
}));
464478
EXPECT_CALL(mock_data, GetReportInfo(_))
465479
.WillOnce(Invoke([](ReportData::ReportInfo *info) {
466-
info->received_bytes = 100;
467-
info->send_bytes = 200;
480+
info->request_body_size = 100;
481+
info->response_body_size = 200;
482+
info->response_totle_size = 120;
483+
info->request_totle_size = 240;
468484
info->duration = std::chrono::nanoseconds(1);
469485
info->response_code = 404;
470486
}));

0 commit comments

Comments
 (0)