fluent-plugin-label-router 0.2.2 → 0.2.7

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: 323aeb0b86fedafdcca48546cb3eed9aa7523efa01df41c3f9a46cd069cd76bb
4
- data.tar.gz: b42d4410cdbacabcf49a8eb2f5d8f8be01d3761efb9b436370ba3166a64eaeb3
3
+ metadata.gz: 9fcacfb0c98686f99facd3bd94da5fa8065b4446cf1d2e5850a3e1456e5721d1
4
+ data.tar.gz: 65f9d48cbf0636faa0544b052d16465760cc74c9a8fe3fb8aa378f122f7d0da6
5
5
  SHA512:
6
- metadata.gz: 3e0989c5509dda968b509bb1ec2b01f125b83353aaa7347a68364b2412b41eec93187d320d5005dde9d9e9fadda1afb9ce8b6416dcb86771f6646dd0c8ade2ce
7
- data.tar.gz: 5c53945c123e3271223dff6e04d9eb41bbb674c0876ce62f48af49f70b9adb7c90218c8e70899557b9a20215d999434f595e47dfb1f34a55bf817233b5ddf955
6
+ metadata.gz: 6b1f0a77e69be61a6ade1329b4e1caa58dde56fdd0d2313bbfa54476342d5d04cacdbd71dac21f5b04ce191f5839624f25ff4d3c765f6d627a48e8c692b86bb8
7
+ data.tar.gz: 3129f7a8a90f4d175941b9a719c96796245ed58bae0c0d60dbb42a608c310079b512aafb2385aebc7cee35b9df51c4bf781f3831696085f4438cce633c9e095a
data/README.md CHANGED
@@ -192,7 +192,7 @@ Use `default_label` and/or `default_tag` to route non matching records.
192
192
  ```
193
193
  <match example.tag**>
194
194
  @type label_router
195
- default_label @default_sink
195
+ default_route @default_sink
196
196
  <route>
197
197
  ...
198
198
  </route>
@@ -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.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 'digest/md5'
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(matches, tag, router)
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[:container_name])
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
- if @route_map.has_key?(tag)
126
- # We already matched with this tag send events to the routers
127
- @route_map[tag].each do |r|
128
- r.emit_es(tag, es.dup)
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
- return
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
- @route_map[tag].push(r)
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
- @route_map[tag].push(@default_router)
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
- @route_map = Hash.new { |h, k| h[k] = Array.new }
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
- puts rule
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
- @default_router = Route.new(nil, @default_tag, event_emitter_router(@default_route))
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].matches, d.instance.routes[0].tag,nil)
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].matches, d.instance.routes[1].tag,nil)
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].matches, d.instance.routes[2].tag,nil)
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].matches, d.instance.routes[3].tag,nil)
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', container_name: 'mycontainer'))
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', container_name: 'mycontainer2'))
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.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: 2020-03-24 00:00:00.000000000 Z
11
+ date: 2021-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
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: '1.14'
26
+ version: '12.0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: test-unit
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '12.0'
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: '12.0'
40
+ version: '3.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: test-unit
42
+ name: prometheus-client
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :development
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: '3.0'
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.0.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: