Skip to content

Commit

Permalink
Add support for proxy_log_destination ABI
Browse files Browse the repository at this point in the history
Signed-off-by: Vikas Choudhary <choudharyvikas16@gmail.com>
  • Loading branch information
vikaschoudhary16 committed Mar 27, 2023
1 parent 489a41f commit c33b884
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 8 deletions.
15 changes: 14 additions & 1 deletion api/envoy/extensions/wasm/v3/wasm.proto
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ message SanitizationConfig {
}

// Configuration for a Wasm VM.
// [#next-free-field: 8]
// [#next-free-field: 9]
message VmConfig {
// An ID which will be used along with a hash of the wasm code (or the name of the registered Null
// VM plugin) to determine which VM will be used for the plugin. All plugins which use the same
Expand Down Expand Up @@ -106,6 +106,19 @@ message VmConfig {
// vars just like when you do on native platforms.
// Warning: Envoy rejects the configuration if there's conflict of key space.
EnvironmentVariables environment_variables = 7;

// Specifies the log destination for the plugin.
// If not specified, the plugin will log to the default Envoy log
// example: "audit-logs": { file_path: "/var/log/audit.log" }
map<string, LogDestination> log_destination = 8;
}

message LogDestination {
// Target destination for the log messages from the plugin.
oneof target {
string file_path = 1;
// TODO: Remote logging service
}
}

message EnvironmentVariables {
Expand Down
30 changes: 30 additions & 0 deletions source/extensions/common/wasm/plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,36 @@ WasmConfig::WasmConfig(const envoy::extensions::wasm::v3::PluginConfig& config)
}
}
}

if (config.vm_config().runtime() == "envoy.wasm.runtime.null" &&
!config_.vm_config().log_destination().empty()) {
throw EnvoyException("envoy.extensions.wasm.v3.VmConfig.log_destination must "
"not be set for NullVm.");
}
// Check key duplication.
absl::flat_hash_set<std::string> keys;
for (const auto& ld : config_.vm_config().log_destination()) {
keys.insert(ld.first);
}
for (const auto& ld : config_.vm_config().log_destination()) {
if (!keys.insert(ld.first).second) {
throw EnvoyException(fmt::format("Key {} is duplicated in "
"envoy.extensions.wasm.v3.VmConfig.log_destination for {}. "
"All the keys must be unique.",
ld.first, config_.name()));
}
}
// Construct merged key-value pairs. Also check for boundary conditions
// (e.g. empty file path).
for (const auto& ld : config_.vm_config().log_destination()) {
if (ld.second.file_path().empty()) {
throw EnvoyException(
fmt::format("Key {} value envoy.extensions.wasm.v3.VmConfig.LogDestination.file_path "
"must not be empty for {}.",
ld.first, config_.name()));
}
log_destinations_[ld.first] = ld.second.file_path();
}
}

} // namespace Wasm
Expand Down
3 changes: 3 additions & 0 deletions source/extensions/common/wasm/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ namespace Wasm {

// clang-format off
using EnvironmentVariableMap = std::unordered_map<std::string, std::string>;
using LogDestinationMap = std::unordered_map<std::string, std::string>;
// clang-format on

class WasmConfig {
Expand All @@ -26,11 +27,13 @@ class WasmConfig {
const envoy::extensions::wasm::v3::PluginConfig& config() { return config_; }
proxy_wasm::AllowedCapabilitiesMap& allowedCapabilities() { return allowed_capabilities_; }
EnvironmentVariableMap& environmentVariables() { return envs_; }
LogDestinationMap& logDestinations() { return log_destinations_; }

private:
const envoy::extensions::wasm::v3::PluginConfig config_;
proxy_wasm::AllowedCapabilitiesMap allowed_capabilities_{};
EnvironmentVariableMap envs_;
LogDestinationMap log_destinations_;
};

using WasmConfigPtr = std::unique_ptr<WasmConfig>;
Expand Down
16 changes: 9 additions & 7 deletions source/extensions/common/wasm/wasm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,11 @@ void Wasm::initializeLifecycle(Server::ServerLifecycleNotifier& lifecycle_notifi

Wasm::Wasm(WasmConfig& config, absl::string_view vm_key, const Stats::ScopeSharedPtr& scope,
Api::Api& api, Upstream::ClusterManager& cluster_manager, Event::Dispatcher& dispatcher)
: WasmBase(
createWasmVm(config.config().vm_config().runtime()), config.config().vm_config().vm_id(),
MessageUtil::anyToBytes(config.config().vm_config().configuration()),
toStdStringView(vm_key), config.environmentVariables(), config.allowedCapabilities()),
: WasmBase(createWasmVm(config.config().vm_config().runtime()),
config.config().vm_config().vm_id(),
MessageUtil::anyToBytes(config.config().vm_config().configuration()),
toStdStringView(vm_key), config.environmentVariables(), config.logDestinations(),
config.allowedCapabilities()),
scope_(scope), api_(api), stat_name_pool_(scope_->symbolTable()),
custom_stat_namespace_(stat_name_pool_.add(CustomStatNamespace)),
cluster_manager_(cluster_manager), dispatcher_(dispatcher),
Expand Down Expand Up @@ -330,7 +331,8 @@ bool createWasm(const PluginSharedPtr& plugin, const Stats::ScopeSharedPtr& scop
code_cache = new std::remove_reference<decltype(*code_cache)>::type;
}
Stats::ScopeSharedPtr create_wasm_stats_scope = stats_handler.lockAndCreateStats(scope);
// Remove entries older than CODE_CACHE_SECONDS_CACHING_TTL except for our target.
// Remove entries older than CODE_CACHE_SECONDS_CACHING_TTL except for our
// target.
for (auto it = code_cache->begin(); it != code_cache->end();) {
if (now - it->second.use_time > std::chrono::seconds(CODE_CACHE_SECONDS_CACHING_TTL) &&
it->first != vm_config.code().remote().sha256()) {
Expand Down Expand Up @@ -423,8 +425,8 @@ bool createWasm(const PluginSharedPtr& plugin, const Stats::ScopeSharedPtr& scop
}
stats_handler.onRemoteCacheEntriesChanged(code_cache->size());
}
// NB: xDS currently does not support failing asynchronously, so we fail immediately
// if remote Wasm code is not cached and do a background fill.
// NB: xDS currently does not support failing asynchronously, so we fail
// immediately if remote Wasm code is not cached and do a background fill.
if (!vm_config.nack_on_code_cache_miss()) {
if (code.empty()) {
ENVOY_LOG_TO_LOGGER(Envoy::Logger::Registry::getLog(Envoy::Logger::Id::wasm), trace,
Expand Down

0 comments on commit c33b884

Please sign in to comment.