Skip to content
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

Allow prepending access log handler for WASM filter #35924

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions changelogs/current.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,14 @@ behavior_changes:
change: |
Added new tag extraction so that scoped rds stats have their :ref:'scope_route_config_name
<envoy_v3_api_msg_config/route/v3/scoped_route>' and stat prefix extracted.
- area: wasm
change: |
Added prependAccessLogHandler in HTTP filter to be used by WASM in order to fix
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
Added prependAccessLogHandler in HTTP filter to be used by WASM in order to fix
Added ``prependAccessLogHandler`` in HTTP filter to be used by WASM in order to fix

`issue 30859 <https://github.com/envoyproxy/envoy/issues/30859>`_, which allows
reversing adding the order of access loggers in order to provide correct dynamic metadata flow
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
reversing adding the order of access loggers in order to provide correct dynamic metadata flow
reversing the order access loggers are added in order to provide correct dynamic metadata flow

without inheriting onStreamComplete(). This solution is exclusively used by WASM, and may be
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
without inheriting onStreamComplete(). This solution is exclusively used by WASM, and may be
without inheriting ``onStreamComplete()``. This solution is exclusively used by WASM, and may be

changed to an updated WASM access logger if additional features deems it necessary. This behavior can
be reverted by setting the runtime guard ``envoy.reloadable_features.prepend_access_log_handler`` to false.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
be reverted by setting the runtime guard ``envoy.reloadable_features.prepend_access_log_handler`` to false.
be reverted by setting the runtime guard ``envoy.reloadable_features.prepend_access_log_handler`` to ``false``.


minor_behavior_changes:
# *Changes that may cause incompatibilities for some users, but should not for most*
Expand Down
7 changes: 7 additions & 0 deletions envoy/http/filter.h
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,13 @@ class FilterChainFactoryCallbacks {
*/
virtual void addAccessLogHandler(AccessLog::InstanceSharedPtr handler) PURE;

/**
* Prepend an access log handler that is called when the stream is destroyed.
* @param handler supplies the handler to add. Currently used specifically for
* WASM filter.
*/
virtual void prependAccessLogHandler(AccessLog::InstanceSharedPtr handler) PURE;

/**
* Allows filters to access the thread local dispatcher.
* @param return the worker thread's dispatcher.
Expand Down
6 changes: 6 additions & 0 deletions source/common/http/filter_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,9 @@ class FilterManager : public ScopeTrackedObject,
void addAccessLogHandler(AccessLog::InstanceSharedPtr handler) {
access_log_handlers_.push_back(std::move(handler));
}
void prependAccessLogHandler(AccessLog::InstanceSharedPtr handler) {
access_log_handlers_.push_front(std::move(handler));
}
void addStreamDecoderFilter(ActiveStreamDecoderFilterPtr filter) {
// Note: configured decoder filters are appended to decoder_filters_.
// This means that if filters are configured in the following order (assume all three filters
Expand Down Expand Up @@ -975,6 +978,9 @@ class FilterManager : public ScopeTrackedObject,
void addAccessLogHandler(AccessLog::InstanceSharedPtr handler) override {
manager_.addAccessLogHandler(std::move(handler));
}
void prependAccessLogHandler(AccessLog::InstanceSharedPtr handler) override {
manager_.prependAccessLogHandler(std::move(handler));
}

Event::Dispatcher& dispatcher() override { return manager_.dispatcher_; }

Expand Down
1 change: 1 addition & 0 deletions source/common/runtime/runtime_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ RUNTIME_GUARD(envoy_reloadable_features_no_extension_lookup_by_name);
RUNTIME_GUARD(envoy_reloadable_features_no_timer_based_rate_limit_token_bucket);
RUNTIME_GUARD(envoy_reloadable_features_original_dst_rely_on_idle_timeout);
RUNTIME_GUARD(envoy_reloadable_features_prefer_ipv6_dns_on_macos);
RUNTIME_GUARD(envoy_reloadable_features_prepend_access_log_handler);
RUNTIME_GUARD(envoy_reloadable_features_proxy_104);
RUNTIME_GUARD(envoy_reloadable_features_proxy_status_mapping_more_core_response_flags);
RUNTIME_GUARD(envoy_reloadable_features_quic_connect_client_udp_sockets);
Expand Down
3 changes: 3 additions & 0 deletions source/extensions/filters/http/composite/factory_wrapper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ void FactoryCallbacksWrapper::addStreamFilter(Http::StreamFilterSharedPtr filter
void FactoryCallbacksWrapper::addAccessLogHandler(AccessLog::InstanceSharedPtr access_log) {
access_loggers_.push_back(std::move(access_log));
}
void FactoryCallbacksWrapper::prependAccessLogHandler(AccessLog::InstanceSharedPtr access_log) {
access_loggers_.push_front(std::move(access_log));
}
} // namespace Composite
} // namespace HttpFilters
} // namespace Extensions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ struct FactoryCallbacksWrapper : public Http::FilterChainFactoryCallbacks {
void addStreamEncoderFilter(Http::StreamEncoderFilterSharedPtr filter) override;
void addStreamFilter(Http::StreamFilterSharedPtr filter) override;
void addAccessLogHandler(AccessLog::InstanceSharedPtr) override;
void prependAccessLogHandler(AccessLog::InstanceSharedPtr) override;
Event::Dispatcher& dispatcher() override { return dispatcher_; }

Filter& filter_;
Expand All @@ -30,7 +31,7 @@ struct FactoryCallbacksWrapper : public Http::FilterChainFactoryCallbacks {
absl::variant<Http::StreamDecoderFilterSharedPtr, Http::StreamEncoderFilterSharedPtr,
Http::StreamFilterSharedPtr>;
absl::optional<FilterAlternative> filter_to_inject_;
std::vector<AccessLog::InstanceSharedPtr> access_loggers_;
std::list<AccessLog::InstanceSharedPtr> access_loggers_;
std::vector<absl::Status> errors_;
};
} // namespace Composite
Expand Down
4 changes: 4 additions & 0 deletions source/extensions/filters/http/match_delegate/config.cc
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ struct DelegatingFactoryCallbacks : public Envoy::Http::FilterChainFactoryCallba
delegated_callbacks_.addAccessLogHandler(std::move(handler));
}

void prependAccessLogHandler(AccessLog::InstanceSharedPtr handler) override {
delegated_callbacks_.prependAccessLogHandler(std::move(handler));
}

Envoy::Http::FilterChainFactoryCallbacks& delegated_callbacks_;
Matcher::MatchTreeSharedPtr<Envoy::Http::HttpMatchingData> match_tree_;
};
Expand Down
6 changes: 5 additions & 1 deletion source/extensions/filters/http/wasm/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ class WasmFilterConfig
return;
}
callbacks.addStreamFilter(filter);
callbacks.addAccessLogHandler(filter);
if (Runtime::runtimeFeatureEnabled("envoy.reloadable_features.prepend_access_log_handler")) {
callbacks.prependAccessLogHandler(filter);
} else {
callbacks.addAccessLogHandler(filter);
}
};
}
};
Expand Down
22 changes: 11 additions & 11 deletions test/extensions/filters/http/wasm/config_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ TEST_P(WasmFilterConfigTest, JsonLoadFromFileWasm) {
EXPECT_EQ(getContextInitManagerState(), Init::Manager::State::Initialized);
Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}

Expand Down Expand Up @@ -208,7 +208,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromFileWasm) {
.WillOnce([&context](Http::StreamFilterSharedPtr filter) {
context = std::static_pointer_cast<Envoy::Extensions::Common::Wasm::Context>(filter);
});
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}
// Check if the context still holds a valid Wasm even after the factory is destroyed.
Expand Down Expand Up @@ -242,7 +242,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromFileWasmFailOpenOk) {
EXPECT_EQ(getContextInitManagerState(), Init::Manager::State::Initialized);
Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}

Expand Down Expand Up @@ -292,7 +292,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromFileWasmInvalidConfig) {
EXPECT_EQ(getContextInitManagerState(), Init::Manager::State::Initialized);
Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}

Expand All @@ -318,7 +318,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadInlineWasm) {
EXPECT_EQ(getContextInitManagerState(), Init::Manager::State::Initialized);
Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}

Expand Down Expand Up @@ -385,7 +385,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteWasm) {
EXPECT_EQ(getContextInitManagerState(), Init::Manager::State::Initialized);
Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}

Expand Down Expand Up @@ -449,7 +449,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteWasmFailOnUncachedThenSucceed) {

Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));

cb(filter_callback);
dispatcher_.clearDeferredDeleteList();
Expand Down Expand Up @@ -572,7 +572,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteWasmFailCachedThenSucceed) {

Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));

cb(filter_callback);

Expand Down Expand Up @@ -639,7 +639,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteWasmFailCachedThenSucceed) {

Http::MockFilterChainFactoryCallbacks filter_callback2;
EXPECT_CALL(filter_callback2, addStreamFilter(_));
EXPECT_CALL(filter_callback2, addAccessLogHandler(_));
EXPECT_CALL(filter_callback2, prependAccessLogHandler(_));

cb2(filter_callback2);

Expand Down Expand Up @@ -847,7 +847,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteMultipleRetries) {
EXPECT_EQ(getContextInitManagerState(), Init::Manager::State::Initialized);
Http::MockFilterChainFactoryCallbacks filter_callback;
EXPECT_CALL(filter_callback, addStreamFilter(_));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
}

Expand Down Expand Up @@ -900,7 +900,7 @@ TEST_P(WasmFilterConfigTest, YamlLoadFromRemoteSuccessBadcode) {
.WillOnce(Invoke([&context](Http::StreamFilterSharedPtr filter) {
context = std::static_pointer_cast<Extensions::Common::Wasm::Context>(filter);
}));
EXPECT_CALL(filter_callback, addAccessLogHandler(_));
EXPECT_CALL(filter_callback, prependAccessLogHandler(_));
cb(filter_callback);
EXPECT_EQ(context->wasm(), nullptr);
EXPECT_TRUE(context->isFailed());
Expand Down
1 change: 1 addition & 0 deletions test/mocks/http/mocks.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ class MockFilterChainFactoryCallbacks : public Http::FilterChainFactoryCallbacks
MOCK_METHOD(void, addStreamEncoderFilter, (Http::StreamEncoderFilterSharedPtr filter));
MOCK_METHOD(void, addStreamFilter, (Http::StreamFilterSharedPtr filter));
MOCK_METHOD(void, addAccessLogHandler, (AccessLog::InstanceSharedPtr handler));
MOCK_METHOD(void, prependAccessLogHandler, (AccessLog::InstanceSharedPtr handler));
MOCK_METHOD(Event::Dispatcher&, dispatcher, ());
};

Expand Down
Loading