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 +5 -5
- data/CONTRIBUTING.md +1 -3
- data/Gemfile +13 -0
- data/LICENSE +15 -0
- data/README.md +99 -11
- data/Rakefile +24 -0
- data/examples/Dockerfile +31 -0
- data/examples/fluent.conf +107 -0
- data/examples/k8s-log-collector-ds.yaml +174 -0
- data/fluent-plugin-vmware-loginsight.gemspec +38 -0
- data/lib/fluent/plugin/out_vmware_loginsight.rb +309 -0
- data/test/helper.rb +19 -0
- data/test/plugin/test_out_vmware_loginsight.rb +30 -0
- metadata +16 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bbe384aee2a5b9fdc145146c985dd468eafc210da24bf2af3658875a70a66f1a
|
4
|
+
data.tar.gz: 7ecc573eb0d9b91785d0d386ae0677bb9b83e8588c8ee00fb38f8dc65ad9493e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
##
|
29
|
-
|
30
|
-
You can generate configuration template:
|
28
|
+
## Usage
|
31
29
|
|
32
30
|
```
|
33
|
-
|
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
|
-
|
96
|
+
# Serialization
|
97
|
+
serializer, :string, :default => :json :: Valid Value: json
|
37
98
|
|
38
|
-
|
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
|
-
|
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.
|
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]
|
data/examples/Dockerfile
ADDED
@@ -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.
|
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-
|
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.
|
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
|