fluent-plugin-kubernetes_metadata_filter 0.29.0 → 0.30.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
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ae88fa238369257fb50ba6989fc08f80986ec4a0
|
4
|
+
data.tar.gz: 263164257b94e338517a23e06b58e0a7b923f41a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e81f454859bbb3338de78dbc1b0d468d6ea87110aa41f89eafb09f1bfb1e482bb5ada1dd09cd96d892b21d7287c66c9073bf31c812bb381876c05783598b0ed2
|
7
|
+
data.tar.gz: 400599efefa4014dacb62a660a5f2a6c83a0b6012c53cd9e4f75d7cf27e9ce86823cfdb27ee5bf8204316ec391ac4e95d143eb40a67cd41692f418a9268caaf1
|
data/Gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'codeclimate-test-reporter', :group => :test, :require => nil
|
3
|
+
gem 'codeclimate-test-reporter', '<1.0.0', :group => :test, :require => nil
|
4
4
|
gem 'rubocop', require: false
|
5
5
|
|
6
6
|
# Specify your gem's dependencies in fluent-plugin-add.gemspec
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = "fluent-plugin-kubernetes_metadata_filter"
|
7
|
-
gem.version = "0.
|
7
|
+
gem.version = "0.30.0"
|
8
8
|
gem.authors = ["Jimmi Dyson"]
|
9
9
|
gem.email = ["jimmidyson@gmail.com"]
|
10
10
|
gem.description = %q{Filter plugin to add Kubernetes metadata}
|
@@ -16,6 +16,7 @@
|
|
16
16
|
# See the License for the specific language governing permissions and
|
17
17
|
# limitations under the License.
|
18
18
|
#
|
19
|
+
require_relative 'kubernetes_metadata_stats'
|
19
20
|
module Fluent
|
20
21
|
class KubernetesMetadataFilter < Fluent::Filter
|
21
22
|
K8_POD_CA_CERT = 'ca.crt'
|
@@ -57,6 +58,7 @@ module Fluent
|
|
57
58
|
:default => '^(?<name_prefix>[^_]+)_(?<container_name>[^\._]+)(\.(?<container_hash>[^_]+))?_(?<pod_name>[^_]+)_(?<namespace>[^_]+)_[^_]+_[^_]+$'
|
58
59
|
|
59
60
|
config_param :annotation_match, :array, default: []
|
61
|
+
config_param :stats_interval, :integer, default: 30
|
60
62
|
|
61
63
|
def syms_to_strs(hsh)
|
62
64
|
newhsh = {}
|
@@ -110,15 +112,63 @@ module Fluent
|
|
110
112
|
def get_pod_metadata(namespace_name, pod_name)
|
111
113
|
begin
|
112
114
|
metadata = @client.get_pod(pod_name, namespace_name)
|
113
|
-
|
114
|
-
|
115
|
-
|
115
|
+
unless metadata
|
116
|
+
@stats.bump(:pod_cache_api_nil_not_found)
|
117
|
+
else
|
118
|
+
begin
|
119
|
+
metadata = parse_pod_metadata(metadata)
|
120
|
+
@stats.bump(:pod_cache_api_updates)
|
121
|
+
return metadata
|
122
|
+
rescue Exception=>e
|
123
|
+
log.debug(e)
|
124
|
+
@stats.bump(:pod_cache_api_nil_bad_resp_payload)
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
rescue KubeException=>e
|
129
|
+
@stats.bump(:pod_cache_api_nil_error)
|
130
|
+
log.debug "Exception encountered fetching pod metadata from Kubernetes API #{@apiVersion} endpoint #{@kubernetes_url}: #{e.message}"
|
131
|
+
nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def dump_stats
|
136
|
+
@curr_time = Time.now
|
137
|
+
return if @curr_time.to_i - @prev_time.to_i < @stats_interval
|
138
|
+
@prev_time = @curr_time
|
139
|
+
@stats.set(:pod_cache_size, @cache.count)
|
140
|
+
@stats.set(:namespace_cache_size, @namespace_cache.count)
|
141
|
+
log.info(@stats)
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_namespace_metadata(namespace_name)
|
145
|
+
begin
|
146
|
+
metadata = @client.get_namespace(namespace_name)
|
147
|
+
unless metadata
|
148
|
+
@stats.bump(:namespace_cache_api_nil_not_found)
|
149
|
+
else
|
150
|
+
begin
|
151
|
+
metadata = parse_namespace_metadata(metadata)
|
152
|
+
@stats.bump(:namespace_cache_api_updates)
|
153
|
+
return metadata
|
154
|
+
rescue Exception => e
|
155
|
+
log.debug(e)
|
156
|
+
@stats.bump(:namespace_cache_api_nil_bad_resp_payload)
|
157
|
+
nil
|
158
|
+
end
|
159
|
+
end
|
160
|
+
rescue KubeException => kube_error
|
161
|
+
@stats.bump(:namespace_cache_api_nil_error)
|
162
|
+
log.debug "Exception encountered fetching namespace metadata from Kubernetes API #{@apiVersion} endpoint #{@kubernetes_url}: #{kube_error.message}"
|
116
163
|
nil
|
117
164
|
end
|
118
165
|
end
|
119
166
|
|
120
167
|
def initialize
|
121
168
|
super
|
169
|
+
@stats = KubernetesMetadata::Stats.new
|
170
|
+
@prev_time = Time.now
|
171
|
+
|
122
172
|
end
|
123
173
|
|
124
174
|
def configure(conf)
|
@@ -235,6 +285,7 @@ module Fluent
|
|
235
285
|
|
236
286
|
this = self
|
237
287
|
pod_metadata = @cache.getset(cache_key) {
|
288
|
+
@stats.bump(:pod_cache_miss)
|
238
289
|
md = this.get_pod_metadata(
|
239
290
|
namespace_name,
|
240
291
|
pod_name,
|
@@ -245,14 +296,8 @@ module Fluent
|
|
245
296
|
|
246
297
|
if @include_namespace_metadata
|
247
298
|
namespace_metadata = @namespace_cache.getset(namespace_name) {
|
248
|
-
|
249
|
-
|
250
|
-
if namespace
|
251
|
-
parse_namespace_metadata(namespace)
|
252
|
-
end
|
253
|
-
rescue KubeException
|
254
|
-
nil
|
255
|
-
end
|
299
|
+
@stats.bump(:namespace_cache_miss)
|
300
|
+
get_namespace_metadata(namespace_name)
|
256
301
|
}
|
257
302
|
metadata.merge!(namespace_metadata) if namespace_metadata
|
258
303
|
end
|
@@ -289,7 +334,7 @@ module Fluent
|
|
289
334
|
|
290
335
|
new_es.add(time, record)
|
291
336
|
}
|
292
|
-
|
337
|
+
dump_stats
|
293
338
|
new_es
|
294
339
|
end
|
295
340
|
|
@@ -317,9 +362,11 @@ module Fluent
|
|
317
362
|
end
|
318
363
|
unless metadata
|
319
364
|
log.debug "Error: could not match CONTAINER_NAME from record #{record}"
|
365
|
+
@stats.dump(:container_name_match_failed)
|
320
366
|
end
|
321
367
|
elsif record.has_key?('CONTAINER_NAME') && record['CONTAINER_NAME'].start_with?('k8s_')
|
322
368
|
log.debug "Error: no container name and id in record #{record}"
|
369
|
+
@stats.dump(:container_name_id_missing)
|
323
370
|
end
|
324
371
|
|
325
372
|
if metadata
|
@@ -329,6 +376,7 @@ module Fluent
|
|
329
376
|
new_es.add(time, record)
|
330
377
|
}
|
331
378
|
|
379
|
+
dump_stats
|
332
380
|
new_es
|
333
381
|
end
|
334
382
|
|
@@ -341,7 +389,9 @@ module Fluent
|
|
341
389
|
unless @preserve_json_log
|
342
390
|
record.delete(@merge_json_log_key)
|
343
391
|
end
|
344
|
-
rescue JSON::ParserError
|
392
|
+
rescue JSON::ParserError=>e
|
393
|
+
@stats.bump(:merge_json_parse_errors)
|
394
|
+
log.debug(e)
|
345
395
|
end
|
346
396
|
end
|
347
397
|
end
|
@@ -376,9 +426,7 @@ module Fluent
|
|
376
426
|
watcher = @client.watch_pods(resource_version)
|
377
427
|
rescue Exception => e
|
378
428
|
message = "Exception encountered fetching metadata from Kubernetes API endpoint: #{e.message}"
|
379
|
-
if e.respond_to?(:response)
|
380
|
-
message += " (#{e.response})"
|
381
|
-
end
|
429
|
+
message += " (#{e.response})" if e.respond_to?(:response)
|
382
430
|
|
383
431
|
raise Fluent::ConfigError, message
|
384
432
|
end
|
@@ -390,20 +438,32 @@ module Fluent
|
|
390
438
|
cached = @cache[cache_key]
|
391
439
|
if cached
|
392
440
|
@cache[cache_key] = parse_pod_metadata(notice.object)
|
441
|
+
@stats.bump(:pod_cache_watch_updates)
|
442
|
+
else
|
443
|
+
@stats.bump(:pod_cache_watch_misses)
|
393
444
|
end
|
394
445
|
when 'DELETED'
|
395
446
|
cache_key = "#{notice.object['metadata']['namespace']}_#{notice.object['metadata']['name']}"
|
396
447
|
@cache.delete(cache_key)
|
448
|
+
@stats.bump(:pod_cache_watch_deletes)
|
397
449
|
else
|
398
450
|
# Don't pay attention to creations, since the created pod may not
|
399
451
|
# end up on this node.
|
452
|
+
@stats.bump(:pod_cache_watch_ignored)
|
400
453
|
end
|
401
454
|
end
|
402
455
|
end
|
403
456
|
|
404
457
|
def start_namespace_watch
|
405
|
-
|
406
|
-
|
458
|
+
begin
|
459
|
+
resource_version = @client.get_namespaces.resourceVersion
|
460
|
+
watcher = @client.watch_namespaces(resource_version)
|
461
|
+
rescue Exception=>e
|
462
|
+
message = "start_namespace_watch: Exception encountered setting up namespace watch from Kubernetes API #{@apiVersion} endpoint #{@kubernetes_url}: #{e.message}"
|
463
|
+
message += " (#{e.response})" if e.respond_to?(:response)
|
464
|
+
log.debug(message)
|
465
|
+
raise Fluent::ConfigError, message
|
466
|
+
end
|
407
467
|
watcher.each do |notice|
|
408
468
|
case notice.type
|
409
469
|
when 'MODIFIED'
|
@@ -411,12 +471,17 @@ module Fluent
|
|
411
471
|
cached = @namespace_cache[cache_key]
|
412
472
|
if cached
|
413
473
|
@namespace_cache[cache_key] = parse_namespace_metadata(notice.object)
|
474
|
+
@stats.bump(:namespace_cache_watch_updates)
|
475
|
+
else
|
476
|
+
@stats.bump(:namespace_cache_watch_misses)
|
414
477
|
end
|
415
478
|
when 'DELETED'
|
416
479
|
@namespace_cache.delete(notice.object['metadata']['name'])
|
480
|
+
@stats.bump(:namespace_cache_watch_deletes)
|
417
481
|
else
|
418
482
|
# Don't pay attention to creations, since the created namespace may not
|
419
483
|
# be used by any pod on this node.
|
484
|
+
@stats.bump(:namespace_cache_watch_ignored)
|
420
485
|
end
|
421
486
|
end
|
422
487
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
|
3
|
+
# Kubernetes metadata
|
4
|
+
#
|
5
|
+
# Copyright 2015 Red Hat, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
module KubernetesMetadata
|
20
|
+
class Stats
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@stats = LruRedux::TTL::ThreadSafeCache.new(1000, 3600)
|
24
|
+
end
|
25
|
+
|
26
|
+
def bump(key)
|
27
|
+
@stats[key] = @stats.getset(key) { 0 } + 1
|
28
|
+
end
|
29
|
+
|
30
|
+
def set(key, value)
|
31
|
+
@stats[key] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
"stats - " + [].tap do |a|
|
36
|
+
@stats.each {|k,v| a << "#{k.to_s}: #{v}"}
|
37
|
+
end.join(', ')
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd Kubernetes Metadata Filter Plugin - Enrich Fluentd events with
|
3
|
+
# Kubernetes metadata
|
4
|
+
#
|
5
|
+
# Copyright 2015 Red Hat, Inc.
|
6
|
+
#
|
7
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
|
+
# you may not use this file except in compliance with the License.
|
9
|
+
# You may obtain a copy of the License at
|
10
|
+
#
|
11
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
+
#
|
13
|
+
# Unless required by applicable law or agreed to in writing, software
|
14
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
16
|
+
# See the License for the specific language governing permissions and
|
17
|
+
# limitations under the License.
|
18
|
+
#
|
19
|
+
require_relative '../helper'
|
20
|
+
require 'fluent/plugin/kubernetes_metadata_stats'
|
21
|
+
require 'webmock/test_unit'
|
22
|
+
WebMock.disable_net_connect!
|
23
|
+
|
24
|
+
class KubernetesMetadataCacheStatsTest < Test::Unit::TestCase
|
25
|
+
|
26
|
+
test 'watch stats' do
|
27
|
+
require 'lru_redux'
|
28
|
+
stats = KubernetesMetadata::Stats.new
|
29
|
+
stats.bump(:missed)
|
30
|
+
stats.bump(:deleted)
|
31
|
+
stats.bump(:deleted)
|
32
|
+
|
33
|
+
assert_equal("stats - deleted: 2, missed: 1", stats.to_s)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-kubernetes_metadata_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.30.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jimmi Dyson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -207,6 +207,7 @@ files:
|
|
207
207
|
- circle.yml
|
208
208
|
- fluent-plugin-kubernetes_metadata_filter.gemspec
|
209
209
|
- lib/fluent/plugin/filter_kubernetes_metadata.rb
|
210
|
+
- lib/fluent/plugin/kubernetes_metadata_stats.rb
|
210
211
|
- test/cassettes/invalid_api_server_config.yml
|
211
212
|
- test/cassettes/kubernetes_docker_metadata.yml
|
212
213
|
- test/cassettes/kubernetes_docker_metadata_annotations.yml
|
@@ -217,6 +218,7 @@ files:
|
|
217
218
|
- test/cassettes/valid_kubernetes_api_server.yml
|
218
219
|
- test/helper.rb
|
219
220
|
- test/plugin/test.token
|
221
|
+
- test/plugin/test_cache_stats.rb
|
220
222
|
- test/plugin/test_filter_kubernetes_metadata.rb
|
221
223
|
homepage: https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter
|
222
224
|
licenses:
|
@@ -238,7 +240,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
238
240
|
version: '0'
|
239
241
|
requirements: []
|
240
242
|
rubyforge_project:
|
241
|
-
rubygems_version: 2.6.
|
243
|
+
rubygems_version: 2.6.12
|
242
244
|
signing_key:
|
243
245
|
specification_version: 4
|
244
246
|
summary: Filter plugin to add Kubernetes metadata
|
@@ -253,4 +255,5 @@ test_files:
|
|
253
255
|
- test/cassettes/valid_kubernetes_api_server.yml
|
254
256
|
- test/helper.rb
|
255
257
|
- test/plugin/test.token
|
258
|
+
- test/plugin/test_cache_stats.rb
|
256
259
|
- test/plugin/test_filter_kubernetes_metadata.rb
|