fluent-plugin-label-router 0.2.2 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/fluent-plugin-label-router.gemspec +2 -2
- data/lib/fluent/plugin/out_label_router.rb +45 -18
- data/test/plugin/test_out_label_router.rb +35 -6
- metadata +18 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9fcacfb0c98686f99facd3bd94da5fa8065b4446cf1d2e5850a3e1456e5721d1
|
|
4
|
+
data.tar.gz: 65f9d48cbf0636faa0544b052d16465760cc74c9a8fe3fb8aa378f122f7d0da6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6b1f0a77e69be61a6ade1329b4e1caa58dde56fdd0d2313bbfa54476342d5d04cacdbd71dac21f5b04ce191f5839624f25ff4d3c765f6d627a48e8c692b86bb8
|
|
7
|
+
data.tar.gz: 3129f7a8a90f4d175941b9a719c96796245ed58bae0c0d60dbb42a608c310079b512aafb2385aebc7cee35b9df51c4bf781f3831696085f4438cce633c9e095a
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |spec|
|
|
5
5
|
spec.name = "fluent-plugin-label-router"
|
|
6
|
-
spec.version = "0.2.
|
|
6
|
+
spec.version = "0.2.7"
|
|
7
7
|
spec.authors = ["Banzai Cloud"]
|
|
8
8
|
spec.email = ["info@banzaicloud.com"]
|
|
9
9
|
|
|
@@ -20,8 +20,8 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
spec.test_files = test_files
|
|
21
21
|
spec.require_paths = ["lib"]
|
|
22
22
|
|
|
23
|
-
spec.add_development_dependency "bundler", "~> 1.14"
|
|
24
23
|
spec.add_development_dependency "rake", "~> 12.0"
|
|
25
24
|
spec.add_development_dependency "test-unit", "~> 3.0"
|
|
25
|
+
spec.add_dependency "prometheus-client", ">= 2.1.0"
|
|
26
26
|
spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
|
|
27
27
|
end
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
12
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
13
|
# See the License for the specific language governing permissions and
|
|
14
|
-
# limitations under the License
|
|
14
|
+
# limitations under the License
|
|
15
15
|
|
|
16
16
|
require "fluent/plugin/output"
|
|
17
|
-
require '
|
|
17
|
+
require 'prometheus/client'
|
|
18
|
+
|
|
18
19
|
|
|
19
20
|
module Fluent
|
|
20
21
|
module Plugin
|
|
@@ -34,12 +35,16 @@ module Fluent
|
|
|
34
35
|
config_param :default_route, :string, :default => ""
|
|
35
36
|
desc "Default tag to drain unmatched patterns"
|
|
36
37
|
config_param :default_tag, :string, :default => ""
|
|
38
|
+
desc "Enable metrics for the router"
|
|
39
|
+
config_param :metrics, :bool, :default => false
|
|
37
40
|
|
|
38
41
|
config_section :route, param_name: :routes, multi: true do
|
|
39
42
|
desc "New @LABEL if selectors matched"
|
|
40
43
|
config_param :@label, :string, :default => nil
|
|
41
44
|
desc "New tag if selectors matched"
|
|
42
45
|
config_param :tag, :string, :default => ""
|
|
46
|
+
desc "Extra labels for metrics"
|
|
47
|
+
config_param :metrics_labels, :hash, :default => {}
|
|
43
48
|
|
|
44
49
|
config_section :match, param_name: :matches, multi: true do
|
|
45
50
|
desc "Label definition to match record. Example: app:nginx. You can specify more values as comma separated list: key1:value1,key2:value2"
|
|
@@ -56,10 +61,22 @@ module Fluent
|
|
|
56
61
|
end
|
|
57
62
|
|
|
58
63
|
class Route
|
|
59
|
-
def initialize(
|
|
64
|
+
def initialize(rule, router, registry)
|
|
60
65
|
@router = router
|
|
61
|
-
@matches = matches
|
|
62
|
-
@tag = tag
|
|
66
|
+
@matches = rule['matches']
|
|
67
|
+
@tag = rule['tag'].to_s
|
|
68
|
+
@label = rule['@label']
|
|
69
|
+
@metrics_labels = (rule['metrics_labels'].map { |k, v| [k.to_sym, v] }.to_h if rule['metrics_labels'])
|
|
70
|
+
@counter = nil
|
|
71
|
+
unless registry.nil?
|
|
72
|
+
@counter = registry.counter(:fluentd_router_records_total, docstring: "Total number of events router for the flow", labels: [:flow])
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def get_labels
|
|
77
|
+
default = { 'flow': @label }
|
|
78
|
+
labels = default.merge(@metrics_labels)
|
|
79
|
+
labels
|
|
63
80
|
end
|
|
64
81
|
|
|
65
82
|
# Evaluate selectors
|
|
@@ -88,7 +105,7 @@ module Fluent
|
|
|
88
105
|
return false
|
|
89
106
|
end
|
|
90
107
|
# Break on host mismatch
|
|
91
|
-
unless match.container_names.empty? || match.container_names.include?(metadata[:
|
|
108
|
+
unless match.container_names.empty? || match.container_names.include?(metadata[:container])
|
|
92
109
|
return false
|
|
93
110
|
end
|
|
94
111
|
# Break if list of namespaces is not empty and does not include actual namespace
|
|
@@ -113,6 +130,8 @@ module Fluent
|
|
|
113
130
|
else
|
|
114
131
|
@router.emit_stream(@tag, es)
|
|
115
132
|
end
|
|
133
|
+
# increment the counter for a given label set
|
|
134
|
+
@counter&.increment(by: es.size, labels: get_labels)
|
|
116
135
|
end
|
|
117
136
|
|
|
118
137
|
def match_labels(input, match)
|
|
@@ -122,13 +141,15 @@ module Fluent
|
|
|
122
141
|
|
|
123
142
|
def process(tag, es)
|
|
124
143
|
if @sticky_tags
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
144
|
+
@mutex.synchronize {
|
|
145
|
+
if @route_map.has_key?(tag)
|
|
146
|
+
# We already matched with this tag send events to the routers
|
|
147
|
+
@route_map[tag].each do |r|
|
|
148
|
+
r.emit_es(tag, es.dup)
|
|
149
|
+
end
|
|
150
|
+
return
|
|
129
151
|
end
|
|
130
|
-
|
|
131
|
-
end
|
|
152
|
+
}
|
|
132
153
|
end
|
|
133
154
|
event_stream = Hash.new {|h, k| h[k] = Fluent::MultiEventStream.new }
|
|
134
155
|
es.each do |time, record|
|
|
@@ -141,7 +162,9 @@ module Fluent
|
|
|
141
162
|
if r.match?(input_metadata)
|
|
142
163
|
orphan_record = false
|
|
143
164
|
if @sticky_tags
|
|
144
|
-
@
|
|
165
|
+
@mutex.synchronize {
|
|
166
|
+
@route_map[tag].add(r)
|
|
167
|
+
}
|
|
145
168
|
end
|
|
146
169
|
if @batch
|
|
147
170
|
event_stream[r].add(time, record)
|
|
@@ -152,7 +175,9 @@ module Fluent
|
|
|
152
175
|
end
|
|
153
176
|
if !@default_router.nil? && orphan_record
|
|
154
177
|
if @sticky_tags
|
|
155
|
-
@
|
|
178
|
+
@mutex.synchronize {
|
|
179
|
+
@route_map[tag].add(@default_router)
|
|
180
|
+
}
|
|
156
181
|
end
|
|
157
182
|
if @batch
|
|
158
183
|
event_stream[@default_router].add(time, record)
|
|
@@ -170,17 +195,19 @@ module Fluent
|
|
|
170
195
|
|
|
171
196
|
def configure(conf)
|
|
172
197
|
super
|
|
173
|
-
@
|
|
198
|
+
@registry = (::Prometheus::Client.registry if @metrics)
|
|
199
|
+
@route_map = Hash.new { |h, k| h[k] = Set.new }
|
|
200
|
+
@mutex = Mutex.new
|
|
174
201
|
@routers = []
|
|
175
202
|
@default_router = nil
|
|
176
203
|
@routes.each do |rule|
|
|
177
204
|
route_router = event_emitter_router(rule['@label'])
|
|
178
|
-
|
|
179
|
-
@routers << Route.new(rule.matches, rule.tag.to_s, route_router)
|
|
205
|
+
@routers << Route.new(rule, route_router, @registry)
|
|
180
206
|
end
|
|
181
207
|
|
|
182
208
|
if @default_route != '' or @default_tag != ''
|
|
183
|
-
|
|
209
|
+
default_rule = { 'matches' => nil, 'tag' => @default_tag, '@label' => @default_route}
|
|
210
|
+
@default_router = Route.new(default_rule, event_emitter_router(@default_route), @registry)
|
|
184
211
|
end
|
|
185
212
|
|
|
186
213
|
@access_to_labels = record_accessor_create("$.kubernetes.labels")
|
|
@@ -76,7 +76,7 @@ class LabelRouterOutputTest < Test::Unit::TestCase
|
|
|
76
76
|
d = Fluent::Test::Driver::BaseOwner.new(Fluent::Plugin::LabelRouterOutput)
|
|
77
77
|
d.configure(routing_conf)
|
|
78
78
|
|
|
79
|
-
r1 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[0]
|
|
79
|
+
r1 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[0], nil,nil)
|
|
80
80
|
# Selector matched: GO
|
|
81
81
|
assert_equal(true, r1.match?(labels: { 'app' => 'app1' }, namespace: ''))
|
|
82
82
|
# Exclude match: NO GO
|
|
@@ -84,7 +84,7 @@ class LabelRouterOutputTest < Test::Unit::TestCase
|
|
|
84
84
|
# Nothing matched: NO GO
|
|
85
85
|
assert_equal(false, r1.match?(labels: { 'app3' => 'app2' }, namespace: ''))
|
|
86
86
|
|
|
87
|
-
r2 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[1]
|
|
87
|
+
r2 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[1], nil,nil)
|
|
88
88
|
# Match selector and namespace: GO
|
|
89
89
|
assert_equal(true, r2.match?(labels: { 'app' => 'app1' }, namespace: 'test'))
|
|
90
90
|
# Exclude via namespace
|
|
@@ -92,18 +92,18 @@ class LabelRouterOutputTest < Test::Unit::TestCase
|
|
|
92
92
|
# Nothing matched: NO GO
|
|
93
93
|
assert_equal(false, r2.match?(labels: { 'app3' => 'app' }, namespace: 'system'))
|
|
94
94
|
|
|
95
|
-
r3 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[2]
|
|
95
|
+
r3 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[2], nil,nil)
|
|
96
96
|
assert_equal(true, r3.match?(labels: { 'app' => 'nginx' }, namespace: 'dev'))
|
|
97
97
|
assert_equal(true, r3.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
|
|
98
98
|
assert_equal(false, r3.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox'))
|
|
99
99
|
|
|
100
|
-
r4 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[3]
|
|
100
|
+
r4 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[3], nil,nil)
|
|
101
101
|
# Matching container name
|
|
102
|
-
assert_equal(true, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev',
|
|
102
|
+
assert_equal(true, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container: 'mycontainer'))
|
|
103
103
|
# Missing container name is equal to wrong container
|
|
104
104
|
assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
|
|
105
105
|
# Wrong container name
|
|
106
|
-
assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev',
|
|
106
|
+
assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container: 'mycontainer2'))
|
|
107
107
|
# Wrong label but good namespace and container_name
|
|
108
108
|
assert_equal(false, r4.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox', container_name: 'mycontainer2'))
|
|
109
109
|
end
|
|
@@ -208,4 +208,33 @@ default_tag "new_tag"
|
|
|
208
208
|
assert_equal ["new_app_tag", event_time, {"kubernetes" => {"labels" => {"app" => "app2"} } }], events[1]
|
|
209
209
|
end
|
|
210
210
|
end
|
|
211
|
+
|
|
212
|
+
sub_test_case 'test_metrics' do
|
|
213
|
+
test 'normal' do
|
|
214
|
+
CONFIG4 = %[
|
|
215
|
+
metrics true
|
|
216
|
+
<route>
|
|
217
|
+
tag new_app_tag
|
|
218
|
+
<match>
|
|
219
|
+
labels
|
|
220
|
+
namespaces
|
|
221
|
+
</match>
|
|
222
|
+
</route>
|
|
223
|
+
]
|
|
224
|
+
event_time = event_time("2019-07-17 11:11:11 UTC")
|
|
225
|
+
d = create_driver(CONFIG4)
|
|
226
|
+
d.run(default_tag: 'test') do
|
|
227
|
+
d.feed(event_time, {"kubernetes" => {"labels" => {"app" => "app1"} } } )
|
|
228
|
+
end
|
|
229
|
+
d.run(default_tag: 'test2') do
|
|
230
|
+
d.feed(event_time, {"kubernetes" => {"labels" => {"app" => "app2"} } } )
|
|
231
|
+
end
|
|
232
|
+
events = d.events
|
|
233
|
+
|
|
234
|
+
assert_equal(2, events.size)
|
|
235
|
+
assert_equal ["new_app_tag", event_time, {"kubernetes" => {"labels" => {"app" => "app1"} } }], events[0]
|
|
236
|
+
assert_equal ["new_app_tag", event_time, {"kubernetes" => {"labels" => {"app" => "app2"} } }], events[1]
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
211
240
|
end
|
metadata
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: fluent-plugin-label-router
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Banzai Cloud
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2021-06-16 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: rake
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
17
|
- - "~>"
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '12.0'
|
|
20
20
|
type: :development
|
|
21
21
|
prerelease: false
|
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
23
|
requirements:
|
|
24
24
|
- - "~>"
|
|
25
25
|
- !ruby/object:Gem::Version
|
|
26
|
-
version: '
|
|
26
|
+
version: '12.0'
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
28
|
+
name: test-unit
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: '
|
|
33
|
+
version: '3.0'
|
|
34
34
|
type: :development
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: '
|
|
40
|
+
version: '3.0'
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
|
-
name:
|
|
42
|
+
name: prometheus-client
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
44
44
|
requirements:
|
|
45
|
-
- - "
|
|
45
|
+
- - ">="
|
|
46
46
|
- !ruby/object:Gem::Version
|
|
47
|
-
version:
|
|
48
|
-
type: :
|
|
47
|
+
version: 2.1.0
|
|
48
|
+
type: :runtime
|
|
49
49
|
prerelease: false
|
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
51
51
|
requirements:
|
|
52
|
-
- - "
|
|
52
|
+
- - ">="
|
|
53
53
|
- !ruby/object:Gem::Version
|
|
54
|
-
version:
|
|
54
|
+
version: 2.1.0
|
|
55
55
|
- !ruby/object:Gem::Dependency
|
|
56
56
|
name: fluentd
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -92,7 +92,7 @@ homepage: https://github.com/banzaicloud/fluent-plugin-label-router
|
|
|
92
92
|
licenses:
|
|
93
93
|
- Apache-2.0
|
|
94
94
|
metadata: {}
|
|
95
|
-
post_install_message:
|
|
95
|
+
post_install_message:
|
|
96
96
|
rdoc_options: []
|
|
97
97
|
require_paths:
|
|
98
98
|
- lib
|
|
@@ -107,8 +107,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
107
107
|
- !ruby/object:Gem::Version
|
|
108
108
|
version: '0'
|
|
109
109
|
requirements: []
|
|
110
|
-
rubygems_version: 3.
|
|
111
|
-
signing_key:
|
|
110
|
+
rubygems_version: 3.1.6
|
|
111
|
+
signing_key:
|
|
112
112
|
specification_version: 4
|
|
113
113
|
summary: Routing records based on Kubernetes labels.
|
|
114
114
|
test_files:
|