fluent-plugin-kubernetes_metadata_filter 2.9.0 → 2.9.4

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: 1637f0d5dc3b0962bea8bb25f8cda869044b45fd33d27fee1ef7a58d2c403f4c
4
- data.tar.gz: 0bf235def6a0eab1ff766617b704bd3b637403ad88d568c8d087352473a24dc0
3
+ metadata.gz: 98c4002df3754262c547e0b22acf366e62bca72f0142a20430f6a0f6c91dadea
4
+ data.tar.gz: 3f9e5d2d19b505c7cad15d113b69dea7ccb0943a3d4605d121fdf2234952c4a7
5
5
  SHA512:
6
- metadata.gz: 5f31264c9339108f83573e9566ec2f93630afa7c64d4f00a996431925e487a5c74575603183072c10803defac132ef066ef0ec021ad37446e358cef4cad0a05e
7
- data.tar.gz: ca81025a46a85d4e87feededf0f9ef2c8047cd3a8b84b75a71baf16feabc364ca69ce4ed69f3f796dbd1542bc602799dac53f87bbb9e7df980a99e4872c7955f
6
+ metadata.gz: 5474457d9a35d7951a8a380c0099deeb16af6d849a9f036c467ba47e0fcc47ce2ff7f77bbd75ad7d6487c9f172897e63406a91fd9f08dc6494eb32332e2b9373
7
+ data.tar.gz: 91a14c8edabcdd1eaa7b915c14bfd643b7829ae0cc8951ed8f9e77819483638207a5c6264094974971dcf4d7684c50c62a249cee4de36d23574b72cbe4e10589
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-kubernetes_metadata_filter (2.9.0)
4
+ fluent-plugin-kubernetes_metadata_filter (2.9.4)
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)
@@ -155,4 +155,4 @@ DEPENDENCIES
155
155
  yajl-ruby
156
156
 
157
157
  BUNDLED WITH
158
- 2.2.19
158
+ 2.3.4
data/README.md CHANGED
@@ -41,14 +41,14 @@ Configuration options for fluent.conf are:
41
41
  * `client_key` - path to a client key file to authenticate to the API server
42
42
  * `bearer_token_file` - path to a file containing the bearer token to use for authentication
43
43
  * `tag_to_kubernetes_name_regexp` - the regular expression used to extract kubernetes metadata (pod name, container name, namespace) from the current fluentd tag.
44
- This must used named capture groups for `container_name`, `pod_name` & `namespace` default: See [code](https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter/blob/master/lib/fluent/plugin/filter_kubernetes_metadata.rb#L52)
44
+ This must use named capture groups for `container_name`, `pod_name`, `namespace`, and either `pod_uuid (/var/log/pods)` or `docker_id (/var/log/containers)`
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 Datadog and ElasticSearch 2.x compatibility (default: `true`)
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: `__`)
48
+ * *DEPRECATED*`de_dot` - replace dots in labels and annotations with configured `de_dot_separator`, required for Datadog and ElasticSearch 2.x compatibility (default: `true`)
49
+ * *DEPRECATED*`de_dot_separator` - separator to use if `de_dot` is enabled (default: `_`)
50
+ * *DEPRECATED*`de_slash` - replace slashes in labels and annotations with configured `de_slash_separator`, required for Datadog compatibility (default: `false`)
51
+ * *DEPRECATED*`de_slash_separator` - separator to use if `de_slash` is enabled (default: `__`)
52
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
53
53
  if available, otherwise, will use the tag in the `tag_to_kubernetes_name_regexp` format.
54
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)
@@ -68,23 +68,6 @@ when true (default: `true`)
68
68
  * `skip_namespace_metadata` - Skip the namespace_id field from the metadata. The fetch_namespace_metadata function will be skipped. The plugin will be faster and cpu consumption will be less.
69
69
  * `watch_retry_interval` - The time interval in seconds for retry backoffs when watch connections fail. (default: `10`)
70
70
 
71
- **NOTE:** As of the release 2.1.x of this plugin, it no longer supports parsing the source message into JSON and attaching it to the
72
- payload. The following configuration options are removed:
73
-
74
- * `merge_json_log`
75
- * `preserve_json_log`
76
-
77
- One way of preserving JSON logs can be through the [parser plugin](https://docs.fluentd.org/filter/parser)
78
-
79
- **NOTE** As of this release, the use of `use_journal` is **DEPRECATED**. If this setting is not present, the plugin will
80
- attempt to figure out the source of the metadata fields from the following:
81
- - If `lookup_from_k8s_field true` (the default) and the following fields are present in the record:
82
- `docker.container_id`, `kubernetes.namespace_name`, `kubernetes.pod_name`, `kubernetes.container_name`,
83
- then the plugin will use those values as the source to use to lookup the metadata
84
- - If `use_journal true`, or `use_journal` is unset, and the fields `CONTAINER_NAME` and `CONTAINER_ID_FULL` are present in the record,
85
- then the plugin will parse those values using `container_name_to_kubernetes_regexp` and use those as the source to lookup the metadata
86
- - Otherwise, if the tag matches `tag_to_kubernetes_name_regexp`, the plugin will parse the tag and use those values to
87
- lookup the metdata
88
71
 
89
72
  Reading from the JSON formatted log files with `in_tail` and wildcard filenames while respecting the CRI-o log format with the same config you need the fluent-plugin "multi-format-parser":
90
73
 
@@ -154,22 +137,7 @@ Reading from the systemd journal (requires the fluentd `fluent-plugin-systemd` a
154
137
  @type stdout
155
138
  </match>
156
139
  ```
157
- ## Log content as JSON
158
- In former versions this plugin parsed the value of the key log as JSON. In the current version this feature was removed, to avoid duplicate features in the fluentd plugin ecosystem. It can parsed with the parser plugin like this:
159
- ```
160
- <filter kubernetes.**>
161
- @type parser
162
- key_name log
163
- <parse>
164
- @type json
165
- json_parser json
166
- </parse>
167
- replace_invalid_sequence true
168
- reserve_data true # this preserves unparsable log lines
169
- emit_invalid_record_to_error false # In case of unparsable log lines keep the error log clean
170
- reserve_time # the time was already parsed in the source, we don't want to overwrite it with current time.
171
- </filter>
172
- ```
140
+
173
141
 
174
142
  ## Environment variables for Kubernetes
175
143
 
@@ -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.9.0'
8
+ gem.version = '2.9.4'
9
9
  gem.authors = ['Jimmi Dyson']
10
10
  gem.email = ['jimmidyson@gmail.com']
11
11
  gem.description = 'Filter plugin to add Kubernetes metadata'
@@ -51,9 +51,17 @@ 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 = '(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 = '(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
@@ -100,15 +108,15 @@ module Fluent::Plugin
100
108
  config_param :watch_retry_max_times, :integer, default: 10
101
109
 
102
110
  def fetch_pod_metadata(namespace_name, pod_name)
103
- log.trace("fetching pod metadata: #{namespace_name}/#{pod_name}") if log.trace?
111
+ log.trace("fetching pod metadata: #{namespace_name}/#{pod_name}")
104
112
  options = {
105
113
  resource_version: '0' # Fetch from API server cache instead of etcd quorum read
106
114
  }
107
115
  pod_object = @client.get_pod(pod_name, namespace_name, options)
108
- 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}")
109
117
  metadata = parse_pod_metadata(pod_object)
110
118
  @stats.bump(:pod_cache_api_updates)
111
- log.trace("parsed metadata for #{namespace_name}/#{pod_name}: #{metadata}") if log.trace?
119
+ log.trace("parsed metadata for #{namespace_name}/#{pod_name}: #{metadata}")
112
120
  @cache[metadata['pod_id']] = metadata
113
121
  rescue StandardError => e
114
122
  @stats.bump(:pod_cache_api_nil_error)
@@ -132,15 +140,15 @@ module Fluent::Plugin
132
140
  end
133
141
 
134
142
  def fetch_namespace_metadata(namespace_name)
135
- log.trace("fetching namespace metadata: #{namespace_name}") if log.trace?
143
+ log.trace("fetching namespace metadata: #{namespace_name}")
136
144
  options = {
137
145
  resource_version: '0' # Fetch from API server cache instead of etcd quorum read
138
146
  }
139
147
  namespace_object = @client.get_namespace(namespace_name, nil, options)
140
- log.trace("raw metadata for #{namespace_name}: #{namespace_object}") if log.trace?
148
+ log.trace("raw metadata for #{namespace_name}: #{namespace_object}")
141
149
  metadata = parse_namespace_metadata(namespace_object)
142
150
  @stats.bump(:namespace_cache_api_updates)
143
- log.trace("parsed metadata for #{namespace_name}: #{metadata}") if log.trace?
151
+ log.trace("parsed metadata for #{namespace_name}: #{metadata}")
144
152
  @namespace_cache[metadata['namespace_id']] = metadata
145
153
  rescue StandardError => e
146
154
  @stats.bump(:namespace_cache_api_nil_error)
@@ -156,10 +164,6 @@ module Fluent::Plugin
156
164
  def configure(conf)
157
165
  super
158
166
 
159
- def log.trace?
160
- level == Fluent::Log::LEVEL_TRACE
161
- end
162
-
163
167
  require 'kubeclient'
164
168
  require 'lru_redux'
165
169
  @stats = KubernetesMetadata::Stats.new
@@ -187,6 +191,7 @@ module Fluent::Plugin
187
191
  @namespace_cache = LruRedux::TTL::ThreadSafeCache.new(@cache_size, @cache_ttl)
188
192
 
189
193
  @tag_to_kubernetes_name_regexp_compiled = Regexp.compile(@tag_to_kubernetes_name_regexp)
194
+
190
195
  @container_name_to_kubernetes_regexp_compiled = Regexp.compile(@container_name_to_kubernetes_regexp)
191
196
 
192
197
  # Use Kubernetes default service account if we're in a pod.
@@ -300,40 +305,48 @@ module Fluent::Plugin
300
305
  end
301
306
  end
302
307
 
303
- def get_metadata_for_record(namespace_name, pod_name, container_name, container_id, create_time, batch_miss_cache)
308
+ def get_metadata_for_record(namespace_name, pod_name, container_name, cache_key, create_time, batch_miss_cache, docker_id)
304
309
  metadata = {
305
- 'docker' => { 'container_id' => container_id },
310
+ 'docker' => { 'container_id' => "" },
306
311
  'kubernetes' => {
307
312
  'container_name' => container_name,
308
313
  'namespace_name' => namespace_name,
309
314
  'pod_name' => pod_name
310
315
  }
311
316
  }
317
+ metadata['docker']['container_id'] = docker_id unless docker_id.nil?
318
+ container_cache_key = container_name
312
319
  if present?(@kubernetes_url)
313
- pod_metadata = get_pod_metadata(container_id, namespace_name, pod_name, create_time, batch_miss_cache)
314
-
315
- if (pod_metadata.include? 'containers') && (pod_metadata['containers'].include? container_id) && !@skip_container_metadata
316
- metadata['kubernetes']['container_image'] = pod_metadata['containers'][container_id]['image']
317
- 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?
318
325
  end
319
326
 
320
327
  metadata['kubernetes'].merge!(pod_metadata) if pod_metadata
321
328
  metadata['kubernetes'].delete('containers')
322
329
  end
330
+ metadata.delete('docker') if metadata['docker'] && (metadata['docker']['container_id'].nil? || metadata['docker']['container_id'].empty?)
323
331
  metadata
324
332
  end
325
333
 
326
334
  def filter_stream(tag, es)
327
335
  return es if (es.respond_to?(:empty?) && es.empty?) || !es.is_a?(Fluent::EventStream)
328
-
329
336
  new_es = Fluent::MultiEventStream.new
330
337
  tag_match_data = tag.match(@tag_to_kubernetes_name_regexp_compiled) unless @use_journal
331
338
  tag_metadata = nil
332
339
  batch_miss_cache = {}
333
340
  es.each do |time, record|
334
341
  if tag_match_data && tag_metadata.nil?
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
+ docker_id = tag_match_data.names.include?('docker_id') ? tag_match_data['docker_id'] : nil
335
348
  tag_metadata = get_metadata_for_record(tag_match_data['namespace'], tag_match_data['pod_name'], tag_match_data['container_name'],
336
- tag_match_data['docker_id'], create_time_from_record(record, time), batch_miss_cache)
349
+ cache_key, create_time_from_record(record, time), batch_miss_cache, docker_id)
337
350
  end
338
351
  metadata = Marshal.load(Marshal.dump(tag_metadata)) if tag_metadata
339
352
  if (@use_journal || @use_journal.nil?) &&
@@ -348,10 +361,9 @@ module Fluent::Plugin
348
361
  record['docker'].key?('container_id') &&
349
362
  (k_metadata = get_metadata_for_record(record['kubernetes']['namespace_name'], record['kubernetes']['pod_name'],
350
363
  record['kubernetes']['container_name'], record['docker']['container_id'],
351
- create_time_from_record(record, time), batch_miss_cache))
364
+ create_time_from_record(record, time), batch_miss_cache, record['docker']['container_id']))
352
365
  metadata = k_metadata
353
366
  end
354
-
355
367
  record = record.merge(metadata) if metadata
356
368
  new_es.add(time, record)
357
369
  end
@@ -364,7 +376,7 @@ module Fluent::Plugin
364
376
  if record.key?('CONTAINER_NAME') && record.key?('CONTAINER_ID_FULL')
365
377
  metadata = record['CONTAINER_NAME'].match(@container_name_to_kubernetes_regexp_compiled) do |match_data|
366
378
  get_metadata_for_record(match_data['namespace'], match_data['pod_name'], match_data['container_name'],
367
- record['CONTAINER_ID_FULL'], create_time_from_record(record, time), batch_miss_cache)
379
+ record['CONTAINER_ID_FULL'], create_time_from_record(record, time), batch_miss_cache, record['CONTAINER_ID_FULL'])
368
380
  end
369
381
  unless metadata
370
382
  log.debug "Error: could not match CONTAINER_NAME from record #{record}"
@@ -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,
@@ -78,9 +78,9 @@ module KubernetesMetadata
78
78
  container_meta = {}
79
79
  begin
80
80
  pod_object[:status][:containerStatuses].each do |container_status|
81
- # get plain container id (eg. docker://hash -> hash)
82
- container_id = container_status[:containerID].sub(%r{^[-_a-zA-Z0-9]+://}, '')
83
- 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
84
84
  {
85
85
  'name' => container_status[:name]
86
86
  }
@@ -88,10 +88,11 @@ module KubernetesMetadata
88
88
  {
89
89
  'name' => container_status[:name],
90
90
  'image' => container_status[:image],
91
- 'image_id' => container_status[:imageID]
91
+ 'image_id' => container_status[:imageID],
92
+ :containerID => container_id
92
93
  }
93
94
  end
94
- end
95
+ end if pod_object[:status] && pod_object[:status][:containerStatuses]
95
96
  rescue StandardError=>e
96
97
  log.warn("parsing container meta information failed for: #{pod_object[:metadata][:namespace]}/#{pod_object[:metadata][:name]}: #{e}")
97
98
  end
data/release_notes.md ADDED
@@ -0,0 +1,42 @@
1
+ # Release Notes
2
+
3
+ ## 2.9.4
4
+ As of this release, the 'de_dot' functionality is depricated and will be removed in future releases.
5
+ Ref: https://github.com/fabric8io/fluent-plugin-kubernetes_metadata_filter/issues/320
6
+
7
+ ## v2.1.4
8
+ The use of `use_journal` is **DEPRECATED**. If this setting is not present, the plugin will
9
+ attempt to figure out the source of the metadata fields from the following:
10
+ - If `lookup_from_k8s_field true` (the default) and the following fields are present in the record:
11
+ `docker.container_id`, `kubernetes.namespace_name`, `kubernetes.pod_name`, `kubernetes.container_name`,
12
+ then the plugin will use those values as the source to use to lookup the metadata
13
+ - If `use_journal true`, or `use_journal` is unset, and the fields `CONTAINER_NAME` and `CONTAINER_ID_FULL` are present in the record,
14
+ then the plugin will parse those values using `container_name_to_kubernetes_regexp` and use those as the source to lookup the metadata
15
+ - Otherwise, if the tag matches `tag_to_kubernetes_name_regexp`, the plugin will parse the tag and use those values to
16
+ lookup the metdata
17
+
18
+ ## v2.1.x
19
+
20
+ As of the release 2.1.x of this plugin, it no longer supports parsing the source message into JSON and attaching it to the
21
+ payload. The following configuration options are removed:
22
+
23
+ * `merge_json_log`
24
+ * `preserve_json_log`
25
+
26
+ One way of preserving JSON logs can be through the [parser plugin](https://docs.fluentd.org/filter/parser).
27
+ It can parsed with the parser plugin like this:
28
+
29
+ ```
30
+ <filter kubernetes.**>
31
+ @type parser
32
+ key_name log
33
+ <parse>
34
+ @type json
35
+ json_parser json
36
+ </parse>
37
+ replace_invalid_sequence true
38
+ reserve_data true # this preserves unparsable log lines
39
+ emit_invalid_record_to_error false # In case of unparsable log lines keep the error log clean
40
+ reserve_time # the time was already parsed in the source, we don't want to overwrite it with current time.
41
+ </filter>
42
+ ```
@@ -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',
@@ -699,7 +770,6 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
699
770
 
700
771
  test 'uses metadata from tag if use_journal false and lookup_from_k8s_field false' do
701
772
  # with use_journal unset, should still use the journal fields instead of tag fields
702
- tag = 'var.log.containers.fabric8-console-controller-98rqc_default_fabric8-console-container-49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459.log'
703
773
  msg = {
704
774
  'CONTAINER_NAME' => 'k8s_journald-container-name.db89db89_journald-pod-name_journald-namespace-name_c76927af-f563-11e4-b32d-54ee7527188d_89db89db',
705
775
  'CONTAINER_ID_FULL' => '838350c64bacba968d39a30a50789b2795291fceca6ccbff55298671d46b0e3b',
@@ -714,13 +784,13 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
714
784
  VCR.use_cassettes([{ name: 'valid_kubernetes_api_server' }, { name: 'kubernetes_get_api_v1' }, { name: 'kubernetes_get_pod' },
715
785
  { name: 'kubernetes_get_namespace_default', options: { allow_playback_repeats: true } },
716
786
  { name: 'metadata_from_tag_and_journald_fields' }]) do
717
- es = emit_with_tag(tag, msg, '
787
+ es = emit_with_tag(VAR_LOG_CONTAINER_TAG, msg, "
718
788
  kubernetes_url https://localhost:8443
719
789
  watch false
720
790
  cache_size 1
721
791
  lookup_from_k8s_field false
722
792
  use_journal false
723
- ')
793
+ ")
724
794
  expected_kube_metadata = {
725
795
  'docker' => {
726
796
  'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
@@ -954,7 +1024,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
954
1024
  end
955
1025
 
956
1026
  test 'processes all events when reading from MessagePackEventStream' do
957
- 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' },
958
1029
  { name: 'kubernetes_get_pod' },
959
1030
  { name: 'kubernetes_get_namespace_default' }]) do
960
1031
  entries = [[@time, { 'time' => '2015-05-08T09:22:01Z' }], [@time, { 'time' => '2015-05-08T09:22:01Z' }]]
@@ -967,7 +1038,7 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
967
1038
  cache_size 1
968
1039
  ')
969
1040
  d.run do
970
- d.feed(DEFAULT_TAG, msgpack_stream)
1041
+ d.feed(VAR_LOG_CONTAINER_TAG, msgpack_stream)
971
1042
  end
972
1043
  filtered = d.filtered.map(&:last)
973
1044
 
@@ -1011,8 +1082,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
1011
1082
  skip_namespace_metadata true
1012
1083
  ')
1013
1084
  expected_kube_metadata = {
1014
- 'docker' => {
1015
- 'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
1085
+ 'docker'=>{
1086
+ 'container_id'=>'49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
1016
1087
  },
1017
1088
  'kubernetes' => {
1018
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.9.0
4
+ version: 2.9.4
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: 2022-01-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -228,6 +228,7 @@ files:
228
228
  - lib/fluent/plugin/kubernetes_metadata_util.rb
229
229
  - lib/fluent/plugin/kubernetes_metadata_watch_namespaces.rb
230
230
  - lib/fluent/plugin/kubernetes_metadata_watch_pods.rb
231
+ - release_notes.md
231
232
  - test/cassettes/invalid_api_server_config.yml
232
233
  - test/cassettes/kubernetes_docker_metadata_annotations.yml
233
234
  - test/cassettes/kubernetes_docker_metadata_dotted_slashed_labels.yml
@@ -236,6 +237,7 @@ files:
236
237
  - test/cassettes/kubernetes_get_namespace_default.yml
237
238
  - test/cassettes/kubernetes_get_namespace_default_using_token.yml
238
239
  - test/cassettes/kubernetes_get_pod.yml
240
+ - test/cassettes/kubernetes_get_pod_container_init.yml
239
241
  - test/cassettes/kubernetes_get_pod_using_token.yml
240
242
  - test/cassettes/metadata_from_tag_and_journald_fields.yml
241
243
  - test/cassettes/metadata_from_tag_journald_and_kubernetes_fields.yml