-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Support process level access log rate limiting #40992
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
Merged
Merged
Changes from all commits
Commits
Show all changes
70 commits
Select commit
Hold shift + click to select a range
72a6d43
initial change
TAOXUY aed7ddb
format
TAOXUY d518895
fix
TAOXUY 3b671a3
fix
TAOXUY 2ce93ab
fix exception
TAOXUY d2e2927
fix format
TAOXUY c18c9a2
fix format
TAOXUY 2893a27
fix format
TAOXUY e6e01fb
fix format
TAOXUY 2176771
revert exception change
TAOXUY a16910b
Revert "revert exception change"
TAOXUY 78928be
throw exception in network/http filters
TAOXUY b82397f
fix local_ratelimit_test
TAOXUY 1651b95
format
TAOXUY 483f3bf
change to extension
TAOXUY 8c92d68
fix build
TAOXUY 35ba766
fix format
TAOXUY 023a336
MISC
TAOXUY b102740
fix coverage
TAOXUY a7c941c
fix coverage
TAOXUY 48e22bb
add comment
TAOXUY d8d6752
fix comment
TAOXUY 5ac1f64
format
TAOXUY b624b85
move cleanup in destructor
TAOXUY 12e7a81
fix doc
TAOXUY db09002
fix doc
TAOXUY ea055c9
switch to lookup by key+token_bucket's hash
TAOXUY 9c702d4
fix comment
TAOXUY af74791
switch to use global resource
TAOXUY 3760b26
add one more unit test
TAOXUY c4b20fe
fix
TAOXUY 0c5c497
changes
TAOXUY 26bb142
fix
TAOXUY 2b11d9f
fix precheck
TAOXUY 7710a37
fix
TAOXUY 12f5f9a
NIT
TAOXUY 551c517
fix
TAOXUY 17043bc
add integration test
TAOXUY e63d75a
add comment
TAOXUY 98f63f5
change to singleSubscription
TAOXUY 485907b
remove visibility
TAOXUY fc41544
fix comment
TAOXUY cfb8ac0
fix config.yaml
TAOXUY 978ae5f
move test
TAOXUY 26124a9
revert
TAOXUY f8278e8
update
TAOXUY 5de6a7c
update base test lib
TAOXUY d04b9ef
for adi comments
TAOXUY f9b2574
fix comment
TAOXUY 46a0242
Merge branch 'main' into addAccessLogRateLimiter
TAOXUY 323dcb9
fix
TAOXUY 62b24f9
fix
TAOXUY c32db90
fix
TAOXUY 25560af
fix mark comment: merge the resource name in TokenBucket
TAOXUY 361e6fc
for mark: remove name in TokenBucket
TAOXUY a3c29e2
fix comment type
TAOXUY 6f1eadc
add setter cleanup
TAOXUY 0bea2d9
fix race condition
TAOXUY 9a492e1
Fix coverage
TAOXUY baf530c
add initTarget for all getLimiter call & update comments
TAOXUY abd8da6
Merge branch 'main' into addAccessLogRateLimiter
TAOXUY d09aab8
move provider_singleton folder
TAOXUY dd55734
Merge branch 'main' into addAccessLogRateLimiter
TAOXUY fe414d1
Update source/extensions/access_loggers/filters/process_ratelimit/fil…
TAOXUY 3bb513a
Merge branch 'main' into addAccessLogRateLimiter
TAOXUY 53ac2fc
fix
TAOXUY 09fd9ad
switch to initTarget per filter&add stats
TAOXUY 4fc4698
add check for object destruction
TAOXUY 29a1244
fix coverage
TAOXUY 496e6de
NIT
TAOXUY File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
api/envoy/extensions/access_loggers/filters/process_ratelimit/v3/BUILD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| # DO NOT EDIT. This file is generated by tools/proto_format/proto_sync.py. | ||
|
|
||
| load("@envoy_api//bazel:api_build_system.bzl", "api_proto_package") | ||
|
|
||
| licenses(["notice"]) # Apache 2 | ||
|
|
||
| api_proto_package( | ||
| deps = [ | ||
| "//envoy/config/core/v3:pkg", | ||
| "@com_github_cncf_xds//udpa/annotations:pkg", | ||
| ], | ||
| ) |
32 changes: 32 additions & 0 deletions
32
api/envoy/extensions/access_loggers/filters/process_ratelimit/v3/process_ratelimit.proto
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| syntax = "proto3"; | ||
|
|
||
| package envoy.extensions.access_loggers.filters.process_ratelimit.v3; | ||
|
|
||
| import "envoy/config/core/v3/config_source.proto"; | ||
|
|
||
| import "udpa/annotations/status.proto"; | ||
| import "validate/validate.proto"; | ||
|
|
||
| option java_package = "io.envoyproxy.envoy.extensions.access_loggers.filters.process_ratelimit.v3"; | ||
| option java_outer_classname = "ProcessRatelimitProto"; | ||
| option java_multiple_files = true; | ||
| option go_package = "github.com/envoyproxy/go-control-plane/envoy/extensions/access_loggers/filters/process_ratelimit/v3;process_ratelimitv3"; | ||
| option (udpa.annotations.file_status).package_version_status = ACTIVE; | ||
|
|
||
| // [#protodoc-title: ProcessRateLimiter] | ||
| // [#extension: envoy.access_loggers.extension_filters.process_ratelimit] | ||
|
|
||
| // Filters for rate limiting the access log emission using global token buckets per process and shared across all listeners. | ||
| message ProcessRateLimitFilter { | ||
| // The dynamic config for the token bucket. | ||
| DynamicTokenBucket dynamic_config = 1; | ||
| } | ||
|
|
||
| message DynamicTokenBucket { | ||
| // the key used to find the token bucket in the singleton map. | ||
| string resource_name = 1 [(validate.rules).string = {min_len: 1}]; | ||
|
|
||
| // The configuration source for the :ref:`token_bucket <envoy_v3_api_msg_type.v3.TokenBucket>`. | ||
| // It should stay the same through the process lifetime. | ||
| config.core.v3.ConfigSource config_source = 2 [(validate.rules).message = {required: true}]; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
source/extensions/access_loggers/filters/process_ratelimit/BUILD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| load( | ||
| "//bazel:envoy_build_system.bzl", | ||
| "envoy_cc_extension", | ||
| "envoy_cc_library", | ||
| "envoy_extension_package", | ||
| ) | ||
|
|
||
| licenses(["notice"]) # Apache 2 | ||
|
|
||
| envoy_extension_package() | ||
|
|
||
| envoy_cc_library( | ||
| name = "provider_singleton_lib", | ||
| srcs = ["provider_singleton.cc"], | ||
| hdrs = ["provider_singleton.h"], | ||
| deps = [ | ||
| "//envoy/event:dispatcher_interface", | ||
| "//envoy/event:timer_interface", | ||
| "//envoy/ratelimit:ratelimit_interface", | ||
| "//source/common/common:thread_synchronizer_lib", | ||
| "//source/common/common:token_bucket_impl_lib", | ||
| "//source/common/config:subscription_base_interface", | ||
| "//source/common/grpc:common_lib", | ||
| "//source/common/init:target_lib", | ||
| "//source/extensions/filters/common/local_ratelimit:local_ratelimit_lib", | ||
| "@envoy_api//envoy/type/v3:pkg_cc_proto", | ||
| ], | ||
| ) | ||
|
|
||
| envoy_cc_extension( | ||
| name = "filter_lib", | ||
| srcs = ["filter.cc"], | ||
| hdrs = ["filter.h"], | ||
| deps = [ | ||
| ":provider_singleton_lib", | ||
| "//envoy/access_log:access_log_interface", | ||
| "//source/common/init:target_lib", | ||
| "@envoy_api//envoy/extensions/access_loggers/filters/process_ratelimit/v3:pkg_cc_proto", | ||
| ], | ||
| ) | ||
|
|
||
| envoy_cc_extension( | ||
| name = "config", | ||
| srcs = ["config.cc"], | ||
| hdrs = ["config.h"], | ||
| deps = [ | ||
| ":filter_lib", | ||
| "//envoy/access_log:access_log_interface", | ||
| "//envoy/registry", | ||
| "//source/common/access_log:access_log_lib", | ||
| "//source/common/protobuf:utility_lib", | ||
| "@envoy_api//envoy/extensions/access_loggers/filters/process_ratelimit/v3:pkg_cc_proto", | ||
| ], | ||
| ) |
39 changes: 39 additions & 0 deletions
39
source/extensions/access_loggers/filters/process_ratelimit/config.cc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| #include "source/extensions/access_loggers/filters/process_ratelimit/config.h" | ||
|
|
||
| #include "envoy/extensions/access_loggers/filters/process_ratelimit/v3/process_ratelimit.pb.h" | ||
|
|
||
| #include "source/common/protobuf/utility.h" | ||
| #include "source/extensions/access_loggers/filters/process_ratelimit/filter.h" | ||
| #include "source/extensions/filters/common/local_ratelimit/local_ratelimit_impl.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Extensions { | ||
| namespace AccessLoggers { | ||
| namespace Filters { | ||
| namespace ProcessRateLimit { | ||
|
|
||
| AccessLog::FilterPtr ProcessRateLimitFilterFactory::createFilter( | ||
| const envoy::config::accesslog::v3::ExtensionFilter& config, | ||
| Server::Configuration::GenericFactoryContext& context) { | ||
| auto factory_config = | ||
| Config::Utility::translateToFactoryConfig(config, context.messageValidationVisitor(), *this); | ||
| const auto& process_ratelimit_config = | ||
| dynamic_cast<const envoy::extensions::access_loggers::filters::process_ratelimit::v3:: | ||
| ProcessRateLimitFilter&>(*factory_config); | ||
| auto filter = std::make_unique<ProcessRateLimitFilter>(context.serverFactoryContext(), | ||
| process_ratelimit_config); | ||
| return filter; | ||
| } | ||
|
|
||
| ProtobufTypes::MessagePtr ProcessRateLimitFilterFactory::createEmptyConfigProto() { | ||
| return std::make_unique< | ||
| envoy::extensions::access_loggers::filters::process_ratelimit::v3::ProcessRateLimitFilter>(); | ||
| } | ||
|
|
||
| REGISTER_FACTORY(ProcessRateLimitFilterFactory, AccessLog::ExtensionFilterFactory); | ||
|
|
||
| } // namespace ProcessRateLimit | ||
| } // namespace Filters | ||
| } // namespace AccessLoggers | ||
| } // namespace Extensions | ||
| } // namespace Envoy |
28 changes: 28 additions & 0 deletions
28
source/extensions/access_loggers/filters/process_ratelimit/config.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #pragma once | ||
|
|
||
| #include "envoy/access_log/access_log.h" | ||
| #include "envoy/registry/registry.h" | ||
|
|
||
| #include "source/common/access_log/access_log_impl.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Extensions { | ||
| namespace AccessLoggers { | ||
| namespace Filters { | ||
| namespace ProcessRateLimit { | ||
|
|
||
| class ProcessRateLimitFilterFactory : public AccessLog::ExtensionFilterFactory { | ||
| public: | ||
| AccessLog::FilterPtr createFilter(const envoy::config::accesslog::v3::ExtensionFilter& config, | ||
| Server::Configuration::GenericFactoryContext& context) override; | ||
| ProtobufTypes::MessagePtr createEmptyConfigProto() override; | ||
| std::string name() const override { | ||
| return "envoy.access_loggers.extension_filters.process_ratelimit"; | ||
| } | ||
| }; | ||
|
|
||
| } // namespace ProcessRateLimit | ||
| } // namespace Filters | ||
| } // namespace AccessLoggers | ||
| } // namespace Extensions | ||
| } // namespace Envoy |
72 changes: 72 additions & 0 deletions
72
source/extensions/access_loggers/filters/process_ratelimit/filter.cc
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| #include "source/extensions/access_loggers/filters/process_ratelimit/filter.h" | ||
|
|
||
| #include "envoy/access_log/access_log.h" | ||
|
|
||
| #include "source/common/init/target_impl.h" | ||
| #include "source/extensions/filters/common/local_ratelimit/local_ratelimit_impl.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Extensions { | ||
| namespace AccessLoggers { | ||
| namespace Filters { | ||
| namespace ProcessRateLimit { | ||
|
|
||
| ProcessRateLimitFilter::ProcessRateLimitFilter( | ||
| Server::Configuration::ServerFactoryContext& context, | ||
| const envoy::extensions::access_loggers::filters::process_ratelimit::v3::ProcessRateLimitFilter& | ||
| config) | ||
| : setter_key_(reinterpret_cast<intptr_t>(this)), | ||
| cancel_cb_(std::make_shared<std::atomic<bool>>(false)), context_(context), | ||
| stats_({ALL_PROCESS_RATELIMIT_FILTER_STATS( | ||
| POOL_COUNTER_PREFIX(context.scope(), "access_log.process_ratelimit."))}) { | ||
| auto setter = | ||
| [this, cancel_cb = cancel_cb_]( | ||
| Envoy::Extensions::Filters::Common::LocalRateLimit::LocalRateLimiterSharedPtr limiter) | ||
| -> void { | ||
| if (!cancel_cb->load()) { | ||
| ENVOY_BUG(limiter != nullptr, "limiter shouldn't be null if the `limiter` is set from " | ||
| "callback."); | ||
| rate_limiter_->setLimiter(limiter); | ||
| } | ||
| }; | ||
|
|
||
| if (!config.has_dynamic_config()) { | ||
| ExceptionUtil::throwEnvoyException("`dynamic_config` is required."); | ||
| } | ||
| rate_limiter_ = Envoy::Extensions::Filters::Common::LocalRateLimit::RateLimiterProviderSingleton:: | ||
| getRateLimiter(context, config.dynamic_config().resource_name(), | ||
| config.dynamic_config().config_source(), setter_key_, std::move(setter)); | ||
| } | ||
|
|
||
| ProcessRateLimitFilter::~ProcessRateLimitFilter() { | ||
| // The destructor can be called in any thread. | ||
| // The `cancel_cb_` is set to true to prevent the `limiter` from being set in | ||
| // the `setter` from the main thread. | ||
| cancel_cb_->store(true); | ||
| context_.mainThreadDispatcher().post( | ||
| [limiter = std::move(rate_limiter_), setter_key = setter_key_] { | ||
| // remove the setter for this filter. | ||
| limiter->getSubscription()->removeSetter(setter_key); | ||
| }); | ||
| } | ||
|
|
||
| bool ProcessRateLimitFilter::evaluate(const Formatter::Context&, | ||
| const StreamInfo::StreamInfo&) const { | ||
| ENVOY_BUG(rate_limiter_->getLimiter() != nullptr, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there some metric that shows that access logs are dropped? |
||
| "rate_limiter_.limiter_ should be already set in init callback."); | ||
| Extensions::Filters::Common::LocalRateLimit::LocalRateLimiterSharedPtr limiter = | ||
| rate_limiter_->getLimiter(); | ||
| auto result = limiter->requestAllowed({}); | ||
| if (!result.allowed) { | ||
| stats_.denied_.inc(); | ||
| } else { | ||
| stats_.allowed_.inc(); | ||
| } | ||
| return result.allowed; | ||
| } | ||
|
|
||
| } // namespace ProcessRateLimit | ||
| } // namespace Filters | ||
| } // namespace AccessLoggers | ||
| } // namespace Extensions | ||
| } // namespace Envoy | ||
49 changes: 49 additions & 0 deletions
49
source/extensions/access_loggers/filters/process_ratelimit/filter.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| #pragma once | ||
|
|
||
| #include "envoy/access_log/access_log.h" | ||
| #include "envoy/extensions/access_loggers/filters/process_ratelimit/v3/process_ratelimit.pb.h" | ||
|
|
||
| #include "source/common/init/target_impl.h" | ||
| #include "source/extensions/access_loggers/filters/process_ratelimit/provider_singleton.h" | ||
|
|
||
| namespace Envoy { | ||
| namespace Extensions { | ||
| namespace AccessLoggers { | ||
| namespace Filters { | ||
| namespace ProcessRateLimit { | ||
|
|
||
| #define ALL_PROCESS_RATELIMIT_FILTER_STATS(COUNTER) \ | ||
| COUNTER(allowed) \ | ||
| COUNTER(denied) | ||
|
|
||
| /** | ||
| * Struct definition for all process ratelimit filter stats. @see stats_macros.h | ||
| */ | ||
| struct ProcessRateLimitFilterStats { | ||
| ALL_PROCESS_RATELIMIT_FILTER_STATS(GENERATE_COUNTER_STRUCT) | ||
| }; | ||
| class ProcessRateLimitFilter : public AccessLog::Filter { | ||
| public: | ||
| ProcessRateLimitFilter(Server::Configuration::ServerFactoryContext& context, | ||
| const envoy::extensions::access_loggers::filters::process_ratelimit::v3:: | ||
| ProcessRateLimitFilter& config); | ||
|
|
||
| bool evaluate(const Formatter::Context& log_context, | ||
| const StreamInfo::StreamInfo& stream_info) const override; | ||
|
|
||
| ~ProcessRateLimitFilter() override; | ||
|
|
||
| private: | ||
| const intptr_t setter_key_; | ||
| std::shared_ptr<std::atomic<bool>> cancel_cb_; | ||
| Server::Configuration::ServerFactoryContext& context_; | ||
| ProcessRateLimitFilterStats stats_; | ||
| mutable Envoy::Extensions::Filters::Common::LocalRateLimit::RateLimiterProviderSingleton:: | ||
| RateLimiterWrapperPtr rate_limiter_; | ||
| }; | ||
|
|
||
| } // namespace ProcessRateLimit | ||
| } // namespace Filters | ||
| } // namespace AccessLoggers | ||
| } // namespace Extensions | ||
| } // namespace Envoy |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.