fluent-plugin-quota-throttle 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4616f13cc061297e5a1a26dd282723b8696abf657b62b93022aa80a78cbaf1d8
|
4
|
+
data.tar.gz: ba6b6e9f85a436b611dcc6c89693e7f24b8901a7242416136698076c4e4c0e0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8737089035454b8fb25808ed25092f989bea67f8e39998d3f2bae87c46be5f9cbc8006b448f55b327648d30dc8f06a6853092d444478a583dc2a96ffdcaaf81b
|
7
|
+
data.tar.gz: 47dcabe4de812fd2738ba6640b0ace2a870b9a3a9376f2a0256a68773baec1445dae760c28caee653f74032212d89be0b6cceeef93d80064a6d3cf8039b20e23
|
data/README.md
CHANGED
@@ -1,24 +1,24 @@
|
|
1
1
|
# fluent-plugin-quota-throttle
|
2
2
|
|
3
|
-
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/rubrikinc/fluent-plugin-throttle/blob/master/LICENSE) ![Rake Test](https://github.com/rubrikinc/fluent-plugin-quota-throttle/actions/workflows/ruby.yml/badge.svg)
|
3
|
+
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://github.com/rubrikinc/fluent-plugin-throttle/blob/master/LICENSE) ![Rake Test](https://github.com/rubrikinc/fluent-plugin-quota-throttle/actions/workflows/ruby.yml/badge.svg) [![Gem Version](https://badge.fury.io/rb/fluent-plugin-quota-throttle.svg)](https://badge.fury.io/rb/fluent-plugin-quota-throttle)
|
4
4
|
|
5
5
|
A sentry plugin to throttle logs based on well defined quotas. Logs are grouped by configurable keys. When
|
6
6
|
a group exceeds a configuration rate, logs are dropped for this group.
|
7
7
|
|
8
8
|
## Installation
|
9
9
|
|
10
|
-
|
10
|
+
install with `gem` or td-agent provided command as:
|
11
11
|
|
12
|
-
[//]: # (install with `gem` or td-agent provided command as:)
|
13
12
|
|
14
|
-
|
15
|
-
[//]: # (```bash)
|
13
|
+
```bash
|
16
14
|
|
17
|
-
|
15
|
+
# for fluentd
|
18
16
|
|
19
|
-
|
17
|
+
$ gem install fluent-plugin-quota-throttle
|
18
|
+
[OR]
|
19
|
+
$ fluent-gem install fluent-plugin-quota-throttle
|
20
20
|
|
21
|
-
|
21
|
+
```
|
22
22
|
|
23
23
|
## Configuration
|
24
24
|
|
@@ -78,7 +78,7 @@ This is the period of of time over which `bucket_size` applies. This should be g
|
|
78
78
|
|
79
79
|
Either `drop` or `reemit`.
|
80
80
|
|
81
|
-
When a group exceeds its rate limit, logs are either dropped or re-emitted with a new tag
|
81
|
+
When a group exceeds its rate limit, logs are either dropped or re-emitted with a new tag `secondary.<tag>`
|
82
82
|
|
83
83
|
|
84
84
|
|
@@ -96,7 +96,7 @@ the delay between every repetition.
|
|
96
96
|
<filter **>
|
97
97
|
@type quota_throttle
|
98
98
|
@path /etc/fluentd/quota_throttle.yaml
|
99
|
-
@warning_delay
|
99
|
+
@warning_delay 30s
|
100
100
|
</filter>
|
101
101
|
```
|
102
102
|
```yaml
|
@@ -108,7 +108,7 @@ quotas:
|
|
108
108
|
match_by:
|
109
109
|
group1.a: value1
|
110
110
|
bucket_size: 100
|
111
|
-
duration:
|
111
|
+
duration: 60s
|
112
112
|
action: drop
|
113
113
|
- name: quota2
|
114
114
|
description: second quota
|
@@ -119,7 +119,7 @@ quotas:
|
|
119
119
|
group1.a: value2
|
120
120
|
group1.b: value3
|
121
121
|
bucket_size: 200
|
122
|
-
duration:
|
122
|
+
duration: 2m
|
123
123
|
action: reemit
|
124
124
|
- name: quota3
|
125
125
|
description: third quota
|
@@ -130,14 +130,14 @@ quotas:
|
|
130
130
|
group2: value2
|
131
131
|
group3: value3
|
132
132
|
bucket_size: 300
|
133
|
-
duration:
|
133
|
+
duration: 180s
|
134
134
|
action: drop
|
135
135
|
default:
|
136
136
|
description: default quota
|
137
137
|
group_by:
|
138
138
|
- group1.a
|
139
139
|
bucket_size: 300
|
140
|
-
duration:
|
140
|
+
duration: 3m
|
141
141
|
action: reemit
|
142
142
|
```
|
143
143
|
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |spec|
|
6
6
|
spec.name = "fluent-plugin-quota-throttle"
|
7
|
-
spec.version = "0.0.
|
7
|
+
spec.version = "0.0.3"
|
8
8
|
spec.authors = ["Athish Pranav D", "Dipendra Singh", "Rubrik Inc."]
|
9
9
|
spec.email = ["athish.pranav@rubrik.com", "Dipendra.Singh@rubrik.com"]
|
10
10
|
spec.summary = %q{Fluentd filter for throttling logs based on a configurable quotas.}
|
@@ -16,7 +16,7 @@ module ConfigParser
|
|
16
16
|
# +action+: (String) The action to take when the quota is reached. Must be one of the predefined actions in @@allowed_actions.
|
17
17
|
class Quota
|
18
18
|
|
19
|
-
|
19
|
+
attr_reader :name, :desc, :group_by, :match_by, :bucket_size, :duration, :action
|
20
20
|
|
21
21
|
@@allowed_actions = Set["drop", "reemit"]
|
22
22
|
|
@@ -104,7 +104,7 @@ module Fluent::Plugin
|
|
104
104
|
# +timestamp+: (Time) The timestamp of the record
|
105
105
|
def quota_breached(tag, timestamp, record, bucket, quota)
|
106
106
|
if bucket.last_warning.nil? || Time.now - bucket.last_warning > @warning_delay
|
107
|
-
log.warn "Quota breached for group #{bucket.group}
|
107
|
+
log.warn "Quota breached for {group: #{bucket.group}, quota: #{quota.name}, total_logs: #{bucket.bucket_count_total}, limit: #{bucket.bucket_limit}, current_rate: #{bucket.approx_rate_per_second}}"
|
108
108
|
bucket.last_warning = Time.now
|
109
109
|
end
|
110
110
|
case quota.action
|
@@ -5,7 +5,9 @@ module RateLimiter
|
|
5
5
|
##
|
6
6
|
# Bucket class, contains the rate limiting logic for each group
|
7
7
|
# Attributes:
|
8
|
+
# +group+: Group for which the bucket is created
|
8
9
|
# +bucket_count+: Number of requests in the bucket
|
10
|
+
# +bucket_count_total+: Number of requests in the bucket including the dropped requests
|
9
11
|
# +bucket_last_reset+: Time when the bucket was last reset
|
10
12
|
# +approx_rate_per_second+: Approximate rate of requests per second
|
11
13
|
# +rate_last_reset+: Time when the rate was last reset
|
@@ -16,12 +18,13 @@ module RateLimiter
|
|
16
18
|
# +bucket_period+: Time period for the bucket
|
17
19
|
# +rate_limit+: Maximum number of requests allowed per second
|
18
20
|
class Bucket
|
19
|
-
attr_accessor :bucket_count, :bucket_last_reset, :approx_rate_per_second, :rate_last_reset, :curr_count, :last_warning
|
21
|
+
attr_accessor :bucket_count, :bucket_count_total, :bucket_last_reset, :approx_rate_per_second, :rate_last_reset, :curr_count, :last_warning
|
20
22
|
attr_reader :bucket_limit, :bucket_period, :rate_limit, :timeout_s, :group
|
21
23
|
def initialize( group, bucket_limit, bucket_period)
|
22
24
|
now = Time.now
|
23
25
|
@group = group
|
24
26
|
@bucket_count = 0
|
27
|
+
@bucket_count_total = 0
|
25
28
|
@bucket_last_reset = now
|
26
29
|
@approx_rate_per_second = 0
|
27
30
|
@rate_last_reset = now
|
@@ -43,6 +46,7 @@ module RateLimiter
|
|
43
46
|
end
|
44
47
|
now = Time.now
|
45
48
|
@curr_count += 1
|
49
|
+
@bucket_count_total += 1
|
46
50
|
time_lapsed = now - @rate_last_reset
|
47
51
|
|
48
52
|
if time_lapsed.to_i >= 1
|
@@ -80,6 +84,7 @@ module RateLimiter
|
|
80
84
|
now = Time.now
|
81
85
|
unless @bucket_count == -1 && @approx_rate_per_second > @rate_limit
|
82
86
|
@bucket_count = 0
|
87
|
+
@bucket_count_total = 0
|
83
88
|
@bucket_last_reset = now
|
84
89
|
end
|
85
90
|
end
|
@@ -99,7 +104,7 @@ module RateLimiter
|
|
99
104
|
# +group+: Group for which the bucket is required
|
100
105
|
# +quota+: Quota object containing the bucket size and duration
|
101
106
|
def get_bucket(group, quota)
|
102
|
-
@buckets[group] = @buckets.delete(group) || Bucket.new( group, quota.bucket_size, quota.duration)
|
107
|
+
@buckets[[group, quota.name]] = @buckets.delete([group, quota.name]) || Bucket.new( group, quota.bucket_size, quota.duration)
|
103
108
|
end
|
104
109
|
|
105
110
|
# Cleans the buckets that have expired
|
@@ -27,6 +27,8 @@ class TestBucket < Minitest::Test
|
|
27
27
|
def test_bucket_allow_full
|
28
28
|
11.times { @bucket.allow }
|
29
29
|
assert_equal false, @bucket.allow
|
30
|
+
assert_equal -1, @bucket.bucket_count
|
31
|
+
assert_equal 12, @bucket.bucket_count_total
|
30
32
|
end
|
31
33
|
|
32
34
|
def test_reset_bucket
|
@@ -63,10 +65,10 @@ class TestBucketStore < Minitest::Test
|
|
63
65
|
group2 = "value2"
|
64
66
|
@bucket_store.get_bucket(group2, @quota)
|
65
67
|
lru_group, lru_counter = @bucket_store.instance_variable_get(:@buckets).first
|
66
|
-
assert_equal group1, lru_group
|
68
|
+
assert_equal [group1, @quota.name], lru_group
|
67
69
|
sleep(5)
|
68
70
|
@bucket_store.clean_buckets
|
69
71
|
lru_group, lru_counter = @bucket_store.instance_variable_get(:@buckets).first
|
70
|
-
assert_equal group2, lru_group
|
72
|
+
assert_equal [group2, @quota.name], lru_group
|
71
73
|
end
|
72
74
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-quota-throttle
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Athish Pranav D
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-07-
|
13
|
+
date: 2024-07-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: bundler
|