fluent-plugin-vmware-loginsight 0.1.0 → 0.1.2

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
- SHA1:
3
- metadata.gz: 7677f5c4289ba3ecb32f9aa6ddc35c6b8f70f4b6
4
- data.tar.gz: 73023509bb66d43595176f3625256009e4187cac
2
+ SHA256:
3
+ metadata.gz: bbe384aee2a5b9fdc145146c985dd468eafc210da24bf2af3658875a70a66f1a
4
+ data.tar.gz: 7ecc573eb0d9b91785d0d386ae0677bb9b83e8588c8ee00fb38f8dc65ad9493e
5
5
  SHA512:
6
- metadata.gz: d3662938668a3307722b0ac604186cfc7a1b397c18d16968cd669360fd2a5c148c4d7904547d9a7258abda2818cbce2a8ee1505206259120e9efb0955f109bcb
7
- data.tar.gz: 12c29d1640c720f3b380475d3fd2f9e368817d3b5e794ad14960120c0ba6d70ab789764b64737eb28dcbdafed382af331a700499b0f18400b3d93f1f50ae4ec3
6
+ metadata.gz: 6ffbdc970719cd2ab72f5d0d72b8824c53a19fa0b48e44815176c4ea2183c59627c07b32c20db81433b3b2749f0f1a76d8fc566816c83728eac371a58738e6c1
7
+ data.tar.gz: e733f007a89b56328ec7ec442c5d50fed4704f8f7e4aa5325b0dfd1be1cb8a5ade812b08473d96b9936cab8fbfee65fd3565c24a34b8a9ac2407452d566c368f
data/CONTRIBUTING.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  # Contributing to fluent-plugin-vmware-loginsight
4
4
 
5
- The fluent-plugin-vmware-loginsight project team welcomes contributions from the community. If you wish to contribute code and you have not
6
- signed our contributor license agreement (CLA), our bot will update the issue when you open a Pull Request. For any
7
- questions about the CLA process, please refer to our [FAQ](https://cla.vmware.com/faq).
5
+ The fluent-plugin-vmware-loginsight project team welcomes contributions from the community. Before you start working with fluent-plugin-vmware-loginsight, please read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on as an open-source patch.
8
6
 
9
7
  ## Community
10
8
 
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+ source "https://rubygems.org"
12
+
13
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,15 @@
1
+ Fluentd plugin for VMware Log Insight
2
+
3
+ Copyright 2018 VMware, Inc. All rights reserved
4
+
5
+ The MIT license (the ìLicenseî) set forth below applies to all parts of the Fluentd plugin for VMware Log Insight project. You may not use this file except in compliance with the License.†
6
+
7
+ MIT License
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
10
+ so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15
+
data/README.md CHANGED
@@ -25,26 +25,114 @@ And then execute:
25
25
  $ bundle
26
26
  ```
27
27
 
28
- ## Configuration
29
-
30
- You can generate configuration template:
28
+ ## Usage
31
29
 
32
30
  ```
33
- $ fluent-plugin-config-format output vmware-loginsight
31
+ <source>
32
+ @type tail
33
+ path /var/log/containers/*.log
34
+ pos_file /var/log/fluentd-docker.pos
35
+ time_format %Y-%m-%dT%H:%M:%S
36
+ tag kubernetes.*
37
+ format json
38
+ read_from_head true
39
+ </source>
40
+
41
+ # Kubernetes metadata filter that tags additional meta data for each event
42
+ <filter kubernetes.var.log.containers.**.log>
43
+ @type kubernetes_metadata
44
+ </filter>
45
+
46
+ <match **>
47
+ @type vmware_loginsight
48
+ scheme https
49
+ ssl_verify true
50
+ # Loginsight host: One may use IP address or cname
51
+ # host X.X.X.X
52
+ host my-loginsight.mycompany.com
53
+ port 9000
54
+ path api/v1/events/ingest
55
+ agent_id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
56
+ http_method post
57
+ serializer json
58
+ rate_limit_msec 0
59
+ raise_on_error false
60
+ include_tag_key true
61
+ tag_key tag
62
+ </match>
63
+ ```
64
+ ### Configuration options
65
+
34
66
  ```
67
+ scheme, :string, :default => 'http' :: Valid Values: http/https
68
+
69
+ # Loginsight Host ex. localhost
70
+ host, :string, :default => 'localhost' :: Valid Values: loginsight_url | loginsight_ip
71
+
72
+ # Loginsight port ex. 9000
73
+ port, :integer, :default => 80
74
+
75
+ # Loginsight ingestion api path ex. 'api/v1/events/ingest'
76
+ path, :string, :default => 'api/v1/events/ingest'
77
+
78
+ # agent_id generated by your LI
79
+ agent_id, :string, :default => '0'
80
+
81
+ # Credentials if used
82
+ username, :string, :default => nil
83
+ password, :string, :default => nil,
84
+
85
+ # Authentication
86
+ authentication, :string, :default => nil :: Valid Value: nil | basic
87
+
88
+ # SSL verification flag
89
+ ssl_verify, :bool, :default => true :: Valid Value: true | false
90
+ # CA Cert filep
91
+ ca_file, :string, :default => nil
92
+
93
+ # HTTP method
94
+ http_method, :string, :default => :post :: Valid Value: post
35
95
 
36
- You can copy and paste generated documents here.
96
+ # Serialization
97
+ serializer, :string, :default => :json :: Valid Value: json
37
98
 
38
- ## Documentation
99
+ # Number of retries
100
+ request_retries, :integer, :default => 3
101
+ # http connection ttl for each request
102
+ request_timeout, :time, :default => 5
39
103
 
40
- ## Releases & Major Branches
104
+ # Simple rate limiting: ignore any records within `rate_limit_msec` since the last one
105
+ rate_limit_msec, :integer, :default => 0
106
+
107
+ # Raise errors that were rescued during HTTP requests?
108
+ raise_on_error, :bool, :default => false :: Valid Value: true | false
109
+
110
+ # Include tag key as log event?
111
+ include_tag_key, :bool, :default => true :: Valid Value: true | false
112
+
113
+ # Metadata key that identifies Fluentd tags
114
+ tag_key, :string, :default => 'tag'
115
+
116
+ # Flatten hashes to create one key/val pair w/o losing log data
117
+ flatten_hashes, :bool, :default => true :: Valid Value: true | false
118
+
119
+ # Seperator to use for joining flattened keys
120
+ flatten_hashes_separator, :string, :default => "__"
121
+ ```
122
+
123
+ For more examples look at [examples](./examples/)
41
124
 
42
125
  ## Contributing
43
126
 
44
- The fluent-plugin-vmware-loginsight project team welcomes contributions from the community. If you wish to contribute code and you have not
45
- signed our contributor license agreement (CLA), our bot will update the issue when you open a Pull Request. For any
46
- questions about the CLA process, please refer to our [FAQ](https://cla.vmware.com/faq). For more detailed information,
47
- refer to [CONTRIBUTING.md](CONTRIBUTING.md).
127
+ The fluent-plugin-vmware-loginsight project team welcomes contributions from the community. Before you start working with fluent-plugin-vmware-loginsight, please read our [Developer Certificate of Origin](https://cla.vmware.com/dco). All contributions to this repository must be signed as described on that page. Your signature certifies that you wrote the patch or have the right to pass it on as an open-source patch. For more detailed information, refer to [CONTRIBUTING.md](CONTRIBUTING.md).
48
128
 
49
129
  ## License
130
+ Fluentd plugin for VMware Log Insight
131
+
132
+ Copyright 2018 VMware, Inc. All Rights Reserved.
133
+
134
+ This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
135
+
136
+ This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
50
137
 
138
+ SPDX-License-Identifier: MIT
data/Rakefile ADDED
@@ -0,0 +1,24 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ require "bundler"
13
+ Bundler::GemHelper.install_tasks
14
+
15
+ require "rake/testtask"
16
+
17
+ Rake::TestTask.new(:test) do |t|
18
+ t.libs.push("lib", "test")
19
+ t.test_files = FileList["test/**/test_*.rb"]
20
+ t.verbose = true
21
+ t.warning = true
22
+ end
23
+
24
+ task default: [:test]
@@ -0,0 +1,31 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ FROM fluent/fluentd:v0.14.15-debian-onbuild
13
+ # Above image expects the loginsight plugin vmware_loginsight to be available under ./plugins/vmware_loginsight.rb
14
+ # and fluentd config under ./fluent.conf by default
15
+
16
+ USER root
17
+
18
+ RUN buildDeps="sudo make gcc g++ libc-dev ruby-dev libffi-dev" \
19
+ && apt-get update \
20
+ && apt-get install -y --no-install-recommends $buildDeps \
21
+ && sudo gem install \
22
+ fluent-plugin-systemd \
23
+ fluent-plugin-kubernetes_metadata_filter \
24
+ && sudo gem sources --clear-all \
25
+ && SUDO_FORCE_REMOVE=yes \
26
+ apt-get purge -y --auto-remove \
27
+ -o APT::AutoRemove::RecommendsImportant=false \
28
+ $buildDeps \
29
+ && rm -rf /var/lib/apt/lists/* \
30
+ /home/fluent/.gem/ruby/2.3.0/cache/*.gem \
31
+ /home/root/.gem/ruby/2.3.0/cache/*.gem
@@ -0,0 +1,107 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ <system>
13
+ log_level info
14
+ </system>
15
+
16
+ # Prevent fluentd from handling records containing its own logs to handle cycles.
17
+ <match fluent.**>
18
+ @type null
19
+ </match>
20
+
21
+ <source>
22
+ @type systemd
23
+ path /run/log/journal
24
+ # Can filter logs if we want, e.g.
25
+ #filters [{ "_SYSTEMD_UNIT": "kubelet.service" }]
26
+ <storage>
27
+ @type local
28
+ persistent true
29
+ path /var/log/fluentd-systemdlog.pos
30
+ </storage>
31
+ tag systemdlog
32
+ read_from_head true
33
+ strip_underscores true
34
+ </source>
35
+
36
+ <source>
37
+ @type tail
38
+ path /var/log/containers/*.log
39
+ # One could exclude certain logs like:
40
+ # exclude_path ["/var/log/containers/log-collector*.log"]
41
+ pos_file /var/log/fluentd-docker.pos
42
+ time_format %Y-%m-%dT%H:%M:%S
43
+ tag kubernetes.*
44
+ format json
45
+ read_from_head true
46
+ </source>
47
+
48
+
49
+ # Sample rule for services that generate java like stack trace
50
+ #<source>
51
+ # @type tail
52
+ # path /var/log/containers/javaapp**.log
53
+ # pos_file /var/log/fluentd-dockerlog.pos
54
+ # time_format %b %d %H:%M:%S
55
+ # tag kubernetes.*
56
+ # format multiline
57
+ # format_firstline /\d{4}-\d{1,2}-\d{1,2}/
58
+ # format1 /^(?<time>\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}) \[(?<thread>.*)\] (?<level>[^\s]+)(?<message>.*)/
59
+ # read_from_head true
60
+ #</source>
61
+
62
+ # Kubernetes metadata filter that tags additional meta data for each event
63
+ <filter kubernetes.var.log.containers.**.log>
64
+ @type kubernetes_metadata
65
+ </filter>
66
+
67
+ # If we want to transform events we could use:
68
+ #<filter **>
69
+ # @type record_transformer
70
+ # enable_ruby
71
+ # auto_typecast
72
+ # <record>
73
+ # hostname "#{Socket.gethostname}"
74
+ # mykey ${["message"=>record.to_json]}
75
+ # </record>
76
+ #</filter>
77
+
78
+ <match fluent.**>
79
+ @type null
80
+ </match>
81
+
82
+ <match **>
83
+ @type copy
84
+ <store>
85
+ @type vmware_loginsight
86
+ scheme https
87
+ ssl_verify true
88
+ # Loginsight host: One may use IP address or cname
89
+ # host X.X.X.X
90
+ host my-loginsight.mycompany.com
91
+ port 9000
92
+ path api/v1/events/ingest
93
+ agent_id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
94
+ http_method post
95
+ serializer json
96
+ rate_limit_msec 0
97
+ raise_on_error false
98
+ include_tag_key true
99
+ tag_key tag
100
+ </store>
101
+ # copy plugin supports sending/copying logs to multiple plugins
102
+ # One may choose to send them to multiple LIs
103
+ # Or one may want send a copy to stdout for debugging
104
+ # <store>
105
+ # @type stdout
106
+ # </store>
107
+ </match>
@@ -0,0 +1,174 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ ---
13
+ apiVersion: v1
14
+ kind: ConfigMap
15
+ metadata:
16
+ name: fluentd-config
17
+ namespace: kube-system
18
+ data:
19
+ fluent.conf: |
20
+ # We can use this config to load some default config or load user defined config
21
+ @include myapp-fluent.conf
22
+
23
+ myapp-fluent.conf: |
24
+ # Input sources
25
+ @include general.conf
26
+ @include systemd-input.conf
27
+ @include kubernetes-input.conf
28
+
29
+ # Parsing/Filtering
30
+ @include kubernetes-filter.conf
31
+
32
+ # Forwading - Be vigilant of the order in which these plugins are specified. Order matters!
33
+ @include myapp-loginsight-output.conf
34
+
35
+ general.conf: |
36
+ <system>
37
+ log_level info
38
+ </system>
39
+ # Prevent fluentd from handling records containing its own logs to handle cycles.
40
+ <match fluent.**>
41
+ @type null
42
+ </match>
43
+
44
+ systemd-input.conf: |
45
+ <source>
46
+ @type systemd
47
+ path /run/log/journal
48
+ # Can filter logs if we want, e.g.
49
+ # filters [{ "_SYSTEMD_UNIT": "kubelet.service" }]
50
+ <storage>
51
+ @type local
52
+ persistent true
53
+ path /var/log/fluentd-systemdlog.pos
54
+ </storage>
55
+ tag systemdlog
56
+ read_from_head true
57
+ strip_underscores true
58
+ </source>
59
+
60
+ kubernetes-input.conf: |
61
+ <source>
62
+ @type tail
63
+ path /var/log/containers/*.log
64
+ # One could exclude certain logs like:
65
+ # exclude_path ["/var/log/containers/log-collector*.log"]
66
+ pos_file /var/log/fluentd-docker.pos
67
+ time_format %Y-%m-%dT%H:%M:%S
68
+ tag kubernetes.*
69
+ format json
70
+ read_from_head true
71
+ </source>
72
+
73
+ kubernetes-filter.conf: |
74
+ <filter kubernetes.**>
75
+ @type kubernetes_metadata
76
+ merge_json_log true
77
+ preserve_json_log true
78
+ </filter>
79
+
80
+ myapp-loginsight-output.conf: |
81
+ # We are capturing all log messages and redirecting them to endpoints mentioned in each <store> tag.
82
+ # One may redirect these logs to muliple endpoints (including multiple LI instances).
83
+ # Or one may chose to tag their specific logs and add their own config to capture those tagged logs and redirect
84
+ # them to appropriate endpoint. This specific config needs to preceed this generic one.
85
+ <match **>
86
+ @type copy
87
+ <store>
88
+ @type vmware_loginsight
89
+ scheme https
90
+ ssl_verify true
91
+ # Loginsight host: One may use IP address or cname
92
+ # host X.X.X.X
93
+ host my-loginsight.mycompany.com
94
+ port 9000
95
+ path api/v1/events/ingest
96
+ agent_id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
97
+ http_method post
98
+ serializer json
99
+ rate_limit_msec 0
100
+ raise_on_error false
101
+ include_tag_key true
102
+ tag_key tag
103
+ </store>
104
+ # If we want to debug and send logs to stdout as well
105
+ # <store>
106
+ # @type stdout
107
+ # </store>
108
+ </match>
109
+
110
+
111
+ extra.conf: |
112
+ # If we want to transform events we could use:
113
+ #<filter **>
114
+ # @type record_transformer
115
+ # enable_ruby
116
+ # auto_typecast
117
+ # <record>
118
+ # hostname "#{Socket.gethostname}"
119
+ # mykey ${["message"=>record.to_json]}
120
+ # </record>
121
+ #</filter>
122
+
123
+
124
+ ---
125
+ kind: DaemonSet
126
+ apiVersion: extensions/v1beta1
127
+ metadata:
128
+ name: "log-collector"
129
+ namespace: "kube-system"
130
+ labels:
131
+ app: "log-collector"
132
+ version: v1
133
+ spec:
134
+ template:
135
+ metadata:
136
+ labels:
137
+ app: "log-collector"
138
+ version: v1
139
+ spec:
140
+ containers:
141
+ - name: "log-collector"
142
+ image: "my-container-hub.com/log-collector:1.0.0"
143
+ command: ["fluentd", "-c", "/fluentd/etc/fluent.conf", "-p", "/fluentd/plugins"]
144
+ resources:
145
+ requests:
146
+ memory: "512Mi"
147
+ cpu: "500m"
148
+ limits:
149
+ memory: "512Mi"
150
+ cpu: "500m"
151
+ volumeMounts:
152
+ - name: varlog
153
+ mountPath: /var/log
154
+ - name: varlibdockercontainers
155
+ mountPath: /var/lib/docker/containers
156
+ readOnly: true
157
+ - name: runlogjournal
158
+ mountPath: /run/log/journal
159
+ - name: fluentdconfig
160
+ mountPath: /fluentd/etc
161
+ terminationGracePeriodSeconds: 30
162
+ volumes:
163
+ - name: varlog
164
+ hostPath:
165
+ path: /var/log
166
+ - name: varlibdockercontainers
167
+ hostPath:
168
+ path: /var/lib/docker/containers
169
+ - name: runlogjournal
170
+ hostPath:
171
+ path: /run/log/journal
172
+ - name: fluentdconfig
173
+ configMap:
174
+ name: "fluentd-config"
@@ -0,0 +1,38 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ lib = File.expand_path("../lib", __FILE__)
13
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
14
+
15
+ Gem::Specification.new do |spec|
16
+ spec.name = "fluent-plugin-vmware-loginsight"
17
+ spec.version = "0.1.2"
18
+ spec.authors = ["Vishal Mohite"]
19
+ spec.email = ["vmohite@vmware.com"]
20
+
21
+ spec.summary = %q{Fluend output plugin to forward logs to VMware Log Insight}
22
+ spec.description = spec.summary
23
+ spec.homepage = "https://github.com/vmware/fluent-plugin-vmware-loginsight"
24
+ spec.license = "MIT"
25
+
26
+ test_files, files = `git ls-files -z`.split("\x0").partition do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.files = files
30
+ spec.executables = files.grep(%r{^bin/}) { |f| File.basename(f) }
31
+ spec.test_files = test_files
32
+ spec.require_paths = ["lib"]
33
+
34
+ spec.add_development_dependency "bundler", "~> 1.14"
35
+ spec.add_development_dependency "rake", "~> 12.0"
36
+ spec.add_development_dependency "test-unit", "~> 3.0"
37
+ spec.add_runtime_dependency "fluentd", [">= 0.14.10", "< 2"]
38
+ end
@@ -0,0 +1,309 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ require "fluent/plugin/output"
13
+ require 'json'
14
+ require 'net/http'
15
+ require 'uri'
16
+
17
+ module Fluent
18
+ module Plugin
19
+ class Fluent::VmwareLoginsightOutput < Fluent::Output
20
+ class ConnectionFailure < StandardError; end
21
+
22
+ Fluent::Plugin.register_output('vmware_loginsight', self)
23
+
24
+ ### Connection Params ###
25
+ config_param :scheme, :string, :default => 'http'
26
+ # Loginsight Host ex. localhost
27
+ config_param :host, :string, :default => 'localhost'
28
+ # In case we want to post to multiple hosts. This is futuristic, Fluentd copy plugin can support this as is
29
+ #config_param :hosts, :string, :default => nil
30
+ # Loginsight port ex. 9000. Default 80
31
+ config_param :port, :integer, :default => 80
32
+ # Loginsight ingestion api path ex. 'api/v1/events/ingest'
33
+ config_param :path, :string, :default => 'api/v1/events/ingest'
34
+ # agent_id generated by your LI
35
+ config_param :agent_id, :string, :default => '0'
36
+ # Credentials if used
37
+ config_param :username, :string, :default => nil
38
+ config_param :password, :string, :default => nil, :secret => true
39
+ # Authentication nil | 'basic'
40
+ config_param :authentication, :string, :default => nil
41
+
42
+ # Set Net::HTTP.verify_mode to `OpenSSL::SSL::VERIFY_NONE`
43
+ config_param :ssl_verify, :bool, :default => true
44
+ config_param :ca_file, :string, :default => nil
45
+
46
+ ### API Params ###
47
+ # HTTP method
48
+ # post | put
49
+ config_param :http_method, :string, :default => :post
50
+ # form | json
51
+ config_param :serializer, :string, :default => :json
52
+ config_param :request_retries, :integer, :default => 3
53
+ config_param :request_timeout, :time, :default => 5
54
+ config_param :max_batch_size, :integer, :default => 512000
55
+
56
+ # Simple rate limiting: ignore any records within `rate_limit_msec`
57
+ # since the last one.
58
+ config_param :rate_limit_msec, :integer, :default => 0
59
+ # Raise errors that were rescued during HTTP requests?
60
+ config_param :raise_on_error, :bool, :default => false
61
+ ### Additional Params
62
+ config_param :include_tag_key, :bool, :default => true
63
+ # Metadata key that identifies Fluentd tags
64
+ config_param :tag_key, :string, :default => 'tag'
65
+ # Flatten hashes to create one key/val pair w/o losing log data
66
+ config_param :flatten_hashes, :bool, :default => true
67
+ # Seperator to use for joining flattened keys
68
+ config_param :flatten_hashes_separator, :string, :default => "__"
69
+
70
+
71
+ def initialize
72
+ super
73
+ end
74
+
75
+ def configure(conf)
76
+ super
77
+
78
+ @ssl_verify_mode = @ssl_verify ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
79
+ @auth = case @authentication
80
+ when 'basic'
81
+ :basic
82
+ else
83
+ :none
84
+ end
85
+
86
+ @last_request_time = nil
87
+ end
88
+
89
+ def start
90
+ super
91
+ end
92
+
93
+ def shutdown
94
+ super
95
+ end
96
+
97
+ def format_url()
98
+ url = "#{@scheme}://#{host}:#{port}/#{path}/#{agent_id}"
99
+ url
100
+ end
101
+
102
+ def set_header(req)
103
+ if @serializer == 'json'
104
+ set_json_header(req)
105
+ end
106
+ req
107
+ end
108
+
109
+ def set_json_header(req)
110
+ req['Content-Type'] = 'application/json'
111
+ req
112
+ end
113
+
114
+ def shorten_key(key)
115
+ # LI doesn't allow some characters in field 'name'
116
+ # like '/', '-', '\', '.', etc. so replace them with '_'
117
+ key = key.gsub(/[\/\.\-\\]/,'_').downcase
118
+ # remove double underscores
119
+ key = key.gsub(/__/,'_')
120
+ # shorten field names
121
+ key = key.gsub(/kubernetes_/,'k8s_')
122
+ key = key.gsub(/labels_/,'')
123
+ key = key.gsub(/_name/,'')
124
+ key = key.gsub(/_hash/,'')
125
+ key = key.gsub(/container_/,'')
126
+ key = key.gsub(/namespace/,'ns')
127
+ key
128
+ end
129
+
130
+ def create_loginsight_event(tag, time, record)
131
+ flattened_records = {}
132
+ if @flatten_hashes
133
+ flattened_records = flatten_record(record, [])
134
+ end
135
+ flattened_records[@tag_key] = tag if @include_tag_key
136
+ fields = []
137
+ keys = []
138
+ log = ''
139
+ flattened_records.each do |key, value|
140
+ begin
141
+ next if value.nil?
142
+ # LI doesn't support duplicate fields, make unique names by appending underscore
143
+ key = shorten_key(key)
144
+ while keys.include?(key)
145
+ key = key + '_'
146
+ end
147
+ keys.push(key)
148
+ key.force_encoding("utf-8")
149
+ # convert value to string if needed
150
+ begin
151
+ value = value.to_s if not value.instance_of?(String)
152
+ value.force_encoding("utf-8")
153
+ rescue Exception=>e
154
+ $log.warn "force_encoding exception: " "#{e.class}, '#{e.message}', " \
155
+ "\n Request: #{key} #{record.to_json[1..1024]}"
156
+ value = "Exception during conversion: #{e.message}"
157
+ end
158
+ end
159
+ if ['log', 'message', 'msg'].include?(key)
160
+ if log != "#{value}"
161
+ if log.empty?
162
+ log = "#{value}"
163
+ else
164
+ log += " #{value}"
165
+ end
166
+ end
167
+ else
168
+ # If there is time information available, update time for LI. LI ignores
169
+ # time if it is out of the error/adjusment window of 10 mins. in such
170
+ # cases we would still like to preserve time info, so add it as event.
171
+ # TODO Ignore the below block for now. Handle the case for time being in
172
+ # different formats than milliseconds
173
+ #if ['time', '_source_realtime_timestamp'].include?(key)
174
+ # time = value
175
+ #end
176
+ fields << {"name" => key, "content" => value}
177
+ end
178
+ end
179
+ event = {
180
+ "fields" => fields,
181
+ "text" => log.gsub(/^$\n/, ''),
182
+ "timestamp" => time * 1000
183
+ }
184
+ event
185
+ end
186
+
187
+ def flatten_record(record, prefix=[])
188
+ ret = {}
189
+
190
+ case record
191
+ when Hash
192
+ record.each { |key, value|
193
+ ret.merge! flatten_record(value, prefix + [key.to_s])
194
+ }
195
+ when Array
196
+ # Don't mess with arrays, leave them unprocessed
197
+ ret.merge!({prefix.join(@flatten_hashes_separator) => record})
198
+ else
199
+ return {prefix.join(@flatten_hashes_separator) => record}
200
+ end
201
+ ret
202
+ end
203
+
204
+ def create_request(tag, time, record)
205
+ url = format_url()
206
+ uri = URI.parse(url)
207
+ req = Net::HTTP.const_get(@http_method.to_s.capitalize).new(uri.path)
208
+ set_body(req, tag, time, record)
209
+ set_header(req)
210
+ return req, uri
211
+ end
212
+
213
+
214
+ def send_request(req, uri)
215
+ is_rate_limited = (@rate_limit_msec != 0 and not @last_request_time.nil?)
216
+ if is_rate_limited and ((Time.now.to_f - @last_request_time) * 1000.0 < @rate_limit_msec)
217
+ $log.info('Dropped request due to rate limiting')
218
+ return
219
+ end
220
+
221
+ if @auth and @auth == 'basic'
222
+ req.basic_auth(@username, @password)
223
+ end
224
+ begin
225
+ retries ||= 2
226
+ response = nil
227
+ @last_request_time = Time.now.to_f
228
+
229
+ http_conn = Net::HTTP.new(uri.host, uri.port)
230
+ # For debugging, set this
231
+ #http_conn.set_debug_output($stdout)
232
+ http_conn.use_ssl = (uri.scheme == 'https')
233
+ if http_conn.use_ssl?
234
+ http_conn.ca_file = @ca_file
235
+ end
236
+ http_conn.verify_mode = @ssl_verify_mode
237
+
238
+ response = http_conn.start do |http|
239
+ http.read_timeout = @request_timeout
240
+ http.request(req)
241
+ end
242
+ rescue => e # rescue all StandardErrors
243
+ # server didn't respond
244
+ # Be careful while turning on below log, if LI instance can't be reached and you're sending
245
+ # log-container logs to LI as well, you may end up in a cycle.
246
+ # TODO handle the cyclic case at plugin level if possible.
247
+ # $log.warn "Net::HTTP.#{req.method.capitalize} raises exception: " \
248
+ # "#{e.class}, '#{e.message}', \n Request: #{req.body[1..1024]}"
249
+ retry unless (retries -= 1).zero?
250
+ raise e if @raise_on_error
251
+ else
252
+ unless response and response.is_a?(Net::HTTPSuccess)
253
+ res_summary = if response
254
+ "Response Code: #{response.code}\n"\
255
+ "Response Message: #{response.message}\n" \
256
+ "Response Body: #{response.body}"
257
+ else
258
+ "Response = nil"
259
+ end
260
+ # ditto cyclic warning
261
+ # $log.warn "Failed to #{req.method} #{uri}\n(#{res_summary})\n" \
262
+ # "Request Size: #{req.body.size} Request Body: #{req.body[1..1024]}"
263
+ end #end unless
264
+ end # end begin
265
+ end # end send_request
266
+
267
+ def send_events(uri, events)
268
+ req = Net::HTTP.const_get(@http_method.to_s.capitalize).new(uri.path)
269
+ event_req = {
270
+ "events" => events
271
+ }
272
+ req.body = event_req.to_json
273
+ set_header(req)
274
+ send_request(req, uri)
275
+ end
276
+
277
+ def handle_records(tag, es)
278
+ url = format_url()
279
+ uri = URI.parse(url)
280
+ events = []
281
+ count = 0
282
+ es.each do |time, record|
283
+ new_event = create_loginsight_event(tag, time, record)
284
+ new_event_size = new_event.to_json.size
285
+ if new_event_size > @max_batch_size
286
+ $log.warn "dropping event larger than max_batch_size: #{new_event.to_json[1..1024]}"
287
+ else
288
+ if (count + new_event_size) > @max_batch_size
289
+ send_events(uri, events)
290
+ events = []
291
+ count = 0
292
+ end
293
+ count += new_event_size
294
+ events << new_event
295
+ end
296
+ end
297
+ if count > 0
298
+ send_events(uri, events)
299
+ end
300
+ end
301
+
302
+ def emit(tag, es, chain)
303
+ handle_records(tag, es)
304
+ chain.next
305
+ end
306
+ end
307
+ end
308
+ end
309
+
data/test/helper.rb ADDED
@@ -0,0 +1,19 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+
12
+ $LOAD_PATH.unshift(File.expand_path("../../", __FILE__))
13
+ require "test-unit"
14
+ require "fluent/test"
15
+ require "fluent/test/driver/output"
16
+ require "fluent/test/helpers"
17
+
18
+ Test::Unit::TestCase.include(Fluent::Test::Helpers)
19
+ Test::Unit::TestCase.extend(Fluent::Test::Helpers)
@@ -0,0 +1,30 @@
1
+ # Fluentd plugin for VMware Log Insight
2
+ #
3
+ # Copyright 2018 VMware, Inc. All Rights Reserved.
4
+ #
5
+ # This product is licensed to you under the MIT license (the "License"). You may not use this product except in compliance with the MIT License.
6
+ #
7
+ # This product may include a number of subcomponents with separate copyright notices and license terms. Your use of these subcomponents is subject to the terms and conditions of the subcomponent's license, as noted in the LICENSE file.
8
+ #
9
+ # SPDX-License-Identifier: MIT
10
+
11
+ # TODO Need to add tests.
12
+
13
+ require "helper"
14
+ require "fluent/plugin/out_vmware_loginsight.rb"
15
+
16
+ class VmwareLoginsightOutputTest < Test::Unit::TestCase
17
+ setup do
18
+ Fluent::Test.setup
19
+ end
20
+
21
+ test "failure" do
22
+ flunk
23
+ end
24
+
25
+ private
26
+
27
+ def create_driver(conf)
28
+ Fluent::Test::Driver::Output.new(Fluent::Plugin::VmwareLoginsightOutput).configure(conf)
29
+ end
30
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-vmware-loginsight
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vishal Mohite
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-13 00:00:00.000000000 Z
11
+ date: 2018-09-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -81,7 +81,17 @@ extra_rdoc_files: []
81
81
  files:
82
82
  - ".gitignore"
83
83
  - CONTRIBUTING.md
84
+ - Gemfile
85
+ - LICENSE
84
86
  - README.md
87
+ - Rakefile
88
+ - examples/Dockerfile
89
+ - examples/fluent.conf
90
+ - examples/k8s-log-collector-ds.yaml
91
+ - fluent-plugin-vmware-loginsight.gemspec
92
+ - lib/fluent/plugin/out_vmware_loginsight.rb
93
+ - test/helper.rb
94
+ - test/plugin/test_out_vmware_loginsight.rb
85
95
  homepage: https://github.com/vmware/fluent-plugin-vmware-loginsight
86
96
  licenses:
87
97
  - MIT
@@ -102,8 +112,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
102
112
  version: '0'
103
113
  requirements: []
104
114
  rubyforge_project:
105
- rubygems_version: 2.5.2.3
115
+ rubygems_version: 2.7.7
106
116
  signing_key:
107
117
  specification_version: 4
108
118
  summary: Fluend output plugin to forward logs to VMware Log Insight
109
- test_files: []
119
+ test_files:
120
+ - test/helper.rb
121
+ - test/plugin/test_out_vmware_loginsight.rb