From e443758a8bc143daa892e98a3e2ff06b91deeaa8 Mon Sep 17 00:00:00 2001 From: John Plevyak Date: Mon, 12 Aug 2019 16:53:43 -0700 Subject: [PATCH] Make the stats prefix configurable for WebAssembly services. (#127) * Make the stats prefix configurable for WebAssembly services. Signed-off-by: John Plevyak --- api/envoy/config/wasm/v2/wasm.proto | 2 ++ include/envoy/server/wasm_config.h | 9 +++++++-- source/extensions/wasm/config.cc | 4 ++-- source/server/server.cc | 10 +++++++--- source/server/wasm_config_impl.h | 12 +++++++----- test/extensions/wasm/config_test.cc | 12 ++++++------ 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/api/envoy/config/wasm/v2/wasm.proto b/api/envoy/config/wasm/v2/wasm.proto index e2a118439186..e9a007387917 100644 --- a/api/envoy/config/wasm/v2/wasm.proto +++ b/api/envoy/config/wasm/v2/wasm.proto @@ -39,4 +39,6 @@ message WasmConfig { // If true, create a single VM rather than creating one VM per silo. Such a singleton can // not be used with filters. bool singleton = 5; + // If set add 'stat_prefix' as a prefix to all stats. + string stat_prefix = 6; } diff --git a/include/envoy/server/wasm_config.h b/include/envoy/server/wasm_config.h index 8996d7c72348..dd204ef757dd 100644 --- a/include/envoy/server/wasm_config.h +++ b/include/envoy/server/wasm_config.h @@ -38,9 +38,14 @@ class WasmFactoryContext { */ virtual Api::Api& api() PURE; /** - * @return Stats::ScopeSharedPtr shared by all VMs. + * @return Stats::Scope the service's stats scope. */ - virtual Stats::ScopeSharedPtr scope() PURE; + virtual Stats::Scope& scope() PURE; + /** + * @return Stats::ScopeSharedPtr the service's owned Stats::Scope if stats_prefix was provided or + * nullptr if not. + */ + virtual Stats::ScopeSharedPtr owned_scope() PURE; /** * @return information about the local environment the server is running in. */ diff --git a/source/extensions/wasm/config.cc b/source/extensions/wasm/config.cc index 79b5f0cee7bf..73ce1ad3217f 100644 --- a/source/extensions/wasm/config.cc +++ b/source/extensions/wasm/config.cc @@ -23,8 +23,8 @@ Server::WasmSharedPtr WasmFactory::createWasm(const envoy::config::wasm::v2::Was auto root_id = config.root_id(); auto base_wasm = Common::Wasm::createWasm(config.vm_id(), config.vm_config(), root_id, context.clusterManager(), context.dispatcher(), - context.api(), *context.scope(), context.localInfo(), - nullptr /* listener_metadata */, context.scope()); + context.api(), context.scope(), context.localInfo(), + nullptr /* listener_metadata */, context.owned_scope()); if (config.singleton()) { // Return the WASM VM which will be stored as a singleton by the Server. auto root_context = base_wasm->start(root_id, config.vm_config().configuration()); diff --git a/source/server/server.cc b/source/server/server.cc index d96f078d8cf5..403d0d29f1c7 100644 --- a/source/server/server.cc +++ b/source/server/server.cc @@ -386,10 +386,14 @@ void InstanceImpl::initialize(const Options& options, if (bootstrap_.wasm_service_size() > 0) { auto factory = Registry::FactoryRegistry::getFactory("envoy.wasm"); if (factory) { - auto scope = Stats::ScopeSharedPtr(stats_store_.createScope("wasm.")); - Configuration::WasmFactoryContextImpl wasm_factory_context( - clusterManager(), *dispatcher_, thread_local_, api(), scope, *local_info_); for (auto& config : bootstrap_.wasm_service()) { + Stats::ScopeSharedPtr scope; + if (!config.stat_prefix().empty()) { + scope = Stats::ScopeSharedPtr(stats_store_.createScope(config.stat_prefix())); + } + Configuration::WasmFactoryContextImpl wasm_factory_context( + clusterManager(), *dispatcher_, thread_local_, api(), stats_store_, scope, + *local_info_); auto wasm = factory->createWasm(config, wasm_factory_context); if (wasm) { // If not nullptr, this is a singleton WASM service. diff --git a/source/server/wasm_config_impl.h b/source/server/wasm_config_impl.h index e0cef093c9f2..4d7e18f69c52 100644 --- a/source/server/wasm_config_impl.h +++ b/source/server/wasm_config_impl.h @@ -10,16 +10,17 @@ namespace Configuration { class WasmFactoryContextImpl : public WasmFactoryContext { public: WasmFactoryContextImpl(Upstream::ClusterManager& cluster_manager, Event::Dispatcher& dispatcher, - ThreadLocal::SlotAllocator& tls, Api::Api& api, - Stats::ScopeSharedPtr scope, const LocalInfo::LocalInfo& local_info) + ThreadLocal::SlotAllocator& tls, Api::Api& api, Stats::Scope& scope, + Stats::ScopeSharedPtr owned_scope, const LocalInfo::LocalInfo& local_info) : cluster_manager_(cluster_manager), dispatcher_(dispatcher), tls_(tls), api_(api), - scope_(scope), local_info_(local_info) {} + scope_(scope), owned_scope_(owned_scope), local_info_(local_info) {} Upstream::ClusterManager& clusterManager() override { return cluster_manager_; } Event::Dispatcher& dispatcher() override { return dispatcher_; } ThreadLocal::SlotAllocator& threadLocal() override { return tls_; } Api::Api& api() override { return api_; } - Stats::ScopeSharedPtr scope() override { return scope_; } + Stats::Scope& scope() override { return scope_; } + Stats::ScopeSharedPtr owned_scope() override { return owned_scope_; } const LocalInfo::LocalInfo& localInfo() const override { return local_info_; } private: @@ -27,7 +28,8 @@ class WasmFactoryContextImpl : public WasmFactoryContext { Event::Dispatcher& dispatcher_; ThreadLocal::SlotAllocator& tls_; Api::Api& api_; - Stats::ScopeSharedPtr scope_; + Stats::Scope& scope_; + Stats::ScopeSharedPtr owned_scope_; const LocalInfo::LocalInfo& local_info_; }; diff --git a/test/extensions/wasm/config_test.cc b/test/extensions/wasm/config_test.cc index 7adf5f6bab3a..bd85c280754f 100644 --- a/test/extensions/wasm/config_test.cc +++ b/test/extensions/wasm/config_test.cc @@ -53,7 +53,7 @@ TEST_P(WasmFactoryTest, CreateWasmFromWASM) { Api::ApiPtr api = Api::createApiForTest(stats_store); auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); Server::Configuration::WasmFactoryContextImpl context(cluster_manager, dispatcher, tls, *api, - scope, local_info); + *scope, scope, local_info); auto wasm = factory->createWasm(config, context); EXPECT_NE(wasm, nullptr); } @@ -75,7 +75,7 @@ TEST_P(WasmFactoryTest, CreateWasmFromPrecompiledWASM) { Api::ApiPtr api = Api::createApiForTest(stats_store); auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); Server::Configuration::WasmFactoryContextImpl context(cluster_manager, dispatcher, tls, *api, - scope, local_info); + *scope, scope, local_info); auto wasm = factory->createWasm(config, context); EXPECT_NE(wasm, nullptr); } @@ -96,7 +96,7 @@ TEST_P(WasmFactoryTest, CreateWasmFromWASMPerThread) { Api::ApiPtr api = Api::createApiForTest(stats_store); auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); Server::Configuration::WasmFactoryContextImpl context(cluster_manager, dispatcher, tls, *api, - scope, local_info); + *scope, scope, local_info); auto wasm = factory->createWasm(config, context); EXPECT_EQ(wasm, nullptr); } @@ -118,7 +118,7 @@ TEST_P(WasmFactoryTest, MissingImport) { Api::ApiPtr api = Api::createApiForTest(stats_store); auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); Server::Configuration::WasmFactoryContextImpl context(cluster_manager, dispatcher, tls, *api, - scope, local_info); + *scope, scope, local_info); EXPECT_THROW_WITH_REGEX(factory->createWasm(config, context), Extensions::Common::Wasm::WasmException, "Failed to load WASM module due to a missing import: env._missing.*"); @@ -143,7 +143,7 @@ TEST_P(WasmFactoryTest, UnspecifiedRuntime) { Api::ApiPtr api = Api::createApiForTest(stats_store); auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); Server::Configuration::WasmFactoryContextImpl context(cluster_manager, dispatcher, tls, *api, - scope, local_info); + *scope, scope, local_info); #if defined(ENVOY_WASM_V8) == defined(ENVOY_WASM_WAVM) EXPECT_THROW_WITH_MESSAGE(factory->createWasm(config, context), Extensions::Common::Wasm::WasmException, @@ -171,7 +171,7 @@ TEST_P(WasmFactoryTest, UnknownRuntime) { Api::ApiPtr api = Api::createApiForTest(stats_store); auto scope = Stats::ScopeSharedPtr(stats_store.createScope("wasm.")); Server::Configuration::WasmFactoryContextImpl context(cluster_manager, dispatcher, tls, *api, - scope, local_info); + *scope, scope, local_info); EXPECT_THROW_WITH_MESSAGE(factory->createWasm(config, context), Extensions::Common::Wasm::WasmException, "Failed to create WASM VM using envoy.wasm.vm.invalid runtime. "