-
Notifications
You must be signed in to change notification settings - Fork 60
Combined Wasm stats + metadata implementations. #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: If they are not already assigned, you can assign the PR to them by writing The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
This pull request has been automatically marked as stale because it has not had activity in the last 7 days. It will be closed in 7 days if no further activity occurs. Please feel free to give a status update now, ping for review, or re-open when it's ready. Thank you for your contributions! |
Keep alive ping. |
@@ -320,8 +320,9 @@ void InstanceImpl::initialize(const Options& options, | |||
if (bootstrap_.wasm_service_size() > 0) { | |||
auto factory = Registry::FactoryRegistry<Configuration::WasmFactory>::getFactory("envoy.wasm"); | |||
if (factory) { | |||
auto scope = Stats::ScopeSharedPtr(stats_store_.createScope("wasm.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need to create a scope called wasm
? If at all we do create this scope, it should record wasm implementation specific metrics.
I think that the loaded wasm modules get their own namespace with a configurable name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just copied this from what another service did. yes, perhaps we can add an additional scope which includes the VM id (which is unique for each wasm use case).
c->increment(1, "test_tag", 7, true); | ||
logTrace(std::string("get counter = ") + std::to_string(c->get("test_tag", 7, true))); | ||
auto simple_c = c->resolve("test_tag", 7, true); | ||
simple_c++; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this remaining in the worker thread and sent into the envoy singleton periodically, or is every call going into the underlying envoy scope? If it is the latter it may cause a lot of contention especially at ingress where there may be many worker thread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a test for the wasm "service". This is a singleton. It isn't used with any of the per-stream stuff, but just background activity, so it shouldn't contend. There are no calls going into it except the Timer which is going to be called on the single thread that the singleton is bound to.
virtual std::string getProtocol(StreamType type); | ||
|
||
// Metadata | ||
// When used with MetadataType::Request/Response refers to metadata with name "envoy.wasm": the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we will have multiple filters of type envoy.wasm
inserted. It is not clear how we can assume just 1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
example
name: envoy.wasm
config:
Name: istio.metadataFilter
type: “inbound|outbound|gateway”
vm_config:
vm: "envoy.wasm.vm.wavm"
code:
filename: "/var/lib/istio_metadata_http.wasm"
allow_precompiled: true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just checked experimentally in this branch. Multiple filters of type envoy.wasm, works.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Need to test stats API, but the structure is ok.
- What happens when multiple filters "envoy.wasm" filters are loaded?
LGTM for API, we will continue to iterate.
I would like @PiotrSikora and @silentdai to review code as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just some nits
Please feel to ignore.
What I am worry about is the naming and the ownership.
e.g. Callback
is actually function ptr instead of value
@@ -0,0 +1,364 @@ | |||
// Generated by the protocol buffer compiler. DO NOT EDIT! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is generated files are checked in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because these are part of the WASM api which would be copied by users instead of used as part of envoy with bazel. In the future when we sort out the tool chain we may do this differently, but it was expedient until we sort that.
source/extensions/common/wasm/wasm.h
Outdated
@@ -343,20 +387,41 @@ class Wasm : public Envoy::Server::Wasm, | |||
|
|||
private: | |||
friend class Context; | |||
static const uint32_t kMetricTypeMask = 0x3; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: could you put Mask between 0x2 and 0x4?
Super nit: it might be confusing if Mask
is a type...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done (first bit) Yes, it would be confusing... I am open to suggestions. kMaskForMetricType ?
|
||
void registerCallbacks(); // Register functions called out from WASM. | ||
void establishEnvironment(); // Language specific enviroments. | ||
void getFunctions(); // Get functions call into WASM. | ||
|
||
Upstream::ClusterManager& cluster_manager_; | ||
Event::Dispatcher& dispatcher_; | ||
Stats::Scope& scope_; | ||
std::string id_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: the scope_
is either reference to higher level, or to owner_scope_
, correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct, commented.
@@ -213,6 +241,18 @@ class Context : public Http::StreamFilter, | |||
virtual void httpRespond(const Pairs& response_headers, absl::string_view body, | |||
const Pairs& response_trailers); | |||
|
|||
// Stats/Metrics | |||
enum class MetricType : uint32_t { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure why enum is required. Even so we should be able to reuse the value above
static const uint32_t kMetricTypeCounter = 0x0;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The enum is a duplicate of one in the API and it is supposed to be opaque. The implementation uses the same numbers to encode the type of the metric into the metric_id. Yes, they could be reused, but then it would require a bunch of casting . How about I add a comment and some static_assert(s) to ensure that they remain the same.
using WasmCallback3Int = uint32_t (*)(void*, uint32_t, uint32_t, uint32_t); | ||
using WasmCallback5Int = uint32_t (*)(void*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); | ||
using WasmCallback9Int = uint32_t (*)(void*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, | ||
uint32_t, uint32_t, uint32_t, uint32_t); | ||
// Using the standard g++/clang mangling algorithm: | ||
using WasmCallback_Zjl = void (*)(void*, uint32_t, int64_t); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add the comment what Zjl Zjm mjj are referring to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
…ict with rust. Fix compilation fo the wasm exmple using full libprotobuf.
@@ -53,7 +53,7 @@ class HttpFilterNameValues { | |||
// Tap filter | |||
const std::string Tap = "envoy.filters.http.tap"; | |||
// Wasm filter | |||
const std::string Wasm = "envoy.filters.http.wasm"; | |||
const std::string Wasm = "envoy.wasm"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am just following the lua example. The fact that it is an http filter is given by context.
In our environment, the file system directory is as follows: Tue Jun 04 22:28:35][#48# ]$df -h Filesystem Size Used Avail Use% Mounted on tmpfs 77G 104K 77G 1% /dev/shm tmpfs 31G 9.8M 31G 1% /run tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 4.0M 0 4.0M 0% /sys/fs/cgroup /dev/mapper/atomicos-root 150G 144G 5.8G 97% /sysroot /dev/vda2 483M 84M 400M 18% /boot /dev/vdc 1.2T 87G 1.1T 8% /sysroot/home/centos/external We have a directory named /sysroot. If the envoy config file is the that directory, envoy can not start up. [2024-06-04 22:28:35.581][3382724][critical][main] [source/server/server.cc:131] error initializing configuration 'configs/envoy.yaml': Invalid path: configs/envoy.yaml [2024-06-04 22:28:35.581][3382724][info][main] [source/server/server.cc:972] exiting Invalid path: configs/envoy.yaml In my mind, envoy should only check the default system directory such as /dev /sys /proc as illegal path. So it is better to use exact match instead of startwith match. Signed-off-by: Zhang Bo <bozhang@ebay.com>
Combined Wasm stats + metadata implementations.