fluent-plugin-kubernetes_metadata_filter 0.23.0 → 0.24.0

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
  SHA1:
3
- metadata.gz: ad94cfeef2063842b127dcd7717b96951b35c6e4
4
- data.tar.gz: 9ba28aa2447189ed598de36c64f6776c381f090c
3
+ metadata.gz: 718b00c62d8a5f40dd763c50b34ddc7ab4106a98
4
+ data.tar.gz: 4368cdeb4409e1416c7dfe12ab75b7c604c9f5a5
5
5
  SHA512:
6
- metadata.gz: 2930f99ff2db361b6492504da2a032d0148213fe11e33c44fd29e78f7d73a96a867259d618522ef1002b7adfa5a9c323349e34cc25ae2e085f27667d4fab3f50
7
- data.tar.gz: 150b250919002593405ee18de5024b146c4438ce4bf5a631912b85031847d6b8e97567df9c75df2a9278bfd96cd98916440ad8c7c9f9df59bd26b67f2a001895
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.23.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
- return {
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
- @cache[cache_key] = cached
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.23.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-06-14 00:00:00.000000000 Z
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.4.8
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