Skip to content
This repository has been archived by the owner on Dec 16, 2020. It is now read-only.

wasm: API to add tags to active span from wasm filter #384

Closed
wants to merge 14 commits into from
Closed
8 changes: 8 additions & 0 deletions api/wasm/cpp/doc/wasm_filter.md
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,14 @@ method is effective when calling from
Returns [WasmData](#wasmdata) pointer which
holds the response body data.

### activeSpanSetTag

``` {.sourceCode .cpp}
void activeSpanSetTag(StringView key, StringView value)
```
Sets a tag key and value in the active span of the request being
processed by the filte.

Metadata API
------------

Expand Down
6 changes: 6 additions & 0 deletions api/wasm/cpp/proxy_wasm_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ struct Tuple3Hash {
};

using HeaderStringPairs = std::vector<std::pair<std::string, std::string>>;
using SpanTagPairs = std::vector<std::pair<std::string, std::string>>;

class GrpcCallHandlerBase {
public:
Expand Down Expand Up @@ -781,6 +782,11 @@ inline WasmResult makeHttpCall(StringView uri, const HeaderStringPairs& request_
return result;
}

// Tracing
inline WasmResult activeSpanSetTag(StringView key, StringView value) {
return proxy_active_span_set_tag(key.data(), key.size(), value.data(), value.size());
}

// Low level metrics interface.

inline WasmResult defineMetric(MetricType type, StringView name, uint32_t* metric_id) {
Expand Down
3 changes: 3 additions & 0 deletions api/wasm/cpp/proxy_wasm_externs.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ extern "C" void proxy_on_grpc_trailing_metadata(uint32_t context_id, uint32_t to
extern "C" void proxy_on_grpc_receive(uint32_t context_id, uint32_t token, uint32_t response_size);
extern "C" void proxy_on_grpc_close(uint32_t context_id, uint32_t token, uint32_t status_code);

extern "C" WasmResult proxy_active_span_set_tag(const char* key_ptr, size_t key_size, const char* value_ptr,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the ABI level, this should be called proxy_set_active_span_tag().

Also, you should move it into host exports section above.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

size_t value_size);

// The stream/vm has completed.
extern "C" uint32_t proxy_on_done(uint32_t context_id);
// proxy_on_log occurs after proxy_on_done.
Expand Down
1 change: 1 addition & 0 deletions api/wasm/cpp/proxy_wasm_intrinsics.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ mergeInto(LibraryManager.library, {
proxy_set_effective_context : function () {},
proxy_done: function () {},
proxy_call_foreign_function: function () {},
proxy_active_span_set_tag: function () {},
});
Binary file modified examples/wasm/envoy_filter_http_wasm_example.wasm
Binary file not shown.
9 changes: 9 additions & 0 deletions source/extensions/common/wasm/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,15 @@ void Context::scriptLog(spdlog::level::level_enum level, absl::string_view messa
// Connection
bool Context::isSsl() { return decoder_callbacks_->connection()->ssl() != nullptr; }

// Tracing
void Context::activeSpanSetTag(absl::string_view key, absl::string_view value) {
if (!decoder_callbacks_) {
return;
}
Tracing::Span& span = decoder_callbacks_->activeSpan();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you considered a version of this function that uses encoder_callbacks_, maybe as a backup? I ask because I don't know if decoder_callbacks_ is valid in the context of the HTTP encoder. Do you have.an example of this working within the onResponseBody() of a Context subclass?

span.setTag(key, value);
}

//
// Calls into the WASM code.
//
Expand Down
3 changes: 3 additions & 0 deletions source/extensions/common/wasm/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,9 @@ class Context : public Logger::Loggable<Logger::Id::wasm>,
// Connection
virtual bool isSsl();

// Tracing
virtual void activeSpanSetTag(absl::string_view key, absl::string_view value);

void addAfterVmCallAction(std::function<void()> f);

protected:
Expand Down
14 changes: 14 additions & 0 deletions source/extensions/common/wasm/exports.cc
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <iostream>

#include "extensions/common/wasm/wasm.h"

namespace Envoy {
Expand Down Expand Up @@ -778,6 +780,18 @@ Word log(void* raw_context, Word level, Word address, Word size) {
return wasmResultToWord(WasmResult::Ok);
}

Word active_span_set_tag(void* raw_context, Word key_ptr, Word key_size, Word value_ptr,
Word value_size) {
auto context = WASM_CONTEXT(raw_context);
auto key = context->wasmVm()->getMemory(key_ptr.u64_, key_size.u64_);
auto value = context->wasmVm()->getMemory(value_ptr.u64_, value_size.u64_);
if (!key || !value) {
return wasmResultToWord(WasmResult::InvalidMemoryAccess);
}
context->activeSpanSetTag(key.value(), value.value());
return wasmResultToWord(WasmResult::Ok);
}

} // namespace Exports
} // namespace Wasm
} // namespace Common
Expand Down
2 changes: 2 additions & 0 deletions source/extensions/common/wasm/exports.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ Word set_effective_context(void* raw_context, Word context_id);
Word done(void* raw_context);
Word call_foreign_function(void* raw_context, Word function_name, Word function_name_size,
Word arguments, Word warguments_size, Word results, Word results_size);
Word active_span_set_tag(void* raw_context, Word key_ptr, Word key_size, Word value_ptr,
Word value_size);

// Runtime environment functions exported from envoy to wasm.

Expand Down
9 changes: 8 additions & 1 deletion source/extensions/common/wasm/null/wasm_api_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ inline WasmResult proxy_set_shared_data(const char* key_ptr, size_t key_size, co
}

// SharedQueue
// Note: Registering the same queue_name will overwrite the old registration while preseving any
// Note: Registering the same queue_name will overwrite the old registration while preserving any
// pending data. Consequently it should typically be followed by a call to
// proxy_dequeue_shared_queue. Returns unique token for the queue.
inline WasmResult proxy_register_shared_queue(const char* queue_name_ptr, size_t queue_name_size,
Expand Down Expand Up @@ -214,6 +214,13 @@ inline WasmResult proxy_grpc_send(uint64_t token, const char* message_ptr, size_
WS(message_size), WS(end_stream)));
}

// Tracing
inline WasmResult proxy_active_span_set_tag(const char* key_ptr, size_t key_size,
const char* value_ptr, size_t value_size) {
return wordToWasmResult(Exports::active_span_set_tag(current_context_, WR(key_ptr), WS(key_size),
WR(value_ptr), WS(value_size)));
}

// Metrics
// Returns a metric_id which can be used to report a metric. On error returns 0.
inline WasmResult proxy_define_metric(MetricType type, const char* name_ptr, size_t name_size,
Expand Down
1 change: 1 addition & 0 deletions source/extensions/common/wasm/wasm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ void Wasm::registerCallbacks() {
_REGISTER_PROXY(set_effective_context);
_REGISTER_PROXY(done);
_REGISTER_PROXY(call_foreign_function);
_REGISTER_PROXY(active_span_set_tag);
#undef _REGISTER_PROXY
}

Expand Down
Binary file modified test/extensions/access_loggers/wasm/test_data/logging.wasm
Binary file not shown.
2 changes: 1 addition & 1 deletion test/extensions/filters/http/wasm/test_data/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
all: headers_cpp.wasm async_call_cpp.wasm metadata_cpp.wasm grpc_call_cpp.wasm shared_cpp.wasm queue_cpp.wasm root_id_cpp.wasm
all: headers_cpp.wasm async_call_cpp.wasm metadata_cpp.wasm grpc_call_cpp.wasm shared_cpp.wasm queue_cpp.wasm root_id_cpp.wasm tracing_cpp.wasm

include ../../../../../../api/wasm/cpp/Makefile.base_lite
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
DOCKER_SDK=/external_sdk

all: headers_cpp.wasm async_call_cpp.wasm metadata_cpp.wasm grpc_call_cpp.wasm shared_cpp.wasm queue_cpp.wasm http_callout_cpp.wasm grpc_callout_cpp.wasm
all: headers_cpp.wasm async_call_cpp.wasm metadata_cpp.wasm grpc_call_cpp.wasm shared_cpp.wasm queue_cpp.wasm http_callout_cpp.wasm grpc_callout_cpp.wasm tracing_cpp.wasm
chown ${uid}.${gid} *.wasm

include ${DOCKER_SDK}/Makefile.base_lite
Binary file modified test/extensions/filters/http/wasm/test_data/async_call_cpp.wasm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified test/extensions/filters/http/wasm/test_data/headers_cpp.wasm
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified test/extensions/filters/http/wasm/test_data/queue_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/filters/http/wasm/test_data/shared_cpp.wasm
Binary file not shown.
18 changes: 18 additions & 0 deletions test/extensions/filters/http/wasm/test_data/tracing_cpp.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// NOLINT(namespace-envoy)
#include <string>
#include <unordered_map>

#include "proxy_wasm_intrinsics.h"

class ExampleContext : public Context {
public:
explicit ExampleContext(uint32_t id, RootContext* root) : Context(id, root) {}

FilterHeadersStatus onRequestHeaders(uint32_t) override;
};
static RegisterContextFactory register_ExampleContext(CONTEXT_FACTORY(ExampleContext));

FilterHeadersStatus ExampleContext::onRequestHeaders(uint32_t) {
activeSpanSetTag("tag_1", "tag_value_1");
return FilterHeadersStatus::Continue;
}
Binary file not shown.
14 changes: 14 additions & 0 deletions test/extensions/filters/http/wasm/wasm_filter_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "test/mocks/ssl/mocks.h"
#include "test/mocks/stream_info/mocks.h"
#include "test/mocks/thread_local/mocks.h"
#include "test/mocks/tracing/mocks.h"
#include "test/mocks/upstream/mocks.h"
#include "test/test_common/environment.h"
#include "test/test_common/printers.h"
Expand Down Expand Up @@ -149,6 +150,7 @@ class WasmHttpFilterTest : public testing::TestWithParam<std::string> {
NiceMock<Http::MockStreamEncoderFilterCallbacks> encoder_callbacks_;
NiceMock<Envoy::StreamInfo::MockStreamInfo> request_stream_info_;
NiceMock<LocalInfo::MockLocalInfo> local_info_;
NiceMock<Tracing::MockSpan> active_span_;
envoy::config::core::v3::Metadata listener_metadata_;
TestRoot* root_context_ = nullptr;
Config::DataSource::RemoteAsyncDataProviderPtr remote_data_provider_;
Expand Down Expand Up @@ -555,6 +557,18 @@ TEST_P(WasmHttpFilterTest, SharedQueue) {
wasm_->wasm()->queueReady(root_context_->id(), token);
}

// Verifies if the tags have been added correctly.
TEST_P(WasmHttpFilterTest, AddTagToActiveSpans) {
setupConfig(TestEnvironment::readFileToStringForTest(TestEnvironment::substitute(
"{{ test_rundir }}/test/extensions/filters/http/wasm/test_data/tracing_cpp.wasm")));
setupFilter();
EXPECT_CALL(decoder_callbacks_, activeSpan).WillRepeatedly(ReturnRef(active_span_));
EXPECT_CALL(active_span_, setTag(Eq("tag_1"), Eq("tag_value_1")));
Http::TestRequestHeaderMapImpl request_headers{{":path", "/"}};
EXPECT_EQ(Http::FilterHeadersStatus::Continue, filter_->decodeHeaders(request_headers, true));
filter_->onDestroy();
}

// Script using a root_id which is not registered.
TEST_P(WasmHttpFilterTest, RootIdNotRegistered) {
setupConfig(TestEnvironment::readFileToStringForTest(TestEnvironment::substitute(
Expand Down
Binary file modified test/extensions/wasm/test_data/asm2wasm_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/bad_signature_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/emscripten_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/logging_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/missing_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/segv_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/speed_cpp.wasm
Binary file not shown.
Binary file modified test/extensions/wasm/test_data/stats_cpp.wasm
Binary file not shown.
Loading