-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
access_log: log requested_server_name in tcp proxy #4144
Changes from 1 commit
8bbdc82
6b04ff5
c416a01
17cf320
d8369ab
5113cb2
a39f84b
b3274e5
d2c6a34
7d02b33
49f0ffe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -301,6 +301,16 @@ RequestInfoFormatter::RequestInfoFormatter(const std::string& field_name) { | |
return RequestInfo::Utility::formatDownstreamAddressNoPort( | ||
*request_info.downstreamRemoteAddress()); | ||
}; | ||
} else if (field_name == "REQUESTED_SERVER_NAME") { | ||
field_extractor_ = [](const RequestInfo::RequestInfo& request_info) { | ||
absl::string_view requested_server_name; | ||
if (nullptr != request_info.requestedServerName()) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems odd to me. I think |
||
return request_info.requestedServerName().data(); | ||
} else { | ||
requested_server_name = UnspecifiedValueString; | ||
return requested_server_name.data(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The return type for field_extractor_ is std::string, so it seems to me this converts UnspecifiedValueString into a string_view and then back to std::string. Does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If just return UnspecifiedValueString I get a conversion error
maybe further ammo to support the removal of absl::string_view from this part There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if you make the lambda's return type explicit ( |
||
} | ||
}; | ||
} else { | ||
throw EnvoyException(fmt::format("Not supported field in RequestInfo: {}", field_name)); | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -178,6 +178,12 @@ struct RequestInfoImpl : public RequestInfo { | |
(*metadata_.mutable_filter_metadata())[name].MergeFrom(value); | ||
}; | ||
|
||
void setRequestedServerName(const absl::string_view& requested_server_name) override { | ||
requested_server_name_ = requested_server_name; | ||
} | ||
|
||
const absl::string_view& requestedServerName() const override { return requested_server_name_; } | ||
|
||
const SystemTime start_time_; | ||
const MonotonicTime start_time_monotonic_; | ||
|
||
|
@@ -197,13 +203,15 @@ struct RequestInfoImpl : public RequestInfo { | |
bool hc_request_{}; | ||
const Router::RouteEntry* route_entry_{}; | ||
envoy::api::v2::core::Metadata metadata_{}; | ||
absl::string_view requestedServerName_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this one's unused. |
||
|
||
private: | ||
uint64_t bytes_received_{}; | ||
uint64_t bytes_sent_{}; | ||
Network::Address::InstanceConstSharedPtr upstream_local_address_; | ||
Network::Address::InstanceConstSharedPtr downstream_local_address_; | ||
Network::Address::InstanceConstSharedPtr downstream_remote_address_; | ||
absl::string_view requested_server_name_; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it always safe to store this as a string view? (e.g. can the underlying string get deallocated before the RequestInfo is used). Given that this is going to get converted into a std::string when the extractor lambda runs, maybe we should just store it as a std::string to begin with? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was wondering this as well. I just noted some of the lifetime best-practices here. In the access log case, maybe it would probably be safest to store as std::string or still accept string_view but immediately convert with string(string_view). I only used absl::string_view since we pass it in include/envoy/network/listen_socket.h and include/envoy/connection.h. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's safe, provided 2 things:
I think in the end the fact that it's hard to reason about whether that string_view is still valid means we should copy it just to be safe unless there's a known performance implication. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did you decide there's a performance implication and want to keep the string view? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @htuch @PiotrSikora since they may be more familiar with There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, should be safe, but given how much other stuff is in |
||
}; | ||
|
||
} // namespace RequestInfo | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -388,6 +388,9 @@ Network::FilterStatus Filter::onData(Buffer::Instance& data, bool end_stream) { | |
upstream_connection_->write(data, end_stream); | ||
ASSERT(0 == data.length()); | ||
resetIdleTimer(); // TODO(ggreenway) PERF: do we need to reset timer on both send and receive? | ||
getRequestInfo().setRequestedServerName(read_callbacks_->connection().requestedServerName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. onData seems like the wrong place for this call; this will be run everytime downstream data arrives. Is the needed data available in onNewConnection()? At a minimum, have a flag for whether this has happened yet and only do it once. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was thinking the same upon reviewing where I called this today. I ended up hitting problems with null values in cases of TCP HalfOpen and thought it might make more sense to only do this when there is a confirmed ::Connected. |
||
ENVOY_LOG(debug, "TCP:onData(), requestedServerName: {} ", | ||
getRequestInfo().requestedServerName()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI: I think the coverage tests are failing because they enable trace-level logging and either this (or one of the other log messages) is being invoked in a test that doesn't set up the mock. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ack, yep that sounds right upon downloading the results There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should be able to reproduce just by running regular tests with |
||
return Network::FilterStatus::StopIteration; | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -185,6 +185,20 @@ TEST(AccessLogFormatterTest, requestInfoFormatter) { | |
RequestInfoFormatter upstream_format("DOWNSTREAM_REMOTE_ADDRESS"); | ||
EXPECT_EQ("127.0.0.1:0", upstream_format.format(header, header, header, request_info)); | ||
} | ||
|
||
// { | ||
// RequestInfoFormatter upstream_format("REQUESTED_SERVER_NAME"); | ||
// absl::string_view requested_server_name = "stub_server"; | ||
// EXPECT_CALL(request_info, | ||
// requestedServerName()).WillRepeatedly(ReturnRef(requested_server_name)); | ||
// EXPECT_EQ("stub_server", upstream_format.format(header, header, header, request_info)); | ||
// } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be enabled? |
||
|
||
{ | ||
RequestInfoFormatter upstream_format("REQUESTED_SERVER_NAME"); | ||
// EXPECT_CALL(request_info, requestedServerName()).WillOnce(Return(nullptr)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should this be enabled? |
||
EXPECT_EQ("-", upstream_format.format(header, header, header, request_info)); | ||
} | ||
} | ||
|
||
TEST(AccessLogFormatterTest, requestHeaderFormatter) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we normally pass absl::string_view around by value unless we're modifying it in the call.