fluent-plugin-kubernetes_metadata_filter 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -0
- data/fluent-plugin-kubernetes_metadata_filter.gemspec +1 -1
- data/lib/fluent/plugin/filter_kubernetes_metadata.rb +32 -3
- data/test/cassettes/kubernetes_docker_metadata_annotations.yml +188 -0
- data/test/plugin/test_filter_kubernetes_metadata.rb +31 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 718b00c62d8a5f40dd763c50b34ddc7ab4106a98
|
4
|
+
data.tar.gz: 4368cdeb4409e1416c7dfe12ab75b7c604c9f5a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f30bf120124b195306ab89945ecc415edd773d362b830213dade8968daa2fba48df54941a13db1eba83e778057d46319af0d3e9c329776205633e8c4d4a0a5d
|
7
|
+
data.tar.gz: 589952266c386bf83792e58dd404826357232ac68f798cb700ad5942c6e05f04b4c3848de3e575c6ff0782ab26ce8057060c3f8b7d06ec95328e95938cf93951
|
data/README.md
CHANGED
@@ -29,6 +29,7 @@ This must used named capture groups for `container_name`, `pod_name` & `namespac
|
|
29
29
|
* `de_dot_separator` - separator to use if `de_dot` is enabled (default: `_`)
|
30
30
|
* `use_journal` - If false (default), 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.
|
31
31
|
* `container_name_to_kubernetes_regexp` - The regular expression used to extract the k8s metadata encoded in the journal `CONTAINER_NAME` field (default: `'^k8s_(?<container_name>[^\.]+)\.(?<container_hash>[a-z0-9]{8})_(?<pod_name>[^_]+)_(?<namespace>[^_]+)_(?<pod_id>[^_]+)_(?<pod_randhex>[a-z0-9]{8})$'`)
|
32
|
+
* `annotation_match` - Array of regular expressions matching annotation field names. Matched annotations are added to a log record.
|
32
33
|
|
33
34
|
Reading from the JSON formatted log files with `in_tail` and wildcard filenames:
|
34
35
|
```
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
|
5
5
|
Gem::Specification.new do |gem|
|
6
6
|
gem.name = "fluent-plugin-kubernetes_metadata_filter"
|
7
|
-
gem.version = "0.
|
7
|
+
gem.version = "0.24.0"
|
8
8
|
gem.authors = ["Jimmi Dyson"]
|
9
9
|
gem.email = ["jimmidyson@gmail.com"]
|
10
10
|
gem.description = %q{Filter plugin to add Kubernetes metadata}
|
@@ -54,6 +54,8 @@ module Fluent
|
|
54
54
|
:string,
|
55
55
|
:default => '^k8s_(?<container_name>[^\.]+)\.[^_]+_(?<pod_name>[^_]+)_(?<namespace>[^_]+)_[^_]+_[a-f0-9]{8}$'
|
56
56
|
|
57
|
+
config_param :annotation_match, :array, default: []
|
58
|
+
|
57
59
|
def syms_to_strs(hsh)
|
58
60
|
newhsh = {}
|
59
61
|
hsh.each_pair do |kk,vv|
|
@@ -74,10 +76,11 @@ module Fluent
|
|
74
76
|
metadata = @client.get_pod(pod_name, namespace_name)
|
75
77
|
return if !metadata
|
76
78
|
labels = syms_to_strs(metadata['metadata']['labels'].to_h)
|
79
|
+
annotations = match_annotations(syms_to_strs(metadata['metadata']['annotations'].to_h))
|
77
80
|
if @de_dot
|
78
81
|
self.de_dot!(labels)
|
79
82
|
end
|
80
|
-
|
83
|
+
kubernetes_metadata = {
|
81
84
|
'namespace_name' => namespace_name,
|
82
85
|
'pod_id' => metadata['metadata']['uid'],
|
83
86
|
'pod_name' => pod_name,
|
@@ -85,6 +88,8 @@ module Fluent
|
|
85
88
|
'labels' => labels,
|
86
89
|
'host' => metadata['spec']['nodeName']
|
87
90
|
}
|
91
|
+
kubernetes_metadata['annotations'] = annotations unless annotations.empty?
|
92
|
+
return kubernetes_metadata
|
88
93
|
rescue KubeException
|
89
94
|
nil
|
90
95
|
end
|
@@ -180,6 +185,16 @@ module Fluent
|
|
180
185
|
@merge_json_log_key = 'log'
|
181
186
|
self.class.class_eval { alias_method :filter_stream, :filter_stream_from_files }
|
182
187
|
end
|
188
|
+
|
189
|
+
@annotations_regexps = []
|
190
|
+
@annotation_match.each do |regexp|
|
191
|
+
begin
|
192
|
+
@annotations_regexps << Regexp.compile(regexp)
|
193
|
+
rescue RegexpError => e
|
194
|
+
log.error "Error: invalid regular expression in annotation_match: #{e}"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
183
198
|
end
|
184
199
|
|
185
200
|
def filter_stream_from_files(tag, es)
|
@@ -324,6 +339,18 @@ module Fluent
|
|
324
339
|
end
|
325
340
|
end
|
326
341
|
|
342
|
+
def match_annotations(annotations)
|
343
|
+
result = {}
|
344
|
+
@annotations_regexps.each do |regexp|
|
345
|
+
annotations.each do |key, value|
|
346
|
+
if ::Fluent::StringUtil.match_regexp(regexp, key.to_s)
|
347
|
+
result[key] = value
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
result
|
352
|
+
end
|
353
|
+
|
327
354
|
def start_watch
|
328
355
|
begin
|
329
356
|
resource_version = @client.get_pods.resourceVersion
|
@@ -341,13 +368,15 @@ module Fluent
|
|
341
368
|
cache_key = "#{pod_cache_key}_#{container_status['name']}"
|
342
369
|
cached = @cache[cache_key]
|
343
370
|
if cached
|
344
|
-
# Only thing that can be modified is labels
|
371
|
+
# Only thing that can be modified is labels and (possibly) annotations
|
345
372
|
labels = syms_to_strs(notice.object.metadata.labels.to_h)
|
373
|
+
annotations = match_annotations(syms_to_strs(notice.object.metadata.annotations.to_h))
|
346
374
|
if @de_dot
|
347
375
|
self.de_dot!(labels)
|
348
376
|
end
|
349
377
|
cached['kubernetes']['labels'] = labels
|
350
|
-
|
378
|
+
cached['kubernetes']['annotations'] = annotations unless annotations.empty?
|
379
|
+
@cache[cache_key] = cached
|
351
380
|
end
|
352
381
|
}
|
353
382
|
end
|
@@ -0,0 +1,188 @@
|
|
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
|
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
|
+
Content-Length:
|
44
|
+
- '67'
|
45
|
+
body:
|
46
|
+
encoding: UTF-8
|
47
|
+
string: |-
|
48
|
+
{
|
49
|
+
"versions": [
|
50
|
+
"v1"
|
51
|
+
]
|
52
|
+
}
|
53
|
+
http_version:
|
54
|
+
recorded_at: Fri, 08 May 2015 10:35:37 GMT
|
55
|
+
- request:
|
56
|
+
method: get
|
57
|
+
uri: https://localhost:8443/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc
|
58
|
+
body:
|
59
|
+
encoding: US-ASCII
|
60
|
+
string: ''
|
61
|
+
headers:
|
62
|
+
Accept:
|
63
|
+
- "*/*; q=0.5, application/xml"
|
64
|
+
Accept-Encoding:
|
65
|
+
- gzip, deflate
|
66
|
+
User-Agent:
|
67
|
+
- Ruby
|
68
|
+
response:
|
69
|
+
status:
|
70
|
+
code: 200
|
71
|
+
message: OK
|
72
|
+
headers:
|
73
|
+
Content-Type:
|
74
|
+
- application/json
|
75
|
+
Date:
|
76
|
+
- Fri, 08 May 2015 10:35:37 GMT
|
77
|
+
Transfer-Encoding:
|
78
|
+
- chunked
|
79
|
+
body:
|
80
|
+
encoding: UTF-8
|
81
|
+
string: |-
|
82
|
+
{
|
83
|
+
"kind": "Pod",
|
84
|
+
"apiVersion": "v1",
|
85
|
+
"metadata": {
|
86
|
+
"name": "fabric8-console-controller-98rqc",
|
87
|
+
"generateName": "fabric8-console-controller-",
|
88
|
+
"namespace": "default",
|
89
|
+
"selfLink": "/api/v1/namespaces/default/pods/fabric8-console-controller-98rqc",
|
90
|
+
"uid": "c76927af-f563-11e4-b32d-54ee7527188d",
|
91
|
+
"resourceVersion": "122",
|
92
|
+
"creationTimestamp": "2015-05-08T09:22:42Z",
|
93
|
+
"labels": {
|
94
|
+
"component": "fabric8Console"
|
95
|
+
},
|
96
|
+
"annotations": {
|
97
|
+
"kubernetes.io/config.hash": "c171c44f5b9345c6dc17b0e95030318c",
|
98
|
+
"kubernetes.io/config.mirror": "c171c44f5b9345c6dc17b0e95030318c",
|
99
|
+
"kubernetes.io/config.seen": "2016-06-06T08:08:35.680437994Z",
|
100
|
+
"kubernetes.io/config.source": "file",
|
101
|
+
"custom.field1": "hello_kitty",
|
102
|
+
"field.two": "value"
|
103
|
+
}
|
104
|
+
},
|
105
|
+
"spec": {
|
106
|
+
"volumes": [
|
107
|
+
{
|
108
|
+
"name": "openshift-cert-secrets",
|
109
|
+
"hostPath": null,
|
110
|
+
"emptyDir": null,
|
111
|
+
"gcePersistentDisk": null,
|
112
|
+
"gitRepo": null,
|
113
|
+
"secret": {
|
114
|
+
"secretName": "openshift-cert-secrets"
|
115
|
+
},
|
116
|
+
"nfs": null,
|
117
|
+
"iscsi": null,
|
118
|
+
"glusterfs": null
|
119
|
+
}
|
120
|
+
],
|
121
|
+
"containers": [
|
122
|
+
{
|
123
|
+
"name": "fabric8-console-container",
|
124
|
+
"image": "fabric8/hawtio-kubernetes:latest",
|
125
|
+
"ports": [
|
126
|
+
{
|
127
|
+
"containerPort": 9090,
|
128
|
+
"protocol": "TCP"
|
129
|
+
}
|
130
|
+
],
|
131
|
+
"env": [
|
132
|
+
{
|
133
|
+
"name": "OAUTH_CLIENT_ID",
|
134
|
+
"value": "fabric8-console"
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"name": "OAUTH_AUTHORIZE_URI",
|
138
|
+
"value": "https://localhost:8443/oauth/authorize"
|
139
|
+
}
|
140
|
+
],
|
141
|
+
"resources": {},
|
142
|
+
"volumeMounts": [
|
143
|
+
{
|
144
|
+
"name": "openshift-cert-secrets",
|
145
|
+
"readOnly": true,
|
146
|
+
"mountPath": "/etc/secret-volume"
|
147
|
+
}
|
148
|
+
],
|
149
|
+
"terminationMessagePath": "/dev/termination-log",
|
150
|
+
"imagePullPolicy": "IfNotPresent",
|
151
|
+
"capabilities": {}
|
152
|
+
}
|
153
|
+
],
|
154
|
+
"restartPolicy": "Always",
|
155
|
+
"dnsPolicy": "ClusterFirst",
|
156
|
+
"nodeName": "jimmi-redhat.localnet"
|
157
|
+
},
|
158
|
+
"status": {
|
159
|
+
"phase": "Running",
|
160
|
+
"Condition": [
|
161
|
+
{
|
162
|
+
"type": "Ready",
|
163
|
+
"status": "True"
|
164
|
+
}
|
165
|
+
],
|
166
|
+
"hostIP": "172.17.42.1",
|
167
|
+
"podIP": "172.17.0.8",
|
168
|
+
"containerStatuses": [
|
169
|
+
{
|
170
|
+
"name": "fabric8-console-container",
|
171
|
+
"state": {
|
172
|
+
"running": {
|
173
|
+
"startedAt": "2015-05-08T09:22:44Z"
|
174
|
+
}
|
175
|
+
},
|
176
|
+
"lastState": {},
|
177
|
+
"ready": true,
|
178
|
+
"restartCount": 0,
|
179
|
+
"image": "fabric8/hawtio-kubernetes:latest",
|
180
|
+
"imageID": "docker://b2bd1a24a68356b2f30128e6e28e672c1ef92df0d9ec01ec0c7faea5d77d2303",
|
181
|
+
"containerID": "docker://49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459"
|
182
|
+
}
|
183
|
+
]
|
184
|
+
}
|
185
|
+
}
|
186
|
+
http_version:
|
187
|
+
recorded_at: Fri, 08 May 2015 10:35:37 GMT
|
188
|
+
recorded_with: VCR 2.9.3
|
@@ -502,5 +502,36 @@ use_journal true
|
|
502
502
|
end
|
503
503
|
end
|
504
504
|
|
505
|
+
test 'with kubernetes annotations' do
|
506
|
+
VCR.use_cassette('kubernetes_docker_metadata_annotations') do
|
507
|
+
es = emit({},'
|
508
|
+
kubernetes_url https://localhost:8443
|
509
|
+
watch false
|
510
|
+
cache_size 1
|
511
|
+
annotation_match [ "^custom.+", "two"]
|
512
|
+
')
|
513
|
+
expected_kube_metadata = {
|
514
|
+
'docker' => {
|
515
|
+
'container_id' => '49095a2894da899d3b327c5fde1e056a81376cc9a8f8b09a195f2a92bceed459'
|
516
|
+
},
|
517
|
+
'kubernetes' => {
|
518
|
+
'host' => 'jimmi-redhat.localnet',
|
519
|
+
'pod_name' => 'fabric8-console-controller-98rqc',
|
520
|
+
'container_name' => 'fabric8-console-container',
|
521
|
+
'namespace_name' => 'default',
|
522
|
+
'pod_id' => 'c76927af-f563-11e4-b32d-54ee7527188d',
|
523
|
+
'labels' => {
|
524
|
+
'component' => 'fabric8Console'
|
525
|
+
},
|
526
|
+
'annotations' => {
|
527
|
+
'custom.field1' => 'hello_kitty',
|
528
|
+
'field.two' => 'value'
|
529
|
+
}
|
530
|
+
}
|
531
|
+
}
|
532
|
+
assert_equal(expected_kube_metadata, es.instance_variable_get(:@record_array)[0])
|
533
|
+
end
|
534
|
+
end
|
535
|
+
|
505
536
|
end
|
506
537
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-kubernetes_metadata_filter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jimmi Dyson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -223,6 +223,7 @@ files:
|
|
223
223
|
- lib/fluent/plugin/filter_kubernetes_metadata.rb
|
224
224
|
- test/cassettes/invalid_api_server_config.yml
|
225
225
|
- test/cassettes/kubernetes_docker_metadata.yml
|
226
|
+
- test/cassettes/kubernetes_docker_metadata_annotations.yml
|
226
227
|
- test/cassettes/kubernetes_docker_metadata_dotted_labels.yml
|
227
228
|
- test/cassettes/kubernetes_docker_metadata_using_bearer_token.yml
|
228
229
|
- test/cassettes/metadata_with_namespace_id.yml
|
@@ -251,13 +252,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
251
252
|
version: '0'
|
252
253
|
requirements: []
|
253
254
|
rubyforge_project:
|
254
|
-
rubygems_version: 2.
|
255
|
+
rubygems_version: 2.5.1
|
255
256
|
signing_key:
|
256
257
|
specification_version: 4
|
257
258
|
summary: Filter plugin to add Kubernetes metadata
|
258
259
|
test_files:
|
259
260
|
- test/cassettes/invalid_api_server_config.yml
|
260
261
|
- test/cassettes/kubernetes_docker_metadata.yml
|
262
|
+
- test/cassettes/kubernetes_docker_metadata_annotations.yml
|
261
263
|
- test/cassettes/kubernetes_docker_metadata_dotted_labels.yml
|
262
264
|
- test/cassettes/kubernetes_docker_metadata_using_bearer_token.yml
|
263
265
|
- test/cassettes/metadata_with_namespace_id.yml
|