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 +4 -4
- data/Gemfile.lock +28 -28
- data/README.md +6 -38
- data/fluent-plugin-kubernetes_metadata_filter.gemspec +1 -1
- data/lib/fluent/plugin/filter_kubernetes_metadata.rb +37 -25
- data/lib/fluent/plugin/kubernetes_metadata_cache_strategy.rb +1 -3
- data/lib/fluent/plugin/kubernetes_metadata_common.rb +6 -5
- data/release_notes.md +42 -0
- data/test/cassettes/kubernetes_get_pod_container_init.yml +145 -0
- data/test/plugin/test_cache_strategy.rb +1 -1
- data/test/plugin/test_filter_kubernetes_metadata.rb +89 -18
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98c4002df3754262c547e0b22acf366e62bca72f0142a20430f6a0f6c91dadea
|
4
|
+
data.tar.gz: 3f9e5d2d19b505c7cad15d113b69dea7ccb0943a3d4605d121fdf2234952c4a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
71
|
+
mime-types (3.4.1)
|
72
72
|
mime-types-data (~> 3.2015)
|
73
|
-
mime-types-data (3.2021.
|
74
|
-
mini_mime (1.
|
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.
|
80
|
-
parser (3.0.
|
79
|
+
parallel (1.21.0)
|
80
|
+
parser (3.0.2.0)
|
81
81
|
ast (~> 2.4.1)
|
82
|
-
power_assert (
|
82
|
+
power_assert (2.0.1)
|
83
83
|
public_suffix (4.0.6)
|
84
84
|
rainbow (3.0.0)
|
85
|
-
rake (13.0.
|
85
|
+
rake (13.0.6)
|
86
86
|
recursive-open-struct (1.1.3)
|
87
|
-
regexp_parser (2.
|
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 (
|
95
|
-
rubocop (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.
|
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.
|
105
|
-
parser (>=
|
104
|
+
rubocop-ast (1.12.0)
|
105
|
+
parser (>= 3.0.1.1)
|
106
106
|
ruby-progressbar (1.11.0)
|
107
|
-
rugged (1.
|
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.
|
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.
|
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.
|
130
|
+
unicode-display_width (2.1.0)
|
131
131
|
vcr (6.0.0)
|
132
|
-
webmock (3.
|
133
|
-
addressable (>= 2.
|
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.
|
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
|
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
|
-
*
|
49
|
-
*
|
50
|
-
*
|
51
|
-
*
|
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
|
-
|
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.
|
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
|
-
|
55
|
-
|
56
|
-
|
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}")
|
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}")
|
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}")
|
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}")
|
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}")
|
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}")
|
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,
|
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' =>
|
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(
|
314
|
-
|
315
|
-
|
316
|
-
metadata['kubernetes']['
|
317
|
-
metadata['
|
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
|
-
|
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
|
-
|
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} ")
|
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
|
-
|
82
|
-
|
83
|
-
container_meta[
|
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
|
@@ -28,7 +28,8 @@ class KubernetesMetadataFilterTest < Test::Unit::TestCase
|
|
28
28
|
@time = Fluent::Engine.now
|
29
29
|
end
|
30
30
|
|
31
|
-
|
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:
|
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'
|
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'
|
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'
|
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'
|
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(
|
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' },
|
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(
|
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'
|
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.
|
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:
|
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
|