Skip to content

Commit c002720

Browse files
Add implementation for new ABI proxy_log_destination
1 parent 609960c commit c002720

File tree

6 files changed

+67
-22
lines changed

6 files changed

+67
-22
lines changed

Diff for: include/proxy-wasm/exports.h

+14-12
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace exports {
6767
Word get_configuration(Word value_ptr_ptr, Word value_size_ptr);
6868
Word get_status(Word code_ptr, Word value_ptr_ptr, Word value_size_ptr);
6969
Word log(Word level, Word address, Word size);
70+
Word log_destination(Word dest, Word dest_size, Word level, Word address, Word size);
7071
Word get_log_level(Word result_level_uint32_ptr);
7172
Word get_property(Word path_ptr, Word path_size, Word value_ptr_ptr, Word value_size_ptr);
7273
Word set_property(Word key_ptr, Word key_size, Word value_ptr, Word value_size);
@@ -152,18 +153,19 @@ void emscripten_notify_memory_growth(Word);
152153
// Support for embedders, not exported to Wasm.
153154

154155
#define FOR_ALL_HOST_FUNCTIONS(_f) \
155-
_f(log) _f(get_status) _f(set_property) _f(get_property) _f(send_local_response) \
156-
_f(get_shared_data) _f(set_shared_data) _f(register_shared_queue) _f(resolve_shared_queue) \
157-
_f(dequeue_shared_queue) _f(enqueue_shared_queue) _f(get_header_map_value) \
158-
_f(add_header_map_value) _f(replace_header_map_value) _f(remove_header_map_value) \
159-
_f(get_header_map_pairs) _f(set_header_map_pairs) _f(get_header_map_size) \
160-
_f(get_buffer_status) _f(get_buffer_bytes) _f(set_buffer_bytes) \
161-
_f(http_call) _f(grpc_call) _f(grpc_stream) _f(grpc_close) \
162-
_f(grpc_cancel) _f(grpc_send) _f(set_tick_period_milliseconds) \
163-
_f(get_current_time_nanoseconds) _f(define_metric) \
164-
_f(increment_metric) _f(record_metric) _f(get_metric) \
165-
_f(set_effective_context) _f(done) \
166-
_f(call_foreign_function)
156+
_f(log) _f(log_destination) _f(get_status) _f(set_property) _f(get_property) \
157+
_f(send_local_response) _f(get_shared_data) _f(set_shared_data) _f(register_shared_queue) \
158+
_f(resolve_shared_queue) _f(dequeue_shared_queue) _f(enqueue_shared_queue) \
159+
_f(get_header_map_value) _f(add_header_map_value) _f(replace_header_map_value) \
160+
_f(remove_header_map_value) _f(get_header_map_pairs) _f(set_header_map_pairs) \
161+
_f(get_header_map_size) _f(get_buffer_status) _f(get_buffer_bytes) \
162+
_f(set_buffer_bytes) _f(http_call) _f(grpc_call) _f(grpc_stream) \
163+
_f(grpc_close) _f(grpc_cancel) _f(grpc_send) \
164+
_f(set_tick_period_milliseconds) \
165+
_f(get_current_time_nanoseconds) _f(define_metric) \
166+
_f(increment_metric) _f(record_metric) _f(get_metric) \
167+
_f(set_effective_context) _f(done) \
168+
_f(call_foreign_function)
167169

168170
#define FOR_ALL_HOST_FUNCTIONS_ABI_SPECIFIC(_f) \
169171
_f(get_configuration) _f(continue_request) _f(continue_response) _f(clear_route_cache) \

Diff for: include/proxy-wasm/wasm.h

+6-2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
5151
WasmBase(std::unique_ptr<WasmVm> wasm_vm, std::string_view vm_id,
5252
std::string_view vm_configuration, std::string_view vm_key,
5353
std::unordered_map<std::string, std::string> envs,
54+
std::unordered_map<std::string, std::string> log_dest,
5455
AllowedCapabilitiesMap allowed_capabilities);
5556
WasmBase(const std::shared_ptr<WasmHandleBase> &base_wasm_handle, const WasmVmFactory &factory);
5657
virtual ~WasmBase();
@@ -136,6 +137,9 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
136137
AbiVersion abiVersion() const { return abi_version_; }
137138

138139
const std::unordered_map<std::string, std::string> &envs() { return envs_; }
140+
const std::unordered_map<std::string, std::string> &log_destinations() {
141+
return log_destinations_;
142+
}
139143

140144
// Called to raise the flag which indicates that the context should stop iteration regardless of
141145
// returned filter status from Proxy-Wasm extensions. For example, we ignore
@@ -222,7 +226,7 @@ class WasmBase : public std::enable_shared_from_this<WasmBase> {
222226
std::unique_ptr<ShutdownHandle> shutdown_handle_;
223227
std::unordered_map<std::string, std::string>
224228
envs_; // environment variables passed through wasi.environ_get
225-
229+
std::unordered_map<std::string, std::string> log_destinations_;
226230
WasmCallVoid<0> _initialize_; /* WASI reactor (Emscripten v1.39.17+, Rust nightly) */
227231
WasmCallVoid<0> _start_; /* WASI command (Emscripten v1.39.0+, TinyGo) */
228232

@@ -394,7 +398,7 @@ inline void *WasmBase::allocMemory(uint64_t size, uint64_t *address) {
394398
}
395399
wasm_vm_->setRestrictedCallback(
396400
true, {// logging (Proxy-Wasm)
397-
"env.proxy_log",
401+
"env.proxy_log", "env.proxy_log_destination",
398402
// logging (stdout/stderr)
399403
"wasi_unstable.fd_write", "wasi_snapshot_preview1.fd_write",
400404
// time

Diff for: src/exports.cc

+37
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
#include <openssl/rand.h>
2121

22+
#include <fstream>
23+
#include <iostream>
2224
#include <utility>
2325

2426
namespace proxy_wasm {
@@ -916,6 +918,41 @@ Word log(Word level, Word address, Word size) {
916918
return context->log(level, message.value());
917919
}
918920

921+
Word log_destination(Word destination, Word dest_size, Word level, Word address, Word size) {
922+
if (level > static_cast<uint64_t>(LogLevel::Max)) {
923+
return WasmResult::BadArgument;
924+
}
925+
auto *context = contextOrEffectiveContext();
926+
const auto &log_destinations = context->wasm()->log_destinations();
927+
928+
auto message = context->wasmVm()->getMemory(address, size);
929+
if (!message) {
930+
return WasmResult::InvalidMemoryAccess;
931+
}
932+
auto dest = context->wasmVm()->getMemory(destination, dest_size);
933+
if (!dest) {
934+
return WasmResult::InvalidMemoryAccess;
935+
}
936+
context->log(level, dest.value());
937+
// iterate over log_destinations map to check if dest
938+
// destination requested by plugin exists
939+
for (const auto &e : log_destinations) {
940+
if (e.first == dest.value()) {
941+
// write message to the file which is the value of the key if it exists
942+
std::ofstream log_file;
943+
log_file.open(e.second, std::ios::out | std::ios_base::app);
944+
if (!log_file) {
945+
return WasmResult::InvalidMemoryAccess;
946+
}
947+
log_file << message.value() << std::endl;
948+
log_file.close();
949+
return WasmResult::Ok;
950+
}
951+
}
952+
// As a fallback, write to the default log destination.
953+
return context->log(level, message.value());
954+
}
955+
919956
Word get_log_level(Word result_level_uint32_ptr) {
920957
auto *context = contextOrEffectiveContext();
921958
uint32_t level = context->getLogLevel();

Diff for: src/wasm.cc

+5-2
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ WasmBase::WasmBase(const std::shared_ptr<WasmHandleBase> &base_wasm_handle,
190190
vm_id_(base_wasm_handle->wasm()->vm_id_), vm_key_(base_wasm_handle->wasm()->vm_key_),
191191
started_from_(base_wasm_handle->wasm()->wasm_vm()->cloneable()),
192192
envs_(base_wasm_handle->wasm()->envs()),
193+
log_destinations_(base_wasm_handle->wasm()->log_destinations()),
193194
allowed_capabilities_(base_wasm_handle->wasm()->allowed_capabilities_),
194195
base_wasm_handle_(base_wasm_handle) {
195196
if (started_from_ != Cloneable::NotCloneable) {
@@ -207,9 +208,11 @@ WasmBase::WasmBase(const std::shared_ptr<WasmHandleBase> &base_wasm_handle,
207208
WasmBase::WasmBase(std::unique_ptr<WasmVm> wasm_vm, std::string_view vm_id,
208209
std::string_view vm_configuration, std::string_view vm_key,
209210
std::unordered_map<std::string, std::string> envs,
211+
std::unordered_map<std::string, std::string> log_dest,
210212
AllowedCapabilitiesMap allowed_capabilities)
211213
: vm_id_(std::string(vm_id)), vm_key_(std::string(vm_key)), wasm_vm_(std::move(wasm_vm)),
212-
envs_(std::move(envs)), allowed_capabilities_(std::move(allowed_capabilities)),
214+
envs_(std::move(envs)), log_destinations_(std::move(log_dest)),
215+
allowed_capabilities_(std::move(allowed_capabilities)),
213216
vm_configuration_(std::string(vm_configuration)), vm_id_handle_(getVmIdHandle(vm_id)) {
214217
if (!wasm_vm_) {
215218
failed_ = FailState::UnableToCreateVm;
@@ -358,7 +361,7 @@ void WasmBase::startVm(ContextBase *root_context) {
358361
// wasi_snapshot_preview1.clock_time_get
359362
wasm_vm_->setRestrictedCallback(
360363
true, {// logging (Proxy-Wasm)
361-
"env.proxy_log",
364+
"env.proxy_log", "env.proxy_log_destination",
362365
// logging (stdout/stderr)
363366
"wasi_unstable.fd_write", "wasi_snapshot_preview1.fd_write",
364367
// args

Diff for: test/utility.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class TestWasm : public WasmBase {
140140
TestWasm(std::unique_ptr<WasmVm> wasm_vm, std::unordered_map<std::string, std::string> envs = {},
141141
std::string_view vm_id = "", std::string_view vm_configuration = "",
142142
std::string_view vm_key = "")
143-
: WasmBase(std::move(wasm_vm), vm_id, vm_configuration, vm_key, std::move(envs), {}) {}
143+
: WasmBase(std::move(wasm_vm), vm_id, vm_configuration, vm_key, std::move(envs), {}, {}) {}
144144

145145
TestWasm(const std::shared_ptr<WasmHandleBase> &base_wasm_handle, const WasmVmFactory &factory)
146146
: WasmBase(base_wasm_handle, factory) {}

Diff for: test/wasm_test.cc

+4-5
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
#include "include/proxy-wasm/wasm.h"
1616

17+
#include <iostream>
1718
#include <unordered_set>
1819

1920
#include "gtest/gtest.h"
@@ -43,9 +44,9 @@ TEST_P(TestVm, GetOrCreateThreadLocalWasmFailCallbacks) {
4344
// Define callbacks.
4445
WasmHandleFactory wasm_handle_factory =
4546
[this, vm_id, vm_config](std::string_view vm_key) -> std::shared_ptr<WasmHandleBase> {
46-
auto base_wasm = std::make_shared<WasmBase>(newVm(), vm_id, vm_config, vm_key,
47-
std::unordered_map<std::string, std::string>{},
48-
AllowedCapabilitiesMap{});
47+
auto base_wasm = std::make_shared<WasmBase>(
48+
newVm(), vm_id, vm_config, vm_key, std::unordered_map<std::string, std::string>{},
49+
std::unordered_map<std::string, std::string>{}, AllowedCapabilitiesMap{});
4950
return std::make_shared<WasmHandleBase>(base_wasm);
5051
};
5152

@@ -171,7 +172,6 @@ TEST_P(TestVm, AlwaysApplyCanary) {
171172
// For each create Wasm, canary should be done.
172173
EXPECT_EQ(canary_count, 1);
173174

174-
std::unordered_set<std::shared_ptr<WasmHandleBase>> reference_holder;
175175

176176
for (const auto &root_id : root_ids) {
177177
for (const auto &vm_id : vm_ids) {
@@ -209,7 +209,6 @@ TEST_P(TestVm, AlwaysApplyCanary) {
209209
// Keep the reference of wasm_handle_comp in order to utilize the WasmHandleBase
210210
// cache of createWasm. If we don't keep the reference, WasmHandleBase and VM will be
211211
// destroyed for each iteration.
212-
reference_holder.insert(wasm_handle_comp);
213212

214213
EXPECT_TRUE(TestContext::isGlobalLogged("onConfigure: " + root_id));
215214

0 commit comments

Comments
 (0)