fluent-plugin-label-router 0.3.2 → 0.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '0188ed80bdd96932a8d4942585a4cba52843b2e32c0492718aa1706b73ae29e4'
4
- data.tar.gz: 8d9fd20daf7e0a2d171185e752bbd4310fb52575747cc73442492839d51056a3
3
+ metadata.gz: 84f4bafc4ac5d89f9c326c55c54e12f70b4315afe546aa6463492cc6ba69aa8e
4
+ data.tar.gz: 6c507a4af8eccfd37a5f70ea40e64f077ceefb4d34519ea3db1d284d90700a92
5
5
  SHA512:
6
- metadata.gz: 687f7dfb1523caf6ac12c7d5574b7fbab1a7f2a70f4b350a53a1d81aa1c69b24d365546c95d490af4f992b2174b0ad3c6a8793f56e07656f9988f96bf093ad5b
7
- data.tar.gz: 38ce993e367fc24bc974da84a96579ba4ce311cf3891f0afe268bea9ee24b05ddb164e7d7fc1214172128a8fa6d9a9ac42d8ddfe974b8a487e86e7b38817d713
6
+ metadata.gz: 4db8ea9e6b6e0af1c491f9635c47dcf8e5eb8f4ac91cff15c46600717714e2e9784b2eb32a287ba83fdd96439c588e70a9b7e256c8b330998127976fd039d4ee
7
+ data.tar.gz: 8f112e80a1b562008ecbe69e02fe6292c93deed2afd53e9a54a6eb2f2fad56bfbdbb3994ab7fc4b1a2dbe942c25982a3858eed2c4f7f5aaf7813d2b4be8152bd
data/Gemfile CHANGED
@@ -1,3 +1,3 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gemspec
3
+ gemspec
data/Gemfile.lock CHANGED
@@ -1,25 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-label-router (0.3.0)
5
- fluentd (>= 0.14.10, < 2)
4
+ fluent-plugin-label-router (0.3.2)
5
+ concurrent-ruby
6
+ fluentd (>= 1.17.1, < 1.18)
6
7
  prometheus-client (>= 2.1.0)
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
10
11
  specs:
11
12
  base64 (0.2.0)
12
- concurrent-ruby (1.3.1)
13
- cool.io (1.8.1)
13
+ concurrent-ruby (1.3.4)
14
+ cool.io (1.9.0)
14
15
  csv (3.3.0)
15
16
  drb (2.2.1)
16
- fluentd (1.17.0)
17
+ fluentd (1.17.1)
17
18
  base64 (~> 0.2)
18
19
  bundler
19
20
  cool.io (>= 1.4.5, < 2.0.0)
20
21
  csv (~> 3.2)
21
22
  drb (~> 2.2)
22
23
  http_parser.rb (>= 0.5.1, < 0.9.0)
24
+ logger (~> 1.6)
23
25
  msgpack (>= 1.3.1, < 2.0.0)
24
26
  serverengine (>= 2.3.2, < 3.0.0)
25
27
  sigdump (~> 0.2.5)
@@ -29,21 +31,25 @@ GEM
29
31
  webrick (~> 1.4)
30
32
  yajl-ruby (~> 1.0)
31
33
  http_parser.rb (0.8.0)
32
- msgpack (1.7.2)
33
- power_assert (2.0.3)
34
- prometheus-client (4.2.2)
34
+ logger (1.6.1)
35
+ msgpack (1.7.5)
36
+ power_assert (2.0.4)
37
+ prometheus-client (4.2.3)
38
+ base64
35
39
  rake (12.3.3)
36
- serverengine (2.3.2)
40
+ serverengine (2.4.0)
41
+ base64 (~> 0.1)
42
+ logger (~> 1.4)
37
43
  sigdump (~> 0.2.2)
38
44
  sigdump (0.2.5)
39
45
  strptime (0.2.5)
40
- test-unit (3.6.2)
46
+ test-unit (3.6.4)
41
47
  power_assert
42
48
  tzinfo (2.0.6)
43
49
  concurrent-ruby (~> 1.0)
44
- tzinfo-data (1.2024.1)
50
+ tzinfo-data (1.2024.2)
45
51
  tzinfo (>= 1.0.0)
46
- webrick (1.8.2)
52
+ webrick (1.9.0)
47
53
  yajl-ruby (1.4.3)
48
54
 
49
55
  PLATFORMS
data/README.md CHANGED
@@ -35,7 +35,7 @@ $ bundle
35
35
  The configuration builds from `<route>` sections. Each `route` section
36
36
  can have several `<match>` statement. These statements computed in order and
37
37
  positive (or in case of *negate true* negative) results break the evaluation.
38
- We can say that the sections are coupled in a **lazy evaluation OR**.
38
+ We can say that the sections are coupled in a **lazy evaluation OR**.
39
39
 
40
40
  ```
41
41
  <match example.tag**>
@@ -78,6 +78,7 @@ Configuration reference
78
78
  |------------------|-------------------------------------------------------------------------------------------------------|----------|----------|
79
79
  | labels | Label definition to match record. Example: `app:nginx` | Hash | nil |
80
80
  | namespaces | Comma separated list of namespaces. Ignored if left empty. | []string | nil |
81
+ | namespaces_regex | Comma separated list of regex for namespaces match. Ignored if left empty. | []string | nil |
81
82
  | namespace_labels | Label definition of the namespace a record originates. Example: `kubernetes.io/metadata.name=default` | Hash | nil |
82
83
  | hosts | Comma separated list of hosts. Ignored if left empty. | []string | nil |
83
84
  | container_names | Comma separated list of container names. Ignored if left empty. | []string | nil |
@@ -145,7 +146,7 @@ Output
145
146
  @label = "@NGINX"; tag = "new_tag"; {"log" => "", "kubernetes" => { "namespace_name" => "default", "labels" => {"app" => "nginx" } } }
146
147
  nil
147
148
  ```
148
- ### 2. Both `labels` and `namespace` are optional
149
+ ### 3. Both `labels` and `namespace` are optional
149
150
  Only `labels`
150
151
  ```
151
152
  <match example.tag**>
@@ -183,10 +184,10 @@ Rewrite all
183
184
  </match>
184
185
  ```
185
186
 
186
- ### 3. One of `@label` ot `tag` configuration should be specified
187
+ ### 4. One of `@label` or `tag` configuration should be specified
187
188
  If you don't rewrite either of them fluent will **likely to crash** because it will reprocess the same messages again.
188
189
 
189
- ### 4. Default route/tag
190
+ ### 5. Default route/tag
190
191
 
191
192
  Use `default_label` and/or `default_tag` to route non matching records.
192
193
 
@@ -200,6 +201,22 @@ Use `default_label` and/or `default_tag` to route non matching records.
200
201
  </match>
201
202
  ```
202
203
 
204
+ ### 6. Use of namespaces_regex
205
+
206
+ Configuration to re-tag and re-label all logs from namespaces_regex which match regex .*-system$
207
+
208
+ ```
209
+ <match example.tag**>
210
+ @type label_router
211
+ <route>
212
+ @label SYSTEM_NAMESPACE
213
+ tag new_tag
214
+ <match>
215
+ namespaces_regex .*-system$
216
+ </match>
217
+ </route>
218
+ </match>
219
+ ```
203
220
 
204
221
  ## Copyright
205
222
 
@@ -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.3.2"
6
+ spec.version = "0.5.0"
7
7
  spec.authors = ["Banzai Cloud"]
8
8
  spec.email = ["info@banzaicloud.com"]
9
9
 
@@ -24,5 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency "test-unit", "~> 3.0"
25
25
  spec.add_dependency "prometheus-client", ">= 2.1.0"
26
26
  spec.add_dependency "concurrent-ruby"
27
- spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
27
+ spec.add_runtime_dependency "fluentd", [">= 1.17.1", "< 1.18"]
28
28
  end
@@ -13,7 +13,7 @@
13
13
  # See the License for the specific language governing permissions and
14
14
  # limitations under the License
15
15
 
16
- require "fluent/plugin/output"
16
+ require "fluent/plugin/bare_output"
17
17
  require 'prometheus/client'
18
18
  require 'concurrent'
19
19
 
@@ -54,6 +54,8 @@ module Fluent
54
54
  config_param :labels, :hash, :default => {}
55
55
  desc "List of namespace definition to filter the record. Ignored if left empty."
56
56
  config_param :namespaces, :array, :default => [], value_type: :string
57
+ desc "List of regex for namespace definition to filter the record. Ignored if left empty."
58
+ config_param :namespaces_regex, :array, :default => [], value_type: :string
57
59
  desc "List of namespace labels to filter the record based on where it came from. Ignored if left empty."
58
60
  config_param :namespace_labels, :hash, :default => {}
59
61
  desc "List of hosts definition to filter the record. Ignored if left empty."
@@ -117,6 +119,10 @@ module Fluent
117
119
  unless match.namespaces.empty? || match.namespaces.include?(metadata[:namespace])
118
120
  return false
119
121
  end
122
+ # Break if list of namespaces is not empty and does not contain any entry that match actual namespace
123
+ unless match.namespaces_regex.empty? || match.namespaces_regex.any? { |pattern| Regexp.new(pattern).match?(metadata[:namespace]) }
124
+ return false
125
+ end
120
126
  # Break if list of namespace_labels is not empty and does not match actual namespace labels
121
127
  if !match.namespace_labels.empty? && !match_labels(metadata[:namespace_labels], match.namespace_labels)
122
128
  return false
@@ -222,7 +228,7 @@ module Fluent
222
228
  end
223
229
 
224
230
  @access_to_labels = record_accessor_create("$.kubernetes.labels")
225
- @access_to_namespace_labels = record_accessor_create("$.kubernetes.namespace_labels")
231
+ @access_to_namespace_labels = record_accessor_create("$.kubernetes_namespace.labels")
226
232
  @access_to_namespace = record_accessor_create("$.kubernetes.namespace_name")
227
233
  @access_to_host = record_accessor_create("$.kubernetes.host")
228
234
  @access_to_container_name = record_accessor_create("$.kubernetes.container_name")
@@ -59,6 +59,12 @@ class LabelRouterOutputTest < Test::Unit::TestCase
59
59
  </match>
60
60
  tag new_app_tag
61
61
  </route>
62
+ <route>
63
+ <match>
64
+ labels app:app3
65
+ namespaces_regex .*-system$,^kube-.*
66
+ </match>
67
+ </route>
62
68
  <route>
63
69
  <match>
64
70
  labels app:nginx
@@ -98,23 +104,42 @@ class LabelRouterOutputTest < Test::Unit::TestCase
98
104
  assert_equal(false, r2.match?(labels: { 'app3' => 'app' }, namespace: 'system'))
99
105
 
100
106
  r3 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[2], nil,nil)
101
- assert_equal(true, r3.match?(labels: { 'app' => 'nginx' }, namespace: 'dev'))
102
- assert_equal(true, r3.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
103
- assert_equal(false, r3.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox'))
107
+ # Match selector and namespace: GO
108
+ assert_equal(true, r3.match?(labels: { 'app' => 'app3' }, namespace: 'logging-system'))
109
+ # Nothing matched: NO GO
110
+ assert_equal(false, r3.match?(labels: { 'app' => 'app3' }, namespace: 'logging-system1'))
111
+ # Nothing matched: NO GO
112
+ assert_equal(false, r3.match?(labels: { 'app' => 'app3' }, namespace: 'system'))
113
+ # Nothing matched: NO GO
114
+ assert_equal(false, r3.match?(labels: { 'app' => 'app3' }, namespace: '1system'))
115
+ # Match selector and namespace: GO
116
+ assert_equal(true, r3.match?(labels: { 'app' => 'app3' }, namespace: 'kube-ns'))
117
+ # Nothing matched: NO GO
118
+ assert_equal(false, r3.match?(labels: { 'app' => 'app3' }, namespace: '1kube-ns'))
119
+ # Nothing matched: NO GO
120
+ assert_equal(false, r3.match?(labels: { 'app' => 'app3' }, namespace: 'kube'))
121
+ # Nothing matched: NO GO
122
+ assert_equal(false, r3.match?(labels: { 'app' => 'app3' }, namespace: 'kube1'))
123
+
104
124
 
105
125
  r4 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[3], nil,nil)
126
+ assert_equal(true, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev'))
127
+ assert_equal(true, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
128
+ assert_equal(false, r4.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox'))
129
+
130
+ r5 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[4], nil,nil)
106
131
  # Matching container name
107
- assert_equal(true, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container: 'mycontainer'))
132
+ assert_equal(true, r5.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container: 'mycontainer'))
108
133
  # Missing container name is equal to wrong container
109
- assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
134
+ assert_equal(false, r5.match?(labels: { 'app' => 'nginx' }, namespace: 'sandbox'))
110
135
  # Wrong container name
111
- assert_equal(false, r4.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container: 'mycontainer2'))
136
+ assert_equal(false, r5.match?(labels: { 'app' => 'nginx' }, namespace: 'dev', container: 'mycontainer2'))
112
137
  # Wrong label but good namespace and container_name
113
- assert_equal(false, r4.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox', container_name: 'mycontainer2'))
138
+ assert_equal(false, r5.match?(labels: { 'app' => 'nginx2' }, namespace: 'sandbox', container_name: 'mycontainer2'))
114
139
 
115
- r4 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[4], nil,nil)
140
+ r6 = Fluent::Plugin::LabelRouterOutput::Route.new(d.instance.routes[5], nil,nil)
116
141
  # Matching namespaces_labels
117
- assert_equal(true, r4.match?(namespaces_labels: { 'name' => 'default' }))
142
+ assert_equal(true, r6.match?(namespaces_labels: { 'name' => 'default' }))
118
143
  end
119
144
  end
120
145
 
@@ -156,15 +181,15 @@ class LabelRouterOutputTest < Test::Unit::TestCase
156
181
  event_time = event_time("2019-07-17 11:11:11 UTC")
157
182
  d = create_driver(CONFIG)
158
183
  d.run(default_tag: 'test') do
159
- d.feed(event_time, {"kubernetes" => {"namespace_labels" => {"matching" => "no"} } } )
184
+ d.feed(event_time, {"kubernetes_namespace" => {"labels" => {"matching" => "no"} } } )
160
185
  end
161
186
  d.run(default_tag: 'test2') do
162
- d.feed(event_time, {"kubernetes" => {"namespace_labels" => {"matching" => "yes"} } } )
187
+ d.feed(event_time, {"kubernetes_namespace" => {"labels" => {"matching" => "yes"} } } )
163
188
  end
164
189
  events = d.events
165
190
 
166
191
  assert_equal(1, events.size)
167
- assert_equal ["matching", event_time, {"kubernetes" => {"namespace_labels" => {"matching" => "yes"} } }], events[0]
192
+ assert_equal ["matching", event_time, {"kubernetes_namespace" => {"labels" => {"matching" => "yes"} } }], events[0]
168
193
  end
169
194
  end
170
195
 
@@ -224,6 +249,7 @@ default_tag "new_tag"
224
249
  <match>
225
250
  labels
226
251
  namespaces
252
+ namespaces_regex
227
253
  </match>
228
254
  </route>
229
255
  ]
@@ -254,6 +280,7 @@ default_tag "new_tag"
254
280
  <match>
255
281
  labels
256
282
  namespaces
283
+ namespaces_regex
257
284
  </match>
258
285
  </route>
259
286
  ]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-label-router
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Banzai Cloud
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-21 00:00:00.000000000 Z
11
+ date: 2025-04-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -72,20 +72,20 @@ dependencies:
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 0.14.10
75
+ version: 1.17.1
76
76
  - - "<"
77
77
  - !ruby/object:Gem::Version
78
- version: '2'
78
+ version: '1.18'
79
79
  type: :runtime
80
80
  prerelease: false
81
81
  version_requirements: !ruby/object:Gem::Requirement
82
82
  requirements:
83
83
  - - ">="
84
84
  - !ruby/object:Gem::Version
85
- version: 0.14.10
85
+ version: 1.17.1
86
86
  - - "<"
87
87
  - !ruby/object:Gem::Version
88
- version: '2'
88
+ version: '1.18'
89
89
  description: Label-Router helps routing log messages based on their labels and namespace
90
90
  tag in a Kubernetes environment.
91
91
  email: