fluent-plugin-kubernetes_metadata_filter 2.8.1 → 2.9.3

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: 71fd60517a92c89e8c35bc91a3147487ff0637ae41378ecf82b047424cdb203f
4
- data.tar.gz: 310b9a7bbb7e5bd59d1aa3deedb699114f561295b4b3a97fdf54fadcf6d7ee08
3
+ metadata.gz: b6344b1f6ff0602b9d78a5cf317ba5b44e54d0040d6172d102edd002a364d1e7
4
+ data.tar.gz: 421689d196ae7a0c307ac7e8d4d066755464b76357921e7f6c55ad122ca744b0
5
5
  SHA512:
6
- metadata.gz: 76ccb8d8b2a2d26ca1e2823a93c38fef974e76526f402f11a10c8ea4697cbda765370eb202177490e9a4aadb10fef4f9980ba4e38cb39953c55ae3bf49ac3bf4
7
- data.tar.gz: 8ea9696e6df02bf264a7f0e68ab36732adae9a007379e6bbd841633b6ad6dd830d9241a30bdcd0744183151898fdcc71711be14656973a47d8afa7a1f273abb1
6
+ metadata.gz: 63b03d82fec8888d13f4f752b1ea2519a7c3e594ac45eb0363109d323a35a56174fdd0fa401b787069e5bae84168878ff08baefa899810776b0d710bd55d3c04
7
+ data.tar.gz: 6368f491a96f30482ded9e12bdc0e80232aebfc26a3a98be75133312c96b1311ff04ce2de5d818a06ba67d2d75274b658471668bfa846db2251202ea92f4b96e
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-kubernetes_metadata_filter (2.8.1)
4
+ fluent-plugin-kubernetes_metadata_filter (2.9.3)
5
5
  fluentd (>= 0.14.0, < 1.15)
6
6
  kubeclient (>= 4.0.0, < 5.0.0)
7
7
  lru_redux
@@ -11,7 +11,7 @@ GEM
11
11
  specs:
12
12
  addressable (2.8.0)
13
13
  public_suffix (>= 2.0.2, < 5.0)
14
- ast (2.4.1)
14
+ ast (2.4.2)
15
15
  bump (0.10.0)
16
16
  charlock_holmes (0.7.7)
17
17
  codeclimate-test-reporter (0.6.0)
@@ -22,7 +22,7 @@ GEM
22
22
  github-linguist
23
23
  crack (0.4.5)
24
24
  rexml
25
- docile (1.3.5)
25
+ docile (1.4.0)
26
26
  domain_name (0.5.20190701)
27
27
  unf (>= 0.0.5, < 1.0.0)
28
28
  escape_utils (1.2.1)
@@ -30,19 +30,19 @@ GEM
30
30
  ffi-compiler (1.0.1)
31
31
  ffi (>= 1.0.0)
32
32
  rake
33
- fluentd (1.14.0)
33
+ fluentd (1.14.3)
34
34
  bundler
35
35
  cool.io (>= 1.4.5, < 2.0.0)
36
- http_parser.rb (>= 0.5.1, < 0.8.0)
36
+ http_parser.rb (>= 0.5.1, < 0.9.0)
37
37
  msgpack (>= 1.3.1, < 2.0.0)
38
38
  serverengine (>= 2.2.2, < 3.0.0)
39
39
  sigdump (~> 0.2.2)
40
- strptime (>= 0.2.2, < 1.0.0)
40
+ strptime (>= 0.2.4, < 1.0.0)
41
41
  tzinfo (>= 1.0, < 3.0)
42
42
  tzinfo-data (~> 1.0)
43
43
  webrick (>= 1.4.2, < 1.8.0)
44
44
  yajl-ruby (~> 1.0)
45
- github-linguist (7.12.2)
45
+ github-linguist (7.17.0)
46
46
  charlock_holmes (~> 0.7.7)
47
47
  escape_utils (~> 1.2.0)
48
48
  mini_mime (~> 1.0)
@@ -59,7 +59,7 @@ GEM
59
59
  http-form_data (2.3.0)
60
60
  http-parser (1.2.3)
61
61
  ffi-compiler (>= 1.0, < 2.0)
62
- http_parser.rb (0.7.0)
62
+ http_parser.rb (0.8.0)
63
63
  jsonpath (1.1.0)
64
64
  multi_json
65
65
  kubeclient (4.9.2)
@@ -68,43 +68,43 @@ GEM
68
68
  recursive-open-struct (~> 1.1, >= 1.1.1)
69
69
  rest-client (~> 2.0)
70
70
  lru_redux (1.1.0)
71
- mime-types (3.3.1)
71
+ mime-types (3.4.1)
72
72
  mime-types-data (~> 3.2015)
73
- mime-types-data (3.2021.0901)
74
- mini_mime (1.0.2)
73
+ mime-types-data (3.2021.1115)
74
+ mini_mime (1.1.2)
75
75
  minitest (4.7.5)
76
76
  msgpack (1.4.2)
77
77
  multi_json (1.15.0)
78
78
  netrc (0.11.0)
79
- parallel (1.20.1)
80
- parser (3.0.0.0)
79
+ parallel (1.21.0)
80
+ parser (3.0.2.0)
81
81
  ast (~> 2.4.1)
82
- power_assert (1.2.0)
82
+ power_assert (2.0.1)
83
83
  public_suffix (4.0.6)
84
84
  rainbow (3.0.0)
85
- rake (13.0.3)
85
+ rake (13.0.6)
86
86
  recursive-open-struct (1.1.3)
87
- regexp_parser (2.0.3)
87
+ regexp_parser (2.1.1)
88
88
  rest-client (2.1.0)
89
89
  http-accept (>= 1.7.0, < 2.0)
90
90
  http-cookie (>= 1.0.2, < 2.0)
91
91
  mime-types (>= 1.16, < 4.0)
92
92
  netrc (~> 0.8)
93
93
  rexml (3.2.5)
94
- rr (1.2.1)
95
- rubocop (1.8.1)
94
+ rr (3.0.8)
95
+ rubocop (1.22.3)
96
96
  parallel (~> 1.10)
97
97
  parser (>= 3.0.0.0)
98
98
  rainbow (>= 2.2.2, < 4.0)
99
99
  regexp_parser (>= 1.8, < 3.0)
100
100
  rexml
101
- rubocop-ast (>= 1.2.0, < 2.0)
101
+ rubocop-ast (>= 1.12.0, < 2.0)
102
102
  ruby-progressbar (~> 1.7)
103
103
  unicode-display_width (>= 1.4.0, < 3.0)
104
- rubocop-ast (1.4.0)
105
- parser (>= 2.7.1.5)
104
+ rubocop-ast (1.12.0)
105
+ parser (>= 3.0.1.1)
106
106
  ruby-progressbar (1.11.0)
107
- rugged (1.1.0)
107
+ rugged (1.2.0)
108
108
  serverengine (2.2.4)
109
109
  sigdump (~> 0.2.2)
110
110
  sigdump (0.2.4)
@@ -113,7 +113,7 @@ GEM
113
113
  simplecov-html (~> 0.11)
114
114
  simplecov_json_formatter (~> 0.1)
115
115
  simplecov-html (0.12.3)
116
- simplecov_json_formatter (0.1.2)
116
+ simplecov_json_formatter (0.1.3)
117
117
  strptime (0.2.5)
118
118
  test-unit (3.0.9)
119
119
  power_assert
@@ -122,15 +122,15 @@ GEM
122
122
  test-unit (>= 2.5.2)
123
123
  tzinfo (2.0.4)
124
124
  concurrent-ruby (~> 1.0)
125
- tzinfo-data (1.2021.1)
125
+ tzinfo-data (1.2021.5)
126
126
  tzinfo (>= 1.0.0)
127
127
  unf (0.1.4)
128
128
  unf_ext
129
129
  unf_ext (0.0.8)
130
- unicode-display_width (2.0.0)
130
+ unicode-display_width (2.1.0)
131
131
  vcr (6.0.0)
132
- webmock (3.11.1)
133
- addressable (>= 2.3.6)
132
+ webmock (3.14.0)
133
+ addressable (>= 2.8.0)
134
134
  crack (>= 0.3.2)
135
135
  hashdiff (>= 0.4.0, < 2.0.0)
136
136
  webrick (1.7.0)
data/README.md CHANGED
@@ -45,8 +45,10 @@ This must used named capture groups for `container_name`, `pod_name` & `namespac
45
45
  * `cache_size` - size of the cache of Kubernetes metadata to reduce requests to the API server (default: `1000`)
46
46
  * `cache_ttl` - TTL in seconds of each cached element. Set to negative value to disable TTL eviction (default: `3600` - 1 hour)
47
47
  * `watch` - set up a watch on pods on the API server for updates to metadata (default: `true`)
48
- * `de_dot` - replace dots in labels and annotations with configured `de_dot_separator`, required for ElasticSearch 2.x compatibility (default: `true`)
48
+ * `de_dot` - replace dots in labels and annotations with configured `de_dot_separator`, required for Datadog and ElasticSearch 2.x compatibility (default: `true`)
49
49
  * `de_dot_separator` - separator to use if `de_dot` is enabled (default: `_`)
50
+ * `de_slash` - replace slashes in labels and annotations with configured `de_slash_separator`, required for Datadog compatibility (default: `false`)
51
+ * `de_slash_separator` - separator to use if `de_slash` is enabled (default: `__`)
50
52
  * *DEPRECATED* `use_journal` - If false, messages are expected to be formatted and tagged as if read by the fluentd in\_tail plugin with wildcard filename. If true, messages are expected to be formatted as if read from the systemd journal. The `MESSAGE` field has the full message. The `CONTAINER_NAME` field has the encoded k8s metadata (see below). The `CONTAINER_ID_FULL` field has the full container uuid. This requires docker to use the `--log-driver=journald` log driver. If unset (the default), the plugin will use the `CONTAINER_NAME` and `CONTAINER_ID_FULL` fields
51
53
  if available, otherwise, will use the tag in the `tag_to_kubernetes_name_regexp` format.
52
54
  * `container_name_to_kubernetes_regexp` - The regular expression used to extract the k8s metadata encoded in the journal `CONTAINER_NAME` field default: See [code](https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter/blob/master/lib/fluent/plugin/filter_kubernetes_metadata.rb#L68)
@@ -74,7 +76,7 @@ payload. The following configuration options are removed:
74
76
 
75
77
  One way of preserving JSON logs can be through the [parser plugin](https://docs.fluentd.org/filter/parser)
76
78
 
77
- **NOTE** As of this release, the use of `use_journal` is **DEPRECATED**. If this setting is not present, the plugin will
79
+ **NOTE** As of release v2.1.4, the use of `use_journal` is **DEPRECATED**. If this setting is not present, the plugin will
78
80
  attempt to figure out the source of the metadata fields from the following:
79
81
  - If `lookup_from_k8s_field true` (the default) and the following fields are present in the record:
80
82
  `docker.container_id`, `kubernetes.namespace_name`, `kubernetes.pod_name`, `kubernetes.container_name`,
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = 'fluent-plugin-kubernetes_metadata_filter'
8
- gem.version = '2.8.1'
8
+ gem.version = '2.9.3'
9
9
  gem.authors = ['Jimmi Dyson']
10
10
  gem.email = ['jimmidyson@gmail.com']
11
11
  gem.description = 'Filter plugin to add Kubernetes metadata'
@@ -51,13 +51,23 @@ module Fluent::Plugin
51
51
  config_param :client_key, :string, default: nil
52
52
  config_param :ca_file, :string, default: nil
53
53
  config_param :verify_ssl, :bool, default: true
54
- config_param :tag_to_kubernetes_name_regexp,
55
- :string,
56
- default: 'var\.log\.containers\.(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace>[^_]+)_(?<container_name>.+)-(?<docker_id>[a-z0-9]{64})\.log$'
54
+
55
+ REGEX_VAR_LOG_PODS = '(?<prefix>var\.log\.pods)\.(?<namespace>[^_]+)_(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<pod_uuid>[a-z0-9-]*)\.(?<container_name>.+)\..*\.log$'
56
+ REGEX_VAR_LOG_CONTAINERS = '(?<prefix>var\.log\.containers)\.(?<pod_name>[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*)_(?<namespace>[^_]+)_(?<container_name>.+)-(?<docker_id>[a-z0-9]{64})\.log$'
57
+
58
+ #tag_to_kubernetes_name_regexp which must include named capture groups:
59
+ # namespace - The namespace in which the pod is deployed
60
+ # pod_name - The pod name
61
+ # container_name - The name of the container
62
+ # pod_uuid (/var/log/pods) | docker_id (/var/log/containers) - Unique identifier used in caching of either pod_uuid or the container hash
63
+ config_param :tag_to_kubernetes_name_regexp, :string, default: "(#{REGEX_VAR_LOG_PODS}|#{REGEX_VAR_LOG_CONTAINERS})"
64
+
57
65
  config_param :bearer_token_file, :string, default: nil
58
66
  config_param :secret_dir, :string, default: '/var/run/secrets/kubernetes.io/serviceaccount'
59
67
  config_param :de_dot, :bool, default: true
60
68
  config_param :de_dot_separator, :string, default: '_'
69
+ config_param :de_slash, :bool, default: false
70
+ config_param :de_slash_separator, :string, default: '__'
61
71
  # if reading from the journal, the record will contain the following fields in the following
62
72
  # format:
63
73
  # CONTAINER_NAME=k8s_$containername.$containerhash_$podname_$namespacename_$poduuid_$rand32bitashex
@@ -98,15 +108,15 @@ module Fluent::Plugin
98
108
  config_param :watch_retry_max_times, :integer, default: 10
99
109
 
100
110
  def fetch_pod_metadata(namespace_name, pod_name)
101
- log.trace("fetching pod metadata: #{namespace_name}/#{pod_name}") if log.trace?
111
+ log.trace("fetching pod metadata: #{namespace_name}/#{pod_name}")
102
112
  options = {
103
113
  resource_version: '0' # Fetch from API server cache instead of etcd quorum read
104
114
  }
105
115
  pod_object = @client.get_pod(pod_name, namespace_name, options)
106
- log.trace("raw metadata for #{namespace_name}/#{pod_name}: #{pod_object}") if log.trace?
116
+ log.trace("raw metadata for #{namespace_name}/#{pod_name}: #{pod_object}")
107
117
  metadata = parse_pod_metadata(pod_object)
108
118
  @stats.bump(:pod_cache_api_updates)
109
- log.trace("parsed metadata for #{namespace_name}/#{pod_name}: #{metadata}") if log.trace?
119
+ log.trace("parsed metadata for #{namespace_name}/#{pod_name}: #{metadata}")
110
120
  @cache[metadata['pod_id']] = metadata
111
121
  rescue StandardError => e
112
122
  @stats.bump(:pod_cache_api_nil_error)
@@ -130,15 +140,15 @@ module Fluent::Plugin
130
140
  end
131
141
 
132
142
  def fetch_namespace_metadata(namespace_name)
133
- log.trace("fetching namespace metadata: #{namespace_name}") if log.trace?
143
+ log.trace("fetching namespace metadata: #{namespace_name}")
134
144
  options = {
135
145
  resource_version: '0' # Fetch from API server cache instead of etcd quorum read
136
146
  }
137
147
  namespace_object = @client.get_namespace(namespace_name, nil, options)
138
- log.trace("raw metadata for #{namespace_name}: #{namespace_object}") if log.trace?
148
+ log.trace("raw metadata for #{namespace_name}: #{namespace_object}")
139
149
  metadata = parse_namespace_metadata(namespace_object)
140
150
  @stats.bump(:namespace_cache_api_updates)
141
- log.trace("parsed metadata for #{namespace_name}: #{metadata}") if log.trace?
151
+ log.trace("parsed metadata for #{namespace_name}: #{metadata}")
142
152
  @namespace_cache[metadata['namespace_id']] = metadata
143
153
  rescue StandardError => e
144
154
  @stats.bump(:namespace_cache_api_nil_error)
@@ -154,10 +164,6 @@ module Fluent::Plugin
154
164
  def configure(conf)
155
165
  super
156
166
 
157
- def log.trace?
158
- level == Fluent::Log::LEVEL_TRACE
159
- end
160
-
161
167
  require 'kubeclient'
162
168
  require 'lru_redux'
163
169
  @stats = KubernetesMetadata::Stats.new
@@ -166,6 +172,10 @@ module Fluent::Plugin
166
172
  raise Fluent::ConfigError, "Invalid de_dot_separator: cannot be or contain '.'"
167
173
  end
168
174
 
175
+ if @de_slash && @de_slash_separator.include?('/')
176
+ raise Fluent::ConfigError, "Invalid de_slash_separator: cannot be or contain '/'"
177
+ end
178
+
169
179
  if @cache_ttl < 0
170
180
  log.info 'Setting the cache TTL to :none because it was <= 0'
171
181
  @cache_ttl = :none
@@ -181,6 +191,7 @@ module Fluent::Plugin
181
191
  @namespace_cache = LruRedux::TTL::ThreadSafeCache.new(@cache_size, @cache_ttl)
182
192
 
183
193
  @tag_to_kubernetes_name_regexp_compiled = Regexp.compile(@tag_to_kubernetes_name_regexp)
194
+
184
195
  @container_name_to_kubernetes_regexp_compiled = Regexp.compile(@container_name_to_kubernetes_regexp)
185
196
 
186
197
  # Use Kubernetes default service account if we're in a pod.
@@ -294,40 +305,47 @@ module Fluent::Plugin
294
305
  end
295
306
  end
296
307
 
297
- def get_metadata_for_record(namespace_name, pod_name, container_name, container_id, create_time, batch_miss_cache)
308
+ def get_metadata_for_record(source, namespace_name, pod_name, container_name, cache_key, create_time, batch_miss_cache)
298
309
  metadata = {
299
- 'docker' => { 'container_id' => container_id },
310
+ 'docker' => { 'container_id' => "" },
300
311
  'kubernetes' => {
301
312
  'container_name' => container_name,
302
313
  'namespace_name' => namespace_name,
303
314
  'pod_name' => pod_name
304
315
  }
305
316
  }
317
+ metadata['docker']['container_id'] = cache_key unless source == 'var.log.pods'
318
+ container_cache_key = container_name
306
319
  if present?(@kubernetes_url)
307
- pod_metadata = get_pod_metadata(container_id, namespace_name, pod_name, create_time, batch_miss_cache)
308
-
309
- if (pod_metadata.include? 'containers') && (pod_metadata['containers'].include? container_id) && !@skip_container_metadata
310
- metadata['kubernetes']['container_image'] = pod_metadata['containers'][container_id]['image']
311
- metadata['kubernetes']['container_image_id'] = pod_metadata['containers'][container_id]['image_id']
320
+ pod_metadata = get_pod_metadata(cache_key, namespace_name, pod_name, create_time, batch_miss_cache)
321
+ if (pod_metadata.include? 'containers') && (pod_metadata['containers'].include? container_cache_key) && !@skip_container_metadata
322
+ metadata['kubernetes']['container_image'] = pod_metadata['containers'][container_cache_key]['image']
323
+ metadata['kubernetes']['container_image_id'] = pod_metadata['containers'][container_cache_key]['image_id'] unless pod_metadata['containers'][container_cache_key]['image_id'].empty?
324
+ metadata['docker']['container_id'] = pod_metadata['containers'][container_cache_key]['containerID'] unless pod_metadata['containers'][container_cache_key]['containerID'].empty?
312
325
  end
313
326
 
314
327
  metadata['kubernetes'].merge!(pod_metadata) if pod_metadata
315
328
  metadata['kubernetes'].delete('containers')
316
329
  end
330
+ metadata.delete('docker') if metadata['docker'] && (metadata['docker']['container_id'].nil? || metadata['docker']['container_id'].empty?)
317
331
  metadata
318
332
  end
319
333
 
320
334
  def filter_stream(tag, es)
321
335
  return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
322
-
323
336
  new_es = Fluent::MultiEventStream.new
324
337
  tag_match_data = tag.match(@tag_to_kubernetes_name_regexp_compiled) unless @use_journal
325
338
  tag_metadata = nil
326
339
  batch_miss_cache = {}
327
340
  es.each do |time, record|
328
341
  if tag_match_data && tag_metadata.nil?
329
- tag_metadata = get_metadata_for_record(tag_match_data['namespace'], tag_match_data['pod_name'], tag_match_data['container_name'],
330
- tag_match_data['docker_id'], create_time_from_record(record, time), batch_miss_cache)
342
+ cache_key = if tag_match_data.names.include?('pod_uuid') && !tag_match_data['pod_uuid'].nil?
343
+ tag_match_data['pod_uuid']
344
+ else
345
+ tag_match_data['docker_id']
346
+ end
347
+ tag_metadata = get_metadata_for_record(tag_match_data['prefix'], tag_match_data['namespace'], tag_match_data['pod_name'], tag_match_data['container_name'],
348
+ cache_key, create_time_from_record(record, time), batch_miss_cache)
331
349
  end
332
350
  metadata = Marshal.load(Marshal.dump(tag_metadata)) if tag_metadata
333
351
  if (@use_journal || @use_journal.nil?) &&
@@ -340,12 +358,11 @@ module Fluent::Plugin
340
358
  record['kubernetes'].key?('pod_name') &&
341
359
  record['kubernetes'].key?('container_name') &&
342
360
  record['docker'].key?('container_id') &&
343
- (k_metadata = get_metadata_for_record(record['kubernetes']['namespace_name'], record['kubernetes']['pod_name'],
361
+ (k_metadata = get_metadata_for_record(tag_match_data['prefix'], record['kubernetes']['namespace_name'], record['kubernetes']['pod_name'],
344
362
  record['kubernetes']['container_name'], record['docker']['container_id'],
345
363
  create_time_from_record(record, time), batch_miss_cache))
346
364
  metadata = k_metadata
347
365
  end
348
-
349
366
  record = record.merge(metadata) if metadata
350
367
  new_es.add(time, record)
351
368
  end
@@ -357,8 +374,8 @@ module Fluent::Plugin
357
374
  metadata = nil
358
375
  if record.key?('CONTAINER_NAME') && record.key?('CONTAINER_ID_FULL')
359
376
  metadata = record['CONTAINER_NAME'].match(@container_name_to_kubernetes_regexp_compiled) do |match_data|
360
- get_metadata_for_record(match_data['namespace'], match_data['pod_name'], match_data['container_name'],
361
- record['CONTAINER_ID_FULL'], create_time_from_record(record, time), batch_miss_cache)
377
+ get_metadata_for_record(match_data['name_prefix'], match_data['namespace'], match_data['pod_name'], match_data['container_name'],
378
+ record['CONTAINER_ID_FULL'], create_time_from_record(record, time), batch_miss_cache)
362
379
  end
363
380
  unless metadata
364
381
  log.debug "Error: could not match CONTAINER_NAME from record #{record}"
@@ -381,6 +398,16 @@ module Fluent::Plugin
381
398
  end
382
399
  end
383
400
 
401
+ def de_slash!(h)
402
+ h.keys.each do |ref|
403
+ next unless h[ref] && ref =~ /\//
404
+
405
+ v = h.delete(ref)
406
+ newref = ref.to_s.gsub('/', @de_slash_separator)
407
+ h[newref] = v
408
+ end
409
+ end
410
+
384
411
  # copied from activesupport
385
412
  def present?(object)
386
413
  object.respond_to?(:empty?) ? !object.empty? : !!object
@@ -24,8 +24,6 @@ module KubernetesMetadata
24
24
  metadata = {}
25
25
  ids = @id_cache[key]
26
26
  if ids.nil?
27
- # FAST PATH
28
- # Cache hit, fetch metadata from the cache
29
27
  @stats.bump(:id_cache_miss)
30
28
  return batch_miss_cache["#{namespace_name}_#{pod_name}"] if batch_miss_cache.key?("#{namespace_name}_#{pod_name}")
31
29
 
@@ -65,7 +63,7 @@ module KubernetesMetadata
65
63
  @stats.bump(:id_cache_orphaned_record)
66
64
  end
67
65
  if @allow_orphans
68
- log.trace("orphaning message for: #{namespace_name}/#{pod_name} ") if log.trace?
66
+ log.trace("orphaning message for: #{namespace_name}/#{pod_name} ")
69
67
  metadata = {
70
68
  'orphaned_namespace' => namespace_name,
71
69
  'namespace_name' => @orphaned_namespace_name,
@@ -47,6 +47,10 @@ module KubernetesMetadata
47
47
  de_dot!(labels) unless @skip_labels
48
48
  de_dot!(annotations)
49
49
  end
50
+ if @de_slash
51
+ de_slash!(labels) unless @skip_labels
52
+ de_slash!(annotations)
53
+ end
50
54
  kubernetes_metadata = {
51
55
  'namespace_id' => namespace_object[:metadata][:uid],
52
56
  'creation_timestamp' => namespace_object[:metadata][:creationTimestamp]
@@ -65,14 +69,18 @@ module KubernetesMetadata
65
69
  de_dot!(labels) unless @skip_labels
66
70
  de_dot!(annotations)
67
71
  end
72
+ if @de_slash
73
+ de_slash!(labels) unless @skip_labels
74
+ de_slash!(annotations)
75
+ end
68
76
 
69
77
  # collect container information
70
78
  container_meta = {}
71
79
  begin
72
80
  pod_object[:status][:containerStatuses].each do |container_status|
73
- # get plain container id (eg. docker://hash -> hash)
74
- container_id = container_status[:containerID].sub(%r{^[-_a-zA-Z0-9]+://}, '')
75
- container_meta[container_id] = if @skip_container_metadata
81
+ container_id = (container_status[:containerID]||"").sub(%r{^[-_a-zA-Z0-9]+://}, '')
82
+ key = container_status[:name]
83
+ container_meta[key] = if @skip_container_metadata
76
84
  {
77
85
  'name' => container_status[:name]
78
86
  }
@@ -80,10 +88,11 @@ module KubernetesMetadata
80
88
  {
81
89
  'name' => container_status[:name],
82
90
  'image' => container_status[:image],
83
- 'image_id' => container_status[:imageID]
91
+ 'image_id' => container_status[:imageID],
92
+ :containerID => container_id
84
93
  }
85
94
  end
86
- end
95
+ end if pod_object[:status] && pod_object[:status][:containerStatuses]
87
96
  rescue StandardError=>e
88
97
  log.warn("parsing container meta information failed for: #{pod_object[:metadata][:namespace]}/#{pod_object[:metadata][:name]}: #{e}")
89
98
  end
@@ -0,0 +1,145 @@
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
+ ---
20
+ http_interactions:
21
+ - request:
22
+ method: get
23
+ uri: https://localhost:8443/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc
24
+ body:
25
+ encoding: US-ASCII
26
+ string: ''
27
+ headers:
28
+ Accept:
29
+ - "*/*; q=0.5, application/xml"
30
+ Accept-Encoding:
31
+ - gzip, deflate
32
+ User-Agent:
33
+ - Ruby
34
+ response:
35
+ status:
36
+ code: 200
37
+ message: OK
38
+ headers:
39
+ Content-Type:
40
+ - application/json
41
+ Date:
42
+ - Fri, 08 May 2015 10:35:37 GMT
43
+ Transfer-Encoding:
44
+ - chunked
45
+ body:
46
+ encoding: UTF-8
47
+ string: |-
48
+ {
49
+ "kind": "Pod",
50
+ "apiVersion": "v1",
51
+ "metadata": {
52
+ "name": "fabric8-console-controller-98rqc",
53
+ "generateName": "fabric8-console-controller-",
54
+ "namespace": "default",
55
+ "selfLink": "/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc",
56
+ "uid": "c76927af-f563-11e4-b32d-54ee7527188d",
57
+ "resourceVersion": "122",
58
+ "creationTimestamp": "2015-05-08T09:22:42Z",
59
+ "labels": {
60
+ "component": "fabric8Console"
61
+ }
62
+ },
63
+ "spec": {
64
+ "volumes": [
65
+ {
66
+ "name": "openshift-cert-secrets",
67
+ "hostPath": null,
68
+ "emptyDir": null,
69
+ "gcePersistentDisk": null,
70
+ "gitRepo": null,
71
+ "secret": {
72
+ "secretName": "openshift-cert-secrets"
73
+ },
74
+ "nfs": null,
75
+ "iscsi": null,
76
+ "glusterfs": null
77
+ }
78
+ ],
79
+ "containers": [
80
+ {
81
+ "name": "fabric8-console-container",
82
+ "image": "fabric8/hawtio-kubernetes:latest",
83
+ "ports": [
84
+ {
85
+ "containerPort": 9090,
86
+ "protocol": "TCP"
87
+ }
88
+ ],
89
+ "env": [
90
+ {
91
+ "name": "OAUTH_CLIENT_ID",
92
+ "value": "fabric8-console"
93
+ },
94
+ {
95
+ "name": "OAUTH_AUTHORIZE_URI",
96
+ "value": "https://localhost:8443/oauth/authorize"
97
+ }
98
+ ],
99
+ "resources": {},
100
+ "volumeMounts": [
101
+ {
102
+ "name": "openshift-cert-secrets",
103
+ "readOnly": true,
104
+ "mountPath": "/etc/secret-volume"
105
+ }
106
+ ],
107
+ "terminationMessagePath": "/dev/termination-log",
108
+ "imagePullPolicy": "IfNotPresent",
109
+ "capabilities": {}
110
+ }
111
+ ],
112
+ "restartPolicy": "Always",
113
+ "dnsPolicy": "ClusterFirst",
114
+ "nodeName": "jimmi-redhat.localnet"
115
+ },
116
+ "status": {
117
+ "phase": "Running",
118
+ "Condition": [
119
+ {
120
+ "type": "Ready",
121
+ "status": "True"
122
+ }
123
+ ],
124
+ "hostIP": "172.17.42.1",
125
+ "podIP": "172.17.0.8",
126
+ "containerStatuses": [
127
+ {
128
+ "name": "fabric8-console-container",
129
+ "state": {
130
+ "waiting": {
131
+ "reason": "ContainerCreating"
132
+ }
133
+ },
134
+ "lastState": {},
135
+ "ready": true,
136
+ "restartCount": 0,
137
+ "image": "fabric8/hawtio-kubernetes:latest",
138
+ "imageID": ""
139
+ }
140
+ ]
141
+ }
142
+ }
143
+ http_version:
144
+ recorded_at: Fri, 08 May 2015 10:35:37 GMT
145
+ recorded_with: VCR 2.9.3
@@ -44,7 +44,7 @@ class TestCacheStrategy
44
44
 
45
45
  def log
46
46
  logger = {}
47
- def logger.trace?
47
+ def logger.on_trace
48
48
  true
49
49
  end
50
50
 
@@ -28,7 +28,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
28
28
  @time = Fluent::Engine.now
29
29
  end
30
30
 
31
- DEFAULT_TAG = 'var.log.containers.fabric8-console-controller-98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log'
31
+ VAR_LOG_CONTAINER_TAG = 'var.log.containers.fabric8-console-controller-98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log'
32
+ VAR_LOG_POD_TAG = 'var.log.pods.default_fabric8-console-controller-98rqc_c76927af-f563-11e4-b32d-54ee7527188d.fabric8-console-container.0.log'
32
33
 
33
34
  def create_driver(conf = '')
34
35
  Test::Driver::Filter.new(Plugin::KubernetesMetadataFilter).configure(conf)
@@ -45,7 +46,6 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
45
46
  assert_equal('KubernetesMetadata::TestApiAdapter', d.instance.test_api_adapter)
46
47
  end
47
48
 
48
-
49
49
  test 'kubernetes url' do
50
50
  VCR.use_cassette('valid_kubernetes_api_server') do
51
51
  d = create_driver('
@@ -138,7 +138,7 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
138
138
  cache_size 1
139
139
  ', d: nil)
140
140
  d = create_driver(config) if d.nil?
141
- d.run(default_tag: DEFAULT_TAG) do
141
+ d.run(default_tag: VAR_LOG_CONTAINER_TAG) do
142
142
  d.feed(@time, msg)
143
143
  end
144
144
  d.filtered.map(&:last)
@@ -165,6 +165,76 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
165
165
  plugin.filter_stream('tag', Fluent::MultiEventStream.new)
166
166
  end
167
167
 
168
+ sub_test_case 'parsing_pod_metadata when container_status is missing from the pod status' do
169
+ test 'using the tag_to_kubernetes_name_regexp for /var/log/containers ' do
170
+ VCR.use_cassettes(
171
+ [
172
+ { name: 'valid_kubernetes_api_server' },
173
+ { name: 'kubernetes_get_api_v1' },
174
+ { name: 'kubernetes_get_namespace_default' },
175
+ { name: 'kubernetes_get_pod_container_init' }
176
+ ]) do
177
+ filtered = emit({}, "
178
+ kubernetes_url https://localhost:8443
179
+ watch false
180
+ cache_size 1
181
+ ")
182
+ expected_kube_metadata = {
183
+ 'docker' => {
184
+ 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
185
+ },
186
+ 'kubernetes' => {
187
+ 'container_image'=>'fabric8/hawtio-kubernetes:latest',
188
+ 'container_name'=>'fabric8-console-container',
189
+ 'host' => 'jimmi-redhat.localnet',
190
+ 'pod_name' => 'fabric8-console-controller-98rqc',
191
+ 'namespace_id' => '898268c8-4a36-11e5-9d81-42010af0194c',
192
+ 'namespace_name' => 'default',
193
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
194
+ 'pod_ip' => '172.17.0.8',
195
+ 'master_url' => 'https://localhost:8443',
196
+ 'labels' => {
197
+ 'component' => 'fabric8Console'
198
+ }
199
+ }
200
+ }
201
+ assert_equal(expected_kube_metadata, filtered[0])
202
+ end
203
+ end
204
+ test 'using the tag_to_kubernetes_name_regexp for /var/log/pods' do
205
+ VCR.use_cassettes(
206
+ [
207
+ { name: 'valid_kubernetes_api_server' },
208
+ { name: 'kubernetes_get_api_v1' },
209
+ { name: 'kubernetes_get_namespace_default' },
210
+ { name: 'kubernetes_get_pod_container_init' }
211
+ ]) do
212
+ filtered = emit_with_tag(VAR_LOG_POD_TAG,{}, "
213
+ kubernetes_url https://localhost:8443
214
+ watch false
215
+ cache_size 1
216
+ ")
217
+ expected_kube_metadata = {
218
+ 'kubernetes' => {
219
+ 'container_image'=>'fabric8/hawtio-kubernetes:latest',
220
+ 'container_name'=>'fabric8-console-container',
221
+ 'host' => 'jimmi-redhat.localnet',
222
+ 'pod_name' => 'fabric8-console-controller-98rqc',
223
+ 'namespace_id' => '898268c8-4a36-11e5-9d81-42010af0194c',
224
+ 'namespace_name' => 'default',
225
+ 'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
226
+ 'pod_ip' => '172.17.0.8',
227
+ 'master_url' => 'https://localhost:8443',
228
+ 'labels' => {
229
+ 'component' => 'fabric8Console'
230
+ }
231
+ }
232
+ }
233
+ assert_equal(expected_kube_metadata, filtered[0])
234
+ end
235
+ end
236
+ end
237
+
168
238
  test 'inability to connect to the api server handles exception and doensnt block pipeline' do
169
239
  VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' }]) do
170
240
  driver = create_driver('
@@ -177,8 +247,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
177
247
  filtered = emit({ 'time' => '2015-05-08T09:22:01Z' }, '', d: driver)
178
248
  expected_kube_metadata = {
179
249
  'time' => '2015-05-08T09:22:01Z',
180
- 'docker' => {
181
- 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
250
+ 'docker'=>{
251
+ 'container_id'=>'49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
182
252
  },
183
253
  'kubernetes' => {
184
254
  'pod_name' => 'fabric8-console-controller-98rqc',
@@ -265,6 +335,7 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
265
335
  end
266
336
 
267
337
  test 'with docker & kubernetes metadata' do
338
+
268
339
  VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' }, { name: 'kubernetes_get_pod' }, { name: 'kubernetes_get_namespace_default' }]) do
269
340
  filtered = emit({ 'time' => '2015-05-08T09:22:01Z' })
270
341
  expected_kube_metadata = {
@@ -361,8 +432,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
361
432
  test 'with docker & kubernetes metadata but no configured api server' do
362
433
  filtered = emit({}, '')
363
434
  expected_kube_metadata = {
364
- 'docker' => {
365
- 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
435
+ 'docker'=>{
436
+ 'container_id'=>'49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
366
437
  },
367
438
  'kubernetes' => {
368
439
  'pod_name' => 'fabric8-console-controller-98rqc',
@@ -383,8 +454,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
383
454
  stub_request(:any, 'https://localhost:8443/api/v1/namespaces/default').to_timeout
384
455
  filtered = emit
385
456
  expected_kube_metadata = {
386
- 'docker' => {
387
- 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
457
+ 'docker'=>{
458
+ 'container_id'=>'49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
388
459
  },
389
460
  'kubernetes' => {
390
461
  'pod_name' => 'fabric8-console-controller-98rqc',
@@ -406,8 +477,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
406
477
  stub_request(:any, 'https://localhost:8443/api/v1/namespaces/default/pods/fabric8-console-controller.98rqc').to_timeout
407
478
  filtered = emit_with_tag('var.log.containers.fabric8-console-controller.98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log', {}, '')
408
479
  expected_kube_metadata = {
409
- 'docker' => {
410
- 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
480
+ 'docker'=>{
481
+ 'container_id'=>'49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
411
482
  },
412
483
  'kubernetes' => {
413
484
  'pod_name' => 'fabric8-console-controller.98rqc',
@@ -432,13 +503,15 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
432
503
  assert_equal(msg, filtered[0])
433
504
  end
434
505
 
435
- test 'with kubernetes dotted labels, de_dot enabled' do
506
+ test 'with kubernetes dotted and slashed labels, de_dot and de_slash enabled' do
436
507
  VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' },
437
- { name: 'kubernetes_docker_metadata_dotted_labels' }]) do
508
+ { name: 'kubernetes_docker_metadata_dotted_slashed_labels' }]) do
438
509
  filtered = emit({}, '
439
510
  kubernetes_url https://localhost:8443
440
511
  watch false
441
512
  cache_size 1
513
+ de_dot true
514
+ de_slash true
442
515
  ')
443
516
  expected_kube_metadata = {
444
517
  'docker' => {
@@ -452,14 +525,14 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
452
525
  'container_image_id' => 'docker://b2bd1a24a68356b2f30128e6e28e672c1ef92df0d9ec01ec0c7faea5d77d2303',
453
526
  'namespace_id' => '898268c8-4a36-11e5-9d81-42010af0194c',
454
527
  'namespace_labels' => {
455
- 'kubernetes_io/namespacetest' => 'somevalue'
528
+ 'kubernetes_io__namespacetest' => 'somevalue'
456
529
  },
457
530
  'namespace_name' => 'default',
458
531
  'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
459
532
  'pod_ip' => '172.17.0.8',
460
533
  'master_url' => 'https://localhost:8443',
461
534
  'labels' => {
462
- 'kubernetes_io/test' => 'somevalue'
535
+ 'kubernetes_io__test' => 'somevalue'
463
536
  }
464
537
  }
465
538
  }
@@ -467,14 +540,15 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
467
540
  end
468
541
  end
469
542
 
470
- test 'with kubernetes dotted labels, de_dot disabled' do
543
+ test 'with kubernetes dotted and slashed labels, de_dot and de_slash disabled' do
471
544
  VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' },
472
- { name: 'kubernetes_docker_metadata_dotted_labels' }]) do
545
+ { name: 'kubernetes_docker_metadata_dotted_slashed_labels' }]) do
473
546
  filtered = emit({}, '
474
547
  kubernetes_url https://localhost:8443
475
548
  watch false
476
549
  cache_size 1
477
550
  de_dot false
551
+ de_slash false
478
552
  ')
479
553
  expected_kube_metadata = {
480
554
  'docker' => {
@@ -506,11 +580,21 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
506
580
  test 'invalid de_dot_separator config' do
507
581
  assert_raise Fluent::ConfigError do
508
582
  create_driver('
583
+ de_dot true
509
584
  de_dot_separator contains.
510
585
  ')
511
586
  end
512
587
  end
513
588
 
589
+ test 'invalid de_slash_separator config' do
590
+ assert_raise Fluent::ConfigError do
591
+ create_driver('
592
+ de_slash true
593
+ de_slash_separator contains/
594
+ ')
595
+ end
596
+ end
597
+
514
598
  test 'with records from journald and docker & kubernetes metadata' do
515
599
  # with use_journal true should ignore tags and use CONTAINER_NAME and CONTAINER_ID_FULL
516
600
  tag = 'var.log.containers.junk1_junk2_junk3-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed450.log'
@@ -686,7 +770,6 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
686
770
 
687
771
  test 'uses metadata from tag if use_journal false and lookup_from_k8s_field false' do
688
772
  # with use_journal unset, should still use the journal fields instead of tag fields
689
- tag = 'var.log.containers.fabric8-console-controller-98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log'
690
773
  msg = {
691
774
  'CONTAINER_NAME' => 'k8s_journald-container-name.db89db89_journald-pod-name_journald-namespace-name_c76927af-f563-11e4-b32d-54ee7527188d_89db89db',
692
775
  'CONTAINER_ID_FULL' => '838350c64bacba968d39a30a50789b2795291fceca6ccbff55298671d46b0e3b',
@@ -701,13 +784,13 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
701
784
  VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' }, { name: 'kubernetes_get_pod' },
702
785
  { name: 'kubernetes_get_namespace_default', options: { allow_playback_repeats: true } },
703
786
  { name: 'metadata_from_tag_and_journald_fields' }]) do
704
- es = emit_with_tag(tag, msg, '
787
+ es = emit_with_tag(VAR_LOG_CONTAINER_TAG, msg, "
705
788
  kubernetes_url https://localhost:8443
706
789
  watch false
707
790
  cache_size 1
708
791
  lookup_from_k8s_field false
709
792
  use_journal false
710
- ')
793
+ ")
711
794
  expected_kube_metadata = {
712
795
  'docker' => {
713
796
  'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
@@ -941,7 +1024,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
941
1024
  end
942
1025
 
943
1026
  test 'processes all events when reading from MessagePackEventStream' do
944
- VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' },
1027
+ VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' },
1028
+ { name: 'kubernetes_get_api_v1' },
945
1029
  { name: 'kubernetes_get_pod' },
946
1030
  { name: 'kubernetes_get_namespace_default' }]) do
947
1031
  entries = [[@time, { 'time' => '2015-05-08T09:22:01Z' }], [@time, { 'time' => '2015-05-08T09:22:01Z' }]]
@@ -954,7 +1038,7 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
954
1038
  cache_size 1
955
1039
  ')
956
1040
  d.run do
957
- d.feed(DEFAULT_TAG, msgpack_stream)
1041
+ d.feed(VAR_LOG_CONTAINER_TAG, msgpack_stream)
958
1042
  end
959
1043
  filtered = d.filtered.map(&:last)
960
1044
 
@@ -998,8 +1082,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
998
1082
  skip_namespace_metadata true
999
1083
  ')
1000
1084
  expected_kube_metadata = {
1001
- 'docker' => {
1002
- 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
1085
+ 'docker'=>{
1086
+ 'container_id'=>'49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
1003
1087
  },
1004
1088
  'kubernetes' => {
1005
1089
  'host' => 'jimmi-redhat.localnet',
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: 2.8.1
4
+ version: 2.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jimmi Dyson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-09-17 00:00:00.000000000 Z
11
+ date: 2021-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -230,12 +230,13 @@ files:
230
230
  - lib/fluent/plugin/kubernetes_metadata_watch_pods.rb
231
231
  - test/cassettes/invalid_api_server_config.yml
232
232
  - test/cassettes/kubernetes_docker_metadata_annotations.yml
233
- - test/cassettes/kubernetes_docker_metadata_dotted_labels.yml
233
+ - test/cassettes/kubernetes_docker_metadata_dotted_slashed_labels.yml
234
234
  - test/cassettes/kubernetes_get_api_v1.yml
235
235
  - test/cassettes/kubernetes_get_api_v1_using_token.yml
236
236
  - test/cassettes/kubernetes_get_namespace_default.yml
237
237
  - test/cassettes/kubernetes_get_namespace_default_using_token.yml
238
238
  - test/cassettes/kubernetes_get_pod.yml
239
+ - test/cassettes/kubernetes_get_pod_container_init.yml
239
240
  - test/cassettes/kubernetes_get_pod_using_token.yml
240
241
  - test/cassettes/metadata_from_tag_and_journald_fields.yml
241
242
  - test/cassettes/metadata_from_tag_journald_and_kubernetes_fields.yml