diff --git a/include/envoy/grpc/context.h b/include/envoy/grpc/context.h index 2f7fe0107d02..f1837c604e9e 100644 --- a/include/envoy/grpc/context.h +++ b/include/envoy/grpc/context.h @@ -8,6 +8,8 @@ namespace Envoy { namespace Grpc { +struct StatNames; + /** * Captures grpc-related structures with cardinality of one per server. */ @@ -78,6 +80,11 @@ class Context { */ virtual void chargeResponseMessageStat(const Upstream::ClusterInfo& cluster, const RequestNames& request_names, uint64_t amount) PURE; + + /** + * @return a struct containing StatNames for gRPC stat tokens. + */ + virtual StatNames& statNames() PURE; }; using ContextPtr = std::unique_ptr; diff --git a/source/common/grpc/BUILD b/source/common/grpc/BUILD index 051d0881299f..3280a70493f6 100644 --- a/source/common/grpc/BUILD +++ b/source/common/grpc/BUILD @@ -107,6 +107,7 @@ envoy_cc_library( hdrs = ["context_impl.h"], external_deps = ["abseil_optional"], deps = [ + ":stat_names_lib", "//include/envoy/grpc:context_interface", "//include/envoy/http:header_map_interface", "//include/envoy/stats:stats_interface", @@ -138,6 +139,16 @@ envoy_cc_library( ], ) +envoy_cc_library( + name = "stat_names_lib", + srcs = ["stat_names.cc"], + hdrs = ["stat_names.h"], + deps = [ + "//include/envoy/grpc:status", + "//source/common/stats:symbol_table_lib", + ], +) + envoy_cc_library( name = "google_async_client_lib", srcs = ["google_async_client_impl.cc"], @@ -151,6 +162,7 @@ envoy_cc_library( ":google_grpc_context_lib", ":google_grpc_creds_lib", ":google_grpc_utils_lib", + ":stat_names_lib", ":typed_async_client_lib", "//include/envoy/api:api_interface", "//include/envoy/grpc:google_grpc_creds_interface", diff --git a/source/common/grpc/async_client_manager_impl.cc b/source/common/grpc/async_client_manager_impl.cc index 59f9c042545c..dc039473395c 100644 --- a/source/common/grpc/async_client_manager_impl.cc +++ b/source/common/grpc/async_client_manager_impl.cc @@ -33,8 +33,8 @@ AsyncClientFactoryImpl::AsyncClientFactoryImpl(Upstream::ClusterManager& cm, AsyncClientManagerImpl::AsyncClientManagerImpl(Upstream::ClusterManager& cm, ThreadLocal::Instance& tls, TimeSource& time_source, - Api::Api& api) - : cm_(cm), tls_(tls), time_source_(time_source), api_(api) { + Api::Api& api, const StatNames& stat_names) + : cm_(cm), tls_(tls), time_source_(time_source), api_(api), stat_names_(stat_names) { #ifdef ENVOY_GOOGLE_GRPC google_tls_slot_ = tls.allocateSlot(); google_tls_slot_->set( @@ -50,10 +50,10 @@ RawAsyncClientPtr AsyncClientFactoryImpl::create() { GoogleAsyncClientFactoryImpl::GoogleAsyncClientFactoryImpl( ThreadLocal::Instance& tls, ThreadLocal::Slot* google_tls_slot, Stats::Scope& scope, - const envoy::config::core::v3::GrpcService& config, Api::Api& api) + const envoy::config::core::v3::GrpcService& config, Api::Api& api, const StatNames& stat_names) : tls_(tls), google_tls_slot_(google_tls_slot), scope_(scope.createScope(fmt::format("grpc.{}.", config.google_grpc().stat_prefix()))), - config_(config), api_(api) { + config_(config), api_(api), stat_names_(stat_names) { #ifndef ENVOY_GOOGLE_GRPC UNREFERENCED_PARAMETER(tls_); @@ -61,6 +61,7 @@ GoogleAsyncClientFactoryImpl::GoogleAsyncClientFactoryImpl( UNREFERENCED_PARAMETER(scope_); UNREFERENCED_PARAMETER(config_); UNREFERENCED_PARAMETER(api_); + UNREFERENCED_PARAMETER(stat_names_); throw EnvoyException("Google C++ gRPC client is not linked"); #else ASSERT(google_tls_slot_ != nullptr); @@ -72,7 +73,7 @@ RawAsyncClientPtr GoogleAsyncClientFactoryImpl::create() { GoogleGenericStubFactory stub_factory; return std::make_unique( tls_.dispatcher(), google_tls_slot_->getTyped(), stub_factory, - scope_, config_, api_); + scope_, config_, api_, stat_names_); #else return nullptr; #endif @@ -86,7 +87,7 @@ AsyncClientManagerImpl::factoryForGrpcService(const envoy::config::core::v3::Grp return std::make_unique(cm_, config, skip_cluster_check, time_source_); case envoy::config::core::v3::GrpcService::TargetSpecifierCase::kGoogleGrpc: return std::make_unique(tls_, google_tls_slot_.get(), scope, - config, api_); + config, api_, stat_names_); default: NOT_REACHED_GCOVR_EXCL_LINE; } diff --git a/source/common/grpc/async_client_manager_impl.h b/source/common/grpc/async_client_manager_impl.h index 747384156eed..923dc3beb9c1 100644 --- a/source/common/grpc/async_client_manager_impl.h +++ b/source/common/grpc/async_client_manager_impl.h @@ -8,6 +8,8 @@ #include "envoy/thread_local/thread_local.h" #include "envoy/upstream/cluster_manager.h" +#include "common/grpc/stat_names.h" + namespace Envoy { namespace Grpc { @@ -29,7 +31,8 @@ class GoogleAsyncClientFactoryImpl : public AsyncClientFactory { public: GoogleAsyncClientFactoryImpl(ThreadLocal::Instance& tls, ThreadLocal::Slot* google_tls_slot, Stats::Scope& scope, - const envoy::config::core::v3::GrpcService& config, Api::Api& api); + const envoy::config::core::v3::GrpcService& config, Api::Api& api, + const StatNames& stat_names); RawAsyncClientPtr create() override; @@ -39,12 +42,13 @@ class GoogleAsyncClientFactoryImpl : public AsyncClientFactory { Stats::ScopeSharedPtr scope_; const envoy::config::core::v3::GrpcService config_; Api::Api& api_; + const StatNames& stat_names_; }; class AsyncClientManagerImpl : public AsyncClientManager { public: AsyncClientManagerImpl(Upstream::ClusterManager& cm, ThreadLocal::Instance& tls, - TimeSource& time_source, Api::Api& api); + TimeSource& time_source, Api::Api& api, const StatNames& stat_names); // Grpc::AsyncClientManager AsyncClientFactoryPtr factoryForGrpcService(const envoy::config::core::v3::GrpcService& config, @@ -57,6 +61,7 @@ class AsyncClientManagerImpl : public AsyncClientManager { ThreadLocal::SlotPtr google_tls_slot_; TimeSource& time_source_; Api::Api& api_; + const StatNames& stat_names_; }; } // namespace Grpc diff --git a/source/common/grpc/context_impl.cc b/source/common/grpc/context_impl.cc index 9e478a1e53d3..f75d31b30703 100644 --- a/source/common/grpc/context_impl.cc +++ b/source/common/grpc/context_impl.cc @@ -12,7 +12,8 @@ ContextImpl::ContextImpl(Stats::SymbolTable& symbol_table) success_(stat_name_pool_.add("success")), failure_(stat_name_pool_.add("failure")), total_(stat_name_pool_.add("total")), zero_(stat_name_pool_.add("0")), request_message_count_(stat_name_pool_.add("request_message_count")), - response_message_count_(stat_name_pool_.add("response_message_count")) {} + response_message_count_(stat_name_pool_.add("response_message_count")), + stat_names_(symbol_table) {} // Makes a stat name from a string, if we don't already have one for it. // This always takes a lock on mutex_, and if we haven't seen the name @@ -39,18 +40,15 @@ void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster, Protocol prot } absl::string_view status_str = grpc_status->value().getStringView(); - const bool success = (status_str == "0"); - - // TODO(jmarantz): Perhaps the universe of likely grpc status codes is - // sufficiently bounded that we should precompute status StatNames for popular - // ones beyond "0". - const Stats::StatName status_stat_name = success ? zero_ : makeDynamicStatName(status_str); + auto iter = stat_names_.status_names_.find(status_str); + const Stats::StatName status_stat_name = + (iter != stat_names_.status_names_.end()) ? iter->second : makeDynamicStatName(status_str); const Stats::SymbolTable::StoragePtr stat_name_storage = symbol_table_.join({protocolStatName(protocol), request_names.service_, request_names.method_, status_stat_name}); cluster.statsScope().counterFromStatName(Stats::StatName(stat_name_storage.get())).inc(); - chargeStat(cluster, protocol, request_names, success); + chargeStat(cluster, protocol, request_names, (status_str == "0")); } void ContextImpl::chargeStat(const Upstream::ClusterInfo& cluster, Protocol protocol, diff --git a/source/common/grpc/context_impl.h b/source/common/grpc/context_impl.h index de96ca99b529..431799eabcd6 100644 --- a/source/common/grpc/context_impl.h +++ b/source/common/grpc/context_impl.h @@ -7,6 +7,7 @@ #include "envoy/http/header_map.h" #include "common/common/hash.h" +#include "common/grpc/stat_names.h" #include "common/stats/symbol_table_impl.h" #include "absl/types/optional.h" @@ -49,6 +50,8 @@ class ContextImpl : public Context { return protocol == Context::Protocol::Grpc ? grpc_ : grpc_web_; } + StatNames& statNames() override { return stat_names_; } + private: // Makes a stat name from a string, if we don't already have one for it. // This always takes a lock on mutex_, and if we haven't seen the name @@ -70,6 +73,8 @@ class ContextImpl : public Context { const Stats::StatName zero_; const Stats::StatName request_message_count_; const Stats::StatName response_message_count_; + + StatNames stat_names_; }; } // namespace Grpc diff --git a/source/common/grpc/google_async_client_impl.cc b/source/common/grpc/google_async_client_impl.cc index f459b935a3f5..ea22f07c9451 100644 --- a/source/common/grpc/google_async_client_impl.cc +++ b/source/common/grpc/google_async_client_impl.cc @@ -73,7 +73,7 @@ GoogleAsyncClientImpl::GoogleAsyncClientImpl(Event::Dispatcher& dispatcher, GoogleStubFactory& stub_factory, Stats::ScopeSharedPtr scope, const envoy::config::core::v3::GrpcService& config, - Api::Api& api) + Api::Api& api, const StatNames& stat_names) : dispatcher_(dispatcher), tls_(tls), stat_prefix_(config.google_grpc().stat_prefix()), initial_metadata_(config.initial_metadata()), scope_(scope) { // We rebuild the channel each time we construct the channel. It appears that the gRPC library is @@ -83,9 +83,11 @@ GoogleAsyncClientImpl::GoogleAsyncClientImpl(Event::Dispatcher& dispatcher, std::shared_ptr channel = GoogleGrpcUtils::createChannel(config, api); stub_ = stub_factory.createStub(channel); // Initialize client stats. - stats_.streams_total_ = &scope_->counter("streams_total"); + // TODO(jmarantz): Capture these names in async_client_manager_impl.cc and + // pass in a struct of StatName objects so we don't have to take locks here. + stats_.streams_total_ = &scope_->counterFromStatName(stat_names.streams_total_); for (uint32_t i = 0; i <= Status::WellKnownGrpcStatus::MaximumKnown; ++i) { - stats_.streams_closed_[i] = &scope_->counter(absl::StrCat("streams_closed_", i)); + stats_.streams_closed_[i] = &scope_->counterFromStatName(stat_names.streams_closed_[i]); } } diff --git a/source/common/grpc/google_async_client_impl.h b/source/common/grpc/google_async_client_impl.h index cc0321283d04..19b2059420d6 100644 --- a/source/common/grpc/google_async_client_impl.h +++ b/source/common/grpc/google_async_client_impl.h @@ -16,6 +16,7 @@ #include "common/common/thread.h" #include "common/common/thread_annotations.h" #include "common/grpc/google_grpc_context.h" +#include "common/grpc/stat_names.h" #include "common/grpc/typed_async_client.h" #include "common/tracing/http_tracer_impl.h" @@ -169,7 +170,8 @@ class GoogleAsyncClientImpl final : public RawAsyncClient, Logger::Loggable streams_closed_; + absl::flat_hash_map status_names_; +}; + +} // namespace Grpc +} // namespace Envoy diff --git a/source/common/http/BUILD b/source/common/http/BUILD index 1c4068178f4d..577ebadb6336 100644 --- a/source/common/http/BUILD +++ b/source/common/http/BUILD @@ -317,6 +317,7 @@ envoy_cc_library( "//include/envoy/stats:stats_interface", "//include/envoy/stats:stats_macros", "//include/envoy/stats:timespan_interface", + "//source/common/stats:symbol_table_lib", ], ) diff --git a/source/common/http/user_agent.cc b/source/common/http/user_agent.cc index 4a662a0593d4..681c9d18289f 100644 --- a/source/common/http/user_agent.cc +++ b/source/common/http/user_agent.cc @@ -9,6 +9,7 @@ #include "envoy/stats/timespan.h" #include "common/http/headers.h" +#include "common/stats/symbol_table_impl.h" namespace Envoy { namespace Http { @@ -21,8 +22,12 @@ void UserAgent::completeConnectionLength(Stats::Timespan& span) { return; } - // TODO(jmarantz): use stat-names here. - scope_->histogram(prefix_ + "downstream_cx_length_ms", Stats::Histogram::Unit::Milliseconds) + // TODO(jmarantz): use stat-names properly here. This usage takes the symbol + // table lock on every request if real symbol tables are enabled, and we need + // to pre-allocate the strings, including the ones that go into the prefix + // calculation below, so they can be joined without taking a lock. + Stats::StatNameManagedStorage storage(prefix_ + "downstream_cx_length_ms", scope_->symbolTable()); + scope_->histogramFromStatName(storage.statName(), Stats::Histogram::Unit::Milliseconds) .recordValue(span.elapsed().count()); } diff --git a/source/common/upstream/cluster_manager_impl.cc b/source/common/upstream/cluster_manager_impl.cc index 3de5f5ba6b22..aa5f724446f6 100644 --- a/source/common/upstream/cluster_manager_impl.cc +++ b/source/common/upstream/cluster_manager_impl.cc @@ -208,7 +208,7 @@ ClusterManagerImpl::ClusterManagerImpl( Runtime::RandomGenerator& random, const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, Server::Admin& admin, ProtobufMessage::ValidationContext& validation_context, Api::Api& api, - Http::Context& http_context) + Http::Context& http_context, Grpc::Context& grpc_context) : factory_(factory), runtime_(runtime), stats_(stats), tls_(tls.allocateSlot()), random_(random), bind_config_(bootstrap.cluster_manager().upstream_bind_config()), local_info_(local_info), cm_stats_(generateStats(stats)), @@ -219,8 +219,8 @@ ClusterManagerImpl::ClusterManagerImpl( http_context_(http_context), subscription_factory_(local_info, main_thread_dispatcher, *this, random, validation_context.dynamicValidationVisitor(), api) { - async_client_manager_ = - std::make_unique(*this, tls, time_source_, api); + async_client_manager_ = std::make_unique( + *this, tls, time_source_, api, grpc_context.statNames()); const auto& cm_config = bootstrap.cluster_manager(); if (cm_config.has_outlier_detection()) { const std::string event_log_file_path = cm_config.outlier_detection().event_log_path(); @@ -1321,7 +1321,7 @@ ClusterManagerPtr ProdClusterManagerFactory::clusterManagerFromProto( const envoy::config::bootstrap::v3::Bootstrap& bootstrap) { return ClusterManagerPtr{new ClusterManagerImpl( bootstrap, *this, stats_, tls_, runtime_, random_, local_info_, log_manager_, - main_thread_dispatcher_, admin_, validation_context_, api_, http_context_)}; + main_thread_dispatcher_, admin_, validation_context_, api_, http_context_, grpc_context_)}; } Http::ConnectionPool::InstancePtr ProdClusterManagerFactory::allocateConnPool( diff --git a/source/common/upstream/cluster_manager_impl.h b/source/common/upstream/cluster_manager_impl.h index f2cddab32797..707cc1ca476e 100644 --- a/source/common/upstream/cluster_manager_impl.h +++ b/source/common/upstream/cluster_manager_impl.h @@ -39,19 +39,17 @@ namespace Upstream { */ class ProdClusterManagerFactory : public ClusterManagerFactory { public: - ProdClusterManagerFactory(Server::Admin& admin, Runtime::Loader& runtime, Stats::Store& stats, - ThreadLocal::Instance& tls, Runtime::RandomGenerator& random, - Network::DnsResolverSharedPtr dns_resolver, - Ssl::ContextManager& ssl_context_manager, - Event::Dispatcher& main_thread_dispatcher, - const LocalInfo::LocalInfo& local_info, - Secret::SecretManager& secret_manager, - ProtobufMessage::ValidationContext& validation_context, Api::Api& api, - Http::Context& http_context, AccessLog::AccessLogManager& log_manager, - Singleton::Manager& singleton_manager) + ProdClusterManagerFactory( + Server::Admin& admin, Runtime::Loader& runtime, Stats::Store& stats, + ThreadLocal::Instance& tls, Runtime::RandomGenerator& random, + Network::DnsResolverSharedPtr dns_resolver, Ssl::ContextManager& ssl_context_manager, + Event::Dispatcher& main_thread_dispatcher, const LocalInfo::LocalInfo& local_info, + Secret::SecretManager& secret_manager, ProtobufMessage::ValidationContext& validation_context, + Api::Api& api, Http::Context& http_context, Grpc::Context& grpc_context, + AccessLog::AccessLogManager& log_manager, Singleton::Manager& singleton_manager) : main_thread_dispatcher_(main_thread_dispatcher), validation_context_(validation_context), - api_(api), http_context_(http_context), admin_(admin), runtime_(runtime), stats_(stats), - tls_(tls), random_(random), dns_resolver_(dns_resolver), + api_(api), http_context_(http_context), grpc_context_(grpc_context), admin_(admin), + runtime_(runtime), stats_(stats), tls_(tls), random_(random), dns_resolver_(dns_resolver), ssl_context_manager_(ssl_context_manager), local_info_(local_info), secret_manager_(secret_manager), log_manager_(log_manager), singleton_manager_(singleton_manager) {} @@ -80,6 +78,7 @@ class ProdClusterManagerFactory : public ClusterManagerFactory { ProtobufMessage::ValidationContext& validation_context_; Api::Api& api_; Http::Context& http_context_; + Grpc::Context& grpc_context_; Server::Admin& admin_; Runtime::Loader& runtime_; Stats::Store& stats_; @@ -186,7 +185,7 @@ class ClusterManagerImpl : public ClusterManager, Logger::Loggablecounter({stats_->invalid_req_body_}).inc(); + stats_->incCounter({stats_->invalid_req_body_}); } } } @@ -90,7 +90,7 @@ void DynamoFilter::onEncodeComplete(const Buffer::Instance& data) { } } catch (const Json::Exception&) { // Body parsing failed. This should not happen, just put a stat for that. - stats_->counter({stats_->invalid_resp_body_}).inc(); + stats_->incCounter({stats_->invalid_resp_body_}); } } } @@ -160,15 +160,15 @@ void DynamoFilter::chargeBasicStats(uint64_t status) { if (!operation_.empty()) { chargeStatsPerEntity(operation_, "operation", status); } else { - stats_->counter({stats_->operation_missing_}).inc(); + stats_->incCounter({stats_->operation_missing_}); } if (!table_descriptor_.table_name.empty()) { chargeStatsPerEntity(table_descriptor_.table_name, "table", status); } else if (table_descriptor_.is_single_table) { - stats_->counter({stats_->table_missing_}).inc(); + stats_->incCounter({stats_->table_missing_}); } else { - stats_->counter({stats_->multiple_tables_}).inc(); + stats_->incCounter({stats_->multiple_tables_}); } } @@ -189,22 +189,18 @@ void DynamoFilter::chargeStatsPerEntity(const std::string& entity, const std::st const Stats::StatName total_name = dynamic.add(absl::StrCat("upstream_rq_total_", status)); const Stats::StatName time_name = dynamic.add(absl::StrCat("upstream_rq_time_", status)); - stats_->counter({entity_type_name, entity_name, stats_->upstream_rq_total_}).inc(); + stats_->incCounter({entity_type_name, entity_name, stats_->upstream_rq_total_}); const Stats::StatName total_group = stats_->upstream_rq_total_groups_[group_index]; - stats_->counter({entity_type_name, entity_name, total_group}).inc(); - stats_->counter({entity_type_name, entity_name, total_name}).inc(); + stats_->incCounter({entity_type_name, entity_name, total_group}); + stats_->incCounter({entity_type_name, entity_name, total_name}); - stats_ - ->histogram({entity_type_name, entity_name, stats_->upstream_rq_time_}, - Stats::Histogram::Unit::Milliseconds) - .recordValue(latency.count()); + stats_->recordHistogram({entity_type_name, entity_name, stats_->upstream_rq_time_}, + Stats::Histogram::Unit::Milliseconds, latency.count()); const Stats::StatName time_group = stats_->upstream_rq_time_groups_[group_index]; - stats_ - ->histogram({entity_type_name, entity_name, time_group}, Stats::Histogram::Unit::Milliseconds) - .recordValue(latency.count()); - stats_ - ->histogram({entity_type_name, entity_name, time_name}, Stats::Histogram::Unit::Milliseconds) - .recordValue(latency.count()); + stats_->recordHistogram({entity_type_name, entity_name, time_group}, + Stats::Histogram::Unit::Milliseconds, latency.count()); + stats_->recordHistogram({entity_type_name, entity_name, time_name}, + Stats::Histogram::Unit::Milliseconds, latency.count()); } void DynamoFilter::chargeUnProcessedKeysStats(const Json::Object& json_body) { @@ -213,8 +209,8 @@ void DynamoFilter::chargeUnProcessedKeysStats(const Json::Object& json_body) { std::vector unprocessed_tables = RequestParser::parseBatchUnProcessedKeys(json_body); for (const std::string& unprocessed_table : unprocessed_tables) { Stats::StatNameDynamicStorage storage(unprocessed_table, stats_->symbolTable()); - stats_->counter({stats_->error_, storage.statName(), stats_->batch_failure_unprocessed_keys_}) - .inc(); + stats_->incCounter( + {stats_->error_, storage.statName(), stats_->batch_failure_unprocessed_keys_}); } } @@ -224,15 +220,13 @@ void DynamoFilter::chargeFailureSpecificStats(const Json::Object& json_body) { if (!error_type.empty()) { Stats::StatNameDynamicPool dynamic(stats_->symbolTable()); if (table_descriptor_.table_name.empty()) { - stats_->counter({stats_->error_, stats_->no_table_, dynamic.add(error_type)}).inc(); + stats_->incCounter({stats_->error_, stats_->no_table_, dynamic.add(error_type)}); } else { - stats_ - ->counter( - {stats_->error_, dynamic.add(table_descriptor_.table_name), dynamic.add(error_type)}) - .inc(); + stats_->incCounter( + {stats_->error_, dynamic.add(table_descriptor_.table_name), dynamic.add(error_type)}); } } else { - stats_->counter({stats_->empty_response_body_}).inc(); + stats_->incCounter({stats_->empty_response_body_}); } } diff --git a/source/extensions/filters/http/dynamo/dynamo_stats.cc b/source/extensions/filters/http/dynamo/dynamo_stats.cc index 3b0eb2a48474..468c77f0a959 100644 --- a/source/extensions/filters/http/dynamo/dynamo_stats.cc +++ b/source/extensions/filters/http/dynamo/dynamo_stats.cc @@ -54,15 +54,17 @@ Stats::SymbolTable::StoragePtr DynamoStats::addPrefix(const Stats::StatNameVec& return scope_.symbolTable().join(names_with_prefix); } -Stats::Counter& DynamoStats::counter(const Stats::StatNameVec& names) { +void DynamoStats::incCounter(const Stats::StatNameVec& names) { const Stats::SymbolTable::StoragePtr stat_name_storage = addPrefix(names); - return scope_.counterFromStatName(Stats::StatName(stat_name_storage.get())); + scope_.counterFromStatName(Stats::StatName(stat_name_storage.get())).inc(); } -Stats::Histogram& DynamoStats::histogram(const Stats::StatNameVec& names, - Stats::Histogram::Unit unit) { +void DynamoStats::recordHistogram(const Stats::StatNameVec& names, Stats::Histogram::Unit unit, + uint64_t value) { const Stats::SymbolTable::StoragePtr stat_name_storage = addPrefix(names); - return scope_.histogramFromStatName(Stats::StatName(stat_name_storage.get()), unit); + Stats::Histogram& histogram = + scope_.histogramFromStatName(Stats::StatName(stat_name_storage.get()), unit); + histogram.recordValue(value); } Stats::Counter& DynamoStats::buildPartitionStatCounter(const std::string& table_name, diff --git a/source/extensions/filters/http/dynamo/dynamo_stats.h b/source/extensions/filters/http/dynamo/dynamo_stats.h index 6d61fa532391..4241ec5dd711 100644 --- a/source/extensions/filters/http/dynamo/dynamo_stats.h +++ b/source/extensions/filters/http/dynamo/dynamo_stats.h @@ -16,8 +16,9 @@ class DynamoStats { public: DynamoStats(Stats::Scope& scope, const std::string& prefix); - Stats::Counter& counter(const Stats::StatNameVec& names); - Stats::Histogram& histogram(const Stats::StatNameVec& names, Stats::Histogram::Unit unit); + void incCounter(const Stats::StatNameVec& names); + void recordHistogram(const Stats::StatNameVec& names, Stats::Histogram::Unit unit, + uint64_t value); /** * Creates the partition id stats string. The stats format is diff --git a/source/server/config_validation/cluster_manager.cc b/source/server/config_validation/cluster_manager.cc index e7a8e2d7ea9f..4dbdc73a31ef 100644 --- a/source/server/config_validation/cluster_manager.cc +++ b/source/server/config_validation/cluster_manager.cc @@ -12,7 +12,8 @@ ClusterManagerPtr ValidationClusterManagerFactory::clusterManagerFromProto( const envoy::config::bootstrap::v3::Bootstrap& bootstrap) { return std::make_unique( bootstrap, *this, stats_, tls_, runtime_, random_, local_info_, log_manager_, - main_thread_dispatcher_, admin_, validation_context_, api_, http_context_, time_system_); + main_thread_dispatcher_, admin_, validation_context_, api_, http_context_, grpc_context_, + time_system_); } CdsApiPtr @@ -30,9 +31,10 @@ ValidationClusterManager::ValidationClusterManager( Runtime::RandomGenerator& random, const LocalInfo::LocalInfo& local_info, AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, Server::Admin& admin, ProtobufMessage::ValidationContext& validation_context, Api::Api& api, - Http::Context& http_context, Event::TimeSystem& time_system) + Http::Context& http_context, Grpc::Context& grpc_context, Event::TimeSystem& time_system) : ClusterManagerImpl(bootstrap, factory, stats, tls, runtime, random, local_info, log_manager, - main_thread_dispatcher, admin, validation_context, api, http_context), + main_thread_dispatcher, admin, validation_context, api, http_context, + grpc_context), async_client_(api, time_system) {} Http::ConnectionPool::Instance* diff --git a/source/server/config_validation/cluster_manager.h b/source/server/config_validation/cluster_manager.h index fb0b5c5f4742..07ea8f3f8c1c 100644 --- a/source/server/config_validation/cluster_manager.h +++ b/source/server/config_validation/cluster_manager.h @@ -27,13 +27,14 @@ class ValidationClusterManagerFactory : public ProdClusterManagerFactory { Network::DnsResolverSharedPtr dns_resolver, Ssl::ContextManager& ssl_context_manager, Event::Dispatcher& main_thread_dispatcher, const LocalInfo::LocalInfo& local_info, Secret::SecretManager& secret_manager, ProtobufMessage::ValidationContext& validation_context, - Api::Api& api, Http::Context& http_context, AccessLog::AccessLogManager& log_manager, - Singleton::Manager& singleton_manager, Event::TimeSystem& time_system) + Api::Api& api, Http::Context& http_context, Grpc::Context& grpc_context, + AccessLog::AccessLogManager& log_manager, Singleton::Manager& singleton_manager, + Event::TimeSystem& time_system) : ProdClusterManagerFactory(admin, runtime, stats, tls, random, dns_resolver, ssl_context_manager, main_thread_dispatcher, local_info, secret_manager, validation_context, api, http_context, - log_manager, singleton_manager), - time_system_(time_system) {} + grpc_context, log_manager, singleton_manager), + grpc_context_(grpc_context), time_system_(time_system) {} ClusterManagerPtr clusterManagerFromProto(const envoy::config::bootstrap::v3::Bootstrap& bootstrap) override; @@ -44,6 +45,7 @@ class ValidationClusterManagerFactory : public ProdClusterManagerFactory { ClusterManager& cm) override; private: + Grpc::Context& grpc_context_; Event::TimeSystem& time_system_; }; @@ -59,7 +61,8 @@ class ValidationClusterManager : public ClusterManagerImpl { AccessLog::AccessLogManager& log_manager, Event::Dispatcher& dispatcher, Server::Admin& admin, ProtobufMessage::ValidationContext& validation_context, Api::Api& api, - Http::Context& http_context, Event::TimeSystem& time_system); + Http::Context& http_context, Grpc::Context& grpc_context, + Event::TimeSystem& time_system); Http::ConnectionPool::Instance* httpConnPoolForCluster(const std::string&, ResourcePriority, Http::Protocol, diff --git a/source/server/config_validation/server.cc b/source/server/config_validation/server.cc index 68a69f6e721c..77e944513a83 100644 --- a/source/server/config_validation/server.cc +++ b/source/server/config_validation/server.cc @@ -99,7 +99,7 @@ void ValidationInstance::initialize(const Options& options, cluster_manager_factory_ = std::make_unique( admin(), runtime(), stats(), threadLocal(), random(), dnsResolver(), sslContextManager(), dispatcher(), localInfo(), *secret_manager_, messageValidationContext(), *api_, http_context_, - accessLogManager(), singletonManager(), time_system_); + grpc_context_, accessLogManager(), singletonManager(), time_system_); config_.initialize(bootstrap, *this, *cluster_manager_factory_); runtime_loader_->initialize(clusterManager()); http_context_.setTracer(config_.httpTracer()); diff --git a/source/server/server.cc b/source/server/server.cc index a0d3a3fe16e0..3da8bd8678c1 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -391,7 +391,8 @@ void InstanceImpl::initialize(const Options& options, cluster_manager_factory_ = std::make_unique( *admin_, Runtime::LoaderSingleton::get(), stats_store_, thread_local_, *random_generator_, dns_resolver_, *ssl_context_manager_, *dispatcher_, *local_info_, *secret_manager_, - messageValidationContext(), *api_, http_context_, access_log_manager_, *singleton_manager_); + messageValidationContext(), *api_, http_context_, grpc_context_, access_log_manager_, + *singleton_manager_); // Now the configuration gets parsed. The configuration may start setting // thread local data per above. See MainImpl::initialize() for why ConfigImpl @@ -413,7 +414,7 @@ void InstanceImpl::initialize(const Options& options, if (bootstrap_.has_hds_config()) { const auto& hds_config = bootstrap_.hds_config(); async_client_manager_ = std::make_unique( - *config_.clusterManager(), thread_local_, time_source_, *api_); + *config_.clusterManager(), thread_local_, time_source_, *api_, grpc_context_.statNames()); hds_delegate_ = std::make_unique( stats_store_, Config::Utility::factoryForGrpcApiConfigSource(*async_client_manager_, hds_config, diff --git a/test/common/grpc/async_client_manager_impl_test.cc b/test/common/grpc/async_client_manager_impl_test.cc index 63ff03a09656..ef09861d0da0 100644 --- a/test/common/grpc/async_client_manager_impl_test.cc +++ b/test/common/grpc/async_client_manager_impl_test.cc @@ -20,17 +20,20 @@ namespace { class AsyncClientManagerImplTest : public testing::Test { public: - AsyncClientManagerImplTest() : api_(Api::createApiForTest()) {} + AsyncClientManagerImplTest() + : api_(Api::createApiForTest()), stat_names_(scope_.symbolTable()), + async_client_manager_(cm_, tls_, test_time_.timeSystem(), *api_, stat_names_) {} Upstream::MockClusterManager cm_; NiceMock tls_; Stats::MockStore scope_; DangerousDeprecatedTestTime test_time_; Api::ApiPtr api_; + StatNames stat_names_; + AsyncClientManagerImpl async_client_manager_; }; TEST_F(AsyncClientManagerImplTest, EnvoyGrpcOk) { - AsyncClientManagerImpl async_client_manager(cm_, tls_, test_time_.timeSystem(), *api_); envoy::config::core::v3::GrpcService grpc_service; grpc_service.mutable_envoy_grpc()->set_cluster_name("foo"); @@ -41,21 +44,20 @@ TEST_F(AsyncClientManagerImplTest, EnvoyGrpcOk) { EXPECT_CALL(cluster, info()); EXPECT_CALL(*cluster.info_, addedViaApi()); - async_client_manager.factoryForGrpcService(grpc_service, scope_, false); + async_client_manager_.factoryForGrpcService(grpc_service, scope_, false); } TEST_F(AsyncClientManagerImplTest, EnvoyGrpcUnknown) { - AsyncClientManagerImpl async_client_manager(cm_, tls_, test_time_.timeSystem(), *api_); envoy::config::core::v3::GrpcService grpc_service; grpc_service.mutable_envoy_grpc()->set_cluster_name("foo"); EXPECT_CALL(cm_, clusters()); - EXPECT_THROW_WITH_MESSAGE(async_client_manager.factoryForGrpcService(grpc_service, scope_, false), - EnvoyException, "Unknown gRPC client cluster 'foo'"); + EXPECT_THROW_WITH_MESSAGE( + async_client_manager_.factoryForGrpcService(grpc_service, scope_, false), EnvoyException, + "Unknown gRPC client cluster 'foo'"); } TEST_F(AsyncClientManagerImplTest, EnvoyGrpcDynamicCluster) { - AsyncClientManagerImpl async_client_manager(cm_, tls_, test_time_.timeSystem(), *api_); envoy::config::core::v3::GrpcService grpc_service; grpc_service.mutable_envoy_grpc()->set_cluster_name("foo"); @@ -65,31 +67,31 @@ TEST_F(AsyncClientManagerImplTest, EnvoyGrpcDynamicCluster) { EXPECT_CALL(cm_, clusters()).WillOnce(Return(cluster_map)); EXPECT_CALL(cluster, info()); EXPECT_CALL(*cluster.info_, addedViaApi()).WillOnce(Return(true)); - EXPECT_THROW_WITH_MESSAGE(async_client_manager.factoryForGrpcService(grpc_service, scope_, false), - EnvoyException, "gRPC client cluster 'foo' is not static"); + EXPECT_THROW_WITH_MESSAGE( + async_client_manager_.factoryForGrpcService(grpc_service, scope_, false), EnvoyException, + "gRPC client cluster 'foo' is not static"); } TEST_F(AsyncClientManagerImplTest, GoogleGrpc) { EXPECT_CALL(scope_, createScope_("grpc.foo.")); - AsyncClientManagerImpl async_client_manager(cm_, tls_, test_time_.timeSystem(), *api_); envoy::config::core::v3::GrpcService grpc_service; grpc_service.mutable_google_grpc()->set_stat_prefix("foo"); #ifdef ENVOY_GOOGLE_GRPC - EXPECT_NE(nullptr, async_client_manager.factoryForGrpcService(grpc_service, scope_, false)); + EXPECT_NE(nullptr, async_client_manager_.factoryForGrpcService(grpc_service, scope_, false)); #else - EXPECT_THROW_WITH_MESSAGE(async_client_manager.factoryForGrpcService(grpc_service, scope_, false), - EnvoyException, "Google C++ gRPC client is not linked"); + EXPECT_THROW_WITH_MESSAGE( + async_client_manager_.factoryForGrpcService(grpc_service, scope_, false), EnvoyException, + "Google C++ gRPC client is not linked"); #endif } TEST_F(AsyncClientManagerImplTest, EnvoyGrpcUnknownOk) { - AsyncClientManagerImpl async_client_manager(cm_, tls_, test_time_.timeSystem(), *api_); envoy::config::core::v3::GrpcService grpc_service; grpc_service.mutable_envoy_grpc()->set_cluster_name("foo"); EXPECT_CALL(cm_, clusters()).Times(0); - ASSERT_NO_THROW(async_client_manager.factoryForGrpcService(grpc_service, scope_, true)); + ASSERT_NO_THROW(async_client_manager_.factoryForGrpcService(grpc_service, scope_, true)); } } // namespace diff --git a/test/common/grpc/google_async_client_impl_test.cc b/test/common/grpc/google_async_client_impl_test.cc index 57079a801436..776bcf44a55b 100644 --- a/test/common/grpc/google_async_client_impl_test.cc +++ b/test/common/grpc/google_async_client_impl_test.cc @@ -51,14 +51,16 @@ class EnvoyGoogleAsyncClientImplTest : public testing::Test { EnvoyGoogleAsyncClientImplTest() : stats_store_(new Stats::IsolatedStoreImpl), api_(Api::createApiForTest(*stats_store_)), dispatcher_(api_->allocateDispatcher()), scope_(stats_store_), - method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")) { + method_descriptor_(helloworld::Greeter::descriptor()->FindMethodByName("SayHello")), + stat_names_(scope_->symbolTable()) { + envoy::config::core::v3::GrpcService config; auto* google_grpc = config.mutable_google_grpc(); google_grpc->set_target_uri("fake_address"); google_grpc->set_stat_prefix("test_cluster"); tls_ = std::make_unique(*api_); grpc_client_ = std::make_unique(*dispatcher_, *tls_, stub_factory_, - scope_, config, *api_); + scope_, config, *api_, stat_names_); } DangerousDeprecatedTestTime test_time_; @@ -69,6 +71,7 @@ class EnvoyGoogleAsyncClientImplTest : public testing::Test { std::unique_ptr tls_; MockStubFactory stub_factory_; const Protobuf::MethodDescriptor* method_descriptor_; + StatNames stat_names_; AsyncClient grpc_client_; }; diff --git a/test/common/grpc/grpc_client_integration_test_harness.h b/test/common/grpc/grpc_client_integration_test_harness.h index 5dff4a7f6dd1..e276fc4d44cd 100644 --- a/test/common/grpc/grpc_client_integration_test_harness.h +++ b/test/common/grpc/grpc_client_integration_test_harness.h @@ -315,7 +315,8 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { google_tls_ = std::make_unique(*api_); GoogleGenericStubFactory stub_factory; return std::make_unique(*dispatcher_, *google_tls_, stub_factory, - stats_scope_, createGoogleGrpcConfig(), *api_); + stats_scope_, createGoogleGrpcConfig(), *api_, + google_grpc_stat_names_); #else NOT_REACHED_GCOVR_EXCL_LINE; #endif @@ -426,6 +427,7 @@ class GrpcClientIntegrationTest : public GrpcClientIntegrationParamTest { Event::DispatcherPtr dispatcher_; DispatcherHelper dispatcher_helper_{*dispatcher_}; Stats::ScopeSharedPtr stats_scope_{stats_store_}; + Grpc::StatNames google_grpc_stat_names_{stats_store_->symbolTable()}; TestMetadata service_wide_initial_metadata_; #ifdef ENVOY_GOOGLE_GRPC std::unique_ptr google_tls_; diff --git a/test/common/upstream/cluster_manager_impl_test.cc b/test/common/upstream/cluster_manager_impl_test.cc index e106471b119e..a6db18af064f 100644 --- a/test/common/upstream/cluster_manager_impl_test.cc +++ b/test/common/upstream/cluster_manager_impl_test.cc @@ -33,13 +33,14 @@ std::string clustersJson(const std::vector& clusters) { class ClusterManagerImplTest : public testing::Test { public: ClusterManagerImplTest() - : api_(Api::createApiForTest()), http_context_(factory_.stats_.symbolTable()) {} + : api_(Api::createApiForTest()), http_context_(factory_.stats_.symbolTable()), + grpc_context_(factory_.stats_.symbolTable()) {} void create(const envoy::config::bootstrap::v3::Bootstrap& bootstrap) { cluster_manager_ = std::make_unique( bootstrap, factory_, factory_.stats_, factory_.tls_, factory_.runtime_, factory_.random_, factory_.local_info_, log_manager_, factory_.dispatcher_, admin_, validation_context_, - *api_, http_context_); + *api_, http_context_, grpc_context_); } void createWithLocalClusterUpdate(const bool enable_merge_window = true) { @@ -74,7 +75,7 @@ class ClusterManagerImplTest : public testing::Test { cluster_manager_ = std::make_unique( bootstrap, factory_, factory_.stats_, factory_.tls_, factory_.runtime_, factory_.random_, factory_.local_info_, log_manager_, factory_.dispatcher_, admin_, validation_context_, - *api_, local_cluster_update_, local_hosts_removed_, http_context_); + *api_, local_cluster_update_, local_hosts_removed_, http_context_, grpc_context_); } void checkStats(uint64_t added, uint64_t modified, uint64_t removed, uint64_t active, @@ -124,6 +125,7 @@ class ClusterManagerImplTest : public testing::Test { MockLocalClusterUpdate local_cluster_update_; MockLocalHostsRemoved local_hosts_removed_; Http::ContextImpl http_context_; + Grpc::ContextImpl grpc_context_; }; envoy::config::bootstrap::v3::Bootstrap defaultConfig() { diff --git a/test/common/upstream/test_cluster_manager.h b/test/common/upstream/test_cluster_manager.h index 3e99267b689f..956ca894dd99 100644 --- a/test/common/upstream/test_cluster_manager.h +++ b/test/common/upstream/test_cluster_manager.h @@ -163,9 +163,10 @@ class TestClusterManagerImpl : public ClusterManagerImpl { AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, Server::Admin& admin, ProtobufMessage::ValidationContext& validation_context, Api::Api& api, - Http::Context& http_context) + Http::Context& http_context, Grpc::Context& grpc_context) : ClusterManagerImpl(bootstrap, factory, stats, tls, runtime, random, local_info, log_manager, - main_thread_dispatcher, admin, validation_context, api, http_context) {} + main_thread_dispatcher, admin, validation_context, api, http_context, + grpc_context) {} std::map> activeClusters() { std::map> clusters; @@ -187,10 +188,10 @@ class MockedUpdatedClusterManagerImpl : public TestClusterManagerImpl { AccessLog::AccessLogManager& log_manager, Event::Dispatcher& main_thread_dispatcher, Server::Admin& admin, ProtobufMessage::ValidationContext& validation_context, Api::Api& api, MockLocalClusterUpdate& local_cluster_update, MockLocalHostsRemoved& local_hosts_removed, - Http::Context& http_context) + Http::Context& http_context, Grpc::Context& grpc_context) : TestClusterManagerImpl(bootstrap, factory, stats, tls, runtime, random, local_info, log_manager, main_thread_dispatcher, admin, validation_context, api, - http_context), + http_context, grpc_context), local_cluster_update_(local_cluster_update), local_hosts_removed_(local_hosts_removed) {} protected: diff --git a/test/config_test/config_test.cc b/test/config_test/config_test.cc index 2d7023849595..50a39cbaad25 100644 --- a/test/config_test/config_test.cc +++ b/test/config_test/config_test.cc @@ -87,8 +87,8 @@ class ConfigTest { server_.admin(), server_.runtime(), server_.stats(), server_.threadLocal(), server_.random(), server_.dnsResolver(), ssl_context_manager_, server_.dispatcher(), server_.localInfo(), server_.secretManager(), server_.messageValidationContext(), *api_, - server_.httpContext(), server_.accessLogManager(), server_.singletonManager(), - time_system_); + server_.httpContext(), server_.grpcContext(), server_.accessLogManager(), + server_.singletonManager(), time_system_); ON_CALL(server_, clusterManager()).WillByDefault(Invoke([&]() -> Upstream::ClusterManager& { return *main_config.clusterManager(); diff --git a/test/extensions/clusters/aggregate/cluster_update_test.cc b/test/extensions/clusters/aggregate/cluster_update_test.cc index ff7b0a4ccb14..f040c6b88c5d 100644 --- a/test/extensions/clusters/aggregate/cluster_update_test.cc +++ b/test/extensions/clusters/aggregate/cluster_update_test.cc @@ -31,13 +31,14 @@ envoy::config::bootstrap::v3::Bootstrap parseBootstrapFromV2Yaml(const std::stri class AggregateClusterUpdateTest : public testing::Test { public: - AggregateClusterUpdateTest() : http_context_(stats_store_.symbolTable()) {} + AggregateClusterUpdateTest() + : http_context_(stats_store_.symbolTable()), grpc_context_(stats_store_.symbolTable()) {} void initialize(const std::string& yaml_config) { cluster_manager_ = std::make_unique( parseBootstrapFromV2Yaml(yaml_config), factory_, factory_.stats_, factory_.tls_, factory_.runtime_, factory_.random_, factory_.local_info_, log_manager_, - factory_.dispatcher_, admin_, validation_context_, *api_, http_context_); + factory_.dispatcher_, admin_, validation_context_, *api_, http_context_, grpc_context_); EXPECT_EQ(cluster_manager_->activeClusters().size(), 1); cluster_ = cluster_manager_->get("aggregate_cluster"); } @@ -53,6 +54,7 @@ class AggregateClusterUpdateTest : public testing::Test { std::unique_ptr cluster_manager_; AccessLog::MockAccessLogManager log_manager_; Http::ContextImpl http_context_; + Grpc::ContextImpl grpc_context_; const std::string default_yaml_config_ = R"EOF( static_resources: @@ -258,7 +260,7 @@ TEST_F(AggregateClusterUpdateTest, InitializeAggregateClusterAfterOtherClusters) cluster_manager_ = std::make_unique( parseBootstrapFromV2Yaml(config), factory_, factory_.stats_, factory_.tls_, factory_.runtime_, factory_.random_, factory_.local_info_, log_manager_, factory_.dispatcher_, admin_, - validation_context_, *api_, http_context_); + validation_context_, *api_, http_context_, grpc_context_); EXPECT_EQ(cluster_manager_->activeClusters().size(), 2); cluster_ = cluster_manager_->get("aggregate_cluster"); auto primary = cluster_manager_->get("primary"); diff --git a/test/server/config_validation/cluster_manager_test.cc b/test/server/config_validation/cluster_manager_test.cc index c1b3bf373802..cd6cfdbb9b56 100644 --- a/test/server/config_validation/cluster_manager_test.cc +++ b/test/server/config_validation/cluster_manager_test.cc @@ -43,13 +43,14 @@ TEST(ValidationClusterManagerTest, MockedMethods) { LocalInfo::MockLocalInfo local_info; NiceMock admin; Http::ContextImpl http_context(stats_store.symbolTable()); + Grpc::ContextImpl grpc_context(stats_store.symbolTable()); AccessLog::MockAccessLogManager log_manager; Singleton::ManagerImpl singleton_manager{Thread::threadFactoryForTest()}; - ValidationClusterManagerFactory factory(admin, runtime, stats_store, tls, random, dns_resolver, - ssl_context_manager, dispatcher, local_info, - secret_manager, validation_context, *api, http_context, - log_manager, singleton_manager, time_system); + ValidationClusterManagerFactory factory( + admin, runtime, stats_store, tls, random, dns_resolver, ssl_context_manager, dispatcher, + local_info, secret_manager, validation_context, *api, http_context, grpc_context, log_manager, + singleton_manager, time_system); const envoy::config::bootstrap::v3::Bootstrap bootstrap; ClusterManagerPtr cluster_manager = factory.clusterManagerFromProto(bootstrap); diff --git a/test/server/configuration_impl_test.cc b/test/server/configuration_impl_test.cc index 5e16abeaa2aa..b6aa4e96767d 100644 --- a/test/server/configuration_impl_test.cc +++ b/test/server/configuration_impl_test.cc @@ -58,12 +58,12 @@ class ConfigurationImplTest : public testing::Test { protected: ConfigurationImplTest() : api_(Api::createApiForTest()), - cluster_manager_factory_(server_.admin(), server_.runtime(), server_.stats(), - server_.threadLocal(), server_.random(), server_.dnsResolver(), - server_.sslContextManager(), server_.dispatcher(), - server_.localInfo(), server_.secretManager(), - server_.messageValidationContext(), *api_, server_.httpContext(), - server_.accessLogManager(), server_.singletonManager()) {} + cluster_manager_factory_( + server_.admin(), server_.runtime(), server_.stats(), server_.threadLocal(), + server_.random(), server_.dnsResolver(), server_.sslContextManager(), + server_.dispatcher(), server_.localInfo(), server_.secretManager(), + server_.messageValidationContext(), *api_, server_.httpContext(), server_.grpcContext(), + server_.accessLogManager(), server_.singletonManager()) {} void addStatsdFakeClusterConfig(envoy::config::metrics::v3::StatsSink& sink) { envoy::config::metrics::v3::StatsdSink statsd_sink; diff --git a/tools/code_format/check_format.py b/tools/code_format/check_format.py index 140dcaa2a915..4fbd7d94171e 100755 --- a/tools/code_format/check_format.py +++ b/tools/code_format/check_format.py @@ -595,7 +595,8 @@ def checkSourceLine(line, file_path, reportError): reportError("Don't use Protobuf::util::JsonStringToMessage, use TestUtility::loadFromJson.") if isInSubdir(file_path, 'source') and file_path.endswith('.cc') and \ - ('.counter(' in line or '.gauge(' in line or '.histogram(' in line): + ('.counter(' in line or '.gauge(' in line or '.histogram(' in line or \ + '->counter(' in line or '->gauge(' in line or '->histogram(' in line): reportError("Don't lookup stats by name at runtime; use StatName saved during construction") if re.search("envoy::[a-z0-9_:]+::[A-Z][a-z]\w*_\w*_[A-Z]{2}", line):