fluent-plugin-kubernetes_metadata_filter 2.8.1 → 2.9.3

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: 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