-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Add debug log for slow config updates for GRPC subscriptions #14343
Changes from 3 commits
214010b
64ee95c
f9ec323
6a53b02
435bdbe
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 |
---|---|---|
@@ -1,5 +1,7 @@ | ||
#include "common/config/grpc_subscription_impl.h" | ||
|
||
#include <chrono> | ||
|
||
#include "common/common/assert.h" | ||
#include "common/common/logger.h" | ||
#include "common/common/utility.h" | ||
|
@@ -63,14 +65,37 @@ void GrpcSubscriptionImpl::onConfigUpdate(const std::vector<Config::DecodedResou | |
// supply those versions to onConfigUpdate() along with the xDS response ("system") | ||
// version_info. This way, both types of versions can be tracked and exposed for debugging by | ||
// the configuration update targets. | ||
auto start = dispatcher_.timeSource().monotonicTime(); | ||
callbacks_.onConfigUpdate(resources, version_info); | ||
std::chrono::milliseconds update_duration = std::chrono::duration_cast<std::chrono::milliseconds>( | ||
dispatcher_.timeSource().monotonicTime() - start); | ||
stats_.update_success_.inc(); | ||
stats_.update_attempt_.inc(); | ||
stats_.update_time_.set(DateUtil::nowToMilliseconds(dispatcher_.timeSource())); | ||
stats_.version_.set(HashUtil::xxHash64(version_info)); | ||
stats_.version_text_.set(version_info); | ||
stats_.update_duration_.recordValue(update_duration.count()); | ||
ENVOY_LOG(debug, "gRPC config for {} accepted with {} resources with version {}", type_url_, | ||
resources.size(), version_info); | ||
|
||
if (update_duration > updateDurationLogThreshold()) { | ||
// Figure out the total size of all resource names plus delimiters | ||
int name_size = 0; | ||
std::for_each(resources.begin(), resources.end(), | ||
[&name_size](const Config::DecodedResource& resource) { | ||
name_size += resource.name().size() + 2; | ||
}); | ||
std::string resource_names; | ||
resource_names.reserve(name_size); | ||
for (const auto& resource : resources) { | ||
resource_names.append(resource.get().name()); | ||
if (&resource != &resources.back()) { | ||
resource_names.append(", "); | ||
} | ||
} | ||
ENVOY_LOG(debug, "gRPC config update took {} ms! Resources names: {}", update_duration.count(), | ||
resource_names); | ||
} | ||
} | ||
|
||
void GrpcSubscriptionImpl::onConfigUpdate( | ||
|
@@ -79,11 +104,15 @@ void GrpcSubscriptionImpl::onConfigUpdate( | |
const std::string& system_version_info) { | ||
disableInitFetchTimeoutTimer(); | ||
stats_.update_attempt_.inc(); | ||
auto start = dispatcher_.timeSource().monotonicTime(); | ||
callbacks_.onConfigUpdate(added_resources, removed_resources, system_version_info); | ||
std::chrono::milliseconds update_duration = std::chrono::duration_cast<std::chrono::milliseconds>( | ||
dispatcher_.timeSource().monotonicTime() - start); | ||
stats_.update_success_.inc(); | ||
stats_.update_time_.set(DateUtil::nowToMilliseconds(dispatcher_.timeSource())); | ||
stats_.version_.set(HashUtil::xxHash64(system_version_info)); | ||
stats_.version_text_.set(system_version_info); | ||
stats_.update_duration_.recordValue(update_duration.count()); | ||
} | ||
|
||
void GrpcSubscriptionImpl::onConfigUpdateFailed(ConfigUpdateFailureReason reason, | ||
|
@@ -121,5 +150,12 @@ void GrpcSubscriptionImpl::disableInitFetchTimeoutTimer() { | |
} | ||
} | ||
|
||
// Returns the threshold used to trigger logging of long config updates. | ||
// TODO(adamsjob): make the threshold configurable, either through runtime or bootstrap | ||
std::chrono::milliseconds& GrpcSubscriptionImpl::updateDurationLogThreshold() { | ||
static std::chrono::milliseconds* threshold_ms = new std::chrono::milliseconds(50); | ||
return *threshold_ms; | ||
} | ||
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. std::chrono::milliseconds has a constexpr constructor, so this could be just a 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. Done, lmk if I need to make the name more globally unique. |
||
|
||
} // namespace Config | ||
} // namespace Envoy |
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.
use StrJoin with join-formatters https://abseil.io/docs/cpp/guides/strings#join-formatters and it should be in the line of ENVOY_LOG so it's not evaluated when the log isn't desired.
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.
Good point, and done.