fluent-plugin-dynatrace 0.1.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 +7 -0
- data/.github/workflows/integration.yaml +50 -0
- data/.github/workflows/lint.yaml +21 -0
- data/.github/workflows/release.yaml +28 -0
- data/.github/workflows/unit.yaml +24 -0
- data/.gitignore +63 -0
- data/.rubocop.yml +8 -0
- data/CODE_OF_CONDUCT.md +76 -0
- data/Gemfile +5 -0
- data/LICENSE +201 -0
- data/README.md +97 -0
- data/Rakefile +37 -0
- data/fluent-plugin-dynatrace.gemspec +30 -0
- data/lib/fluent/plugin/dynatrace_constants.rb +27 -0
- data/lib/fluent/plugin/out_dynatrace.rb +139 -0
- data/test/.rubocop.yml +5 -0
- data/test/integration/fixtures/docker-compose.yaml +27 -0
- data/test/integration/fixtures/fluent/Dockerfile +30 -0
- data/test/integration/fixtures/fluent/entrypoint.sh +17 -0
- data/test/integration/fixtures/fluent/fluent.conf +30 -0
- data/test/integration/fixtures/logsink/Dockerfile +18 -0
- data/test/integration/fixtures/logsink/server.js +46 -0
- data/test/integration/integration_test.rb +50 -0
- data/test/plugin/out_dynatrace_test.rb +152 -0
- metadata +152 -0
data/README.md
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
# fluent-plugin-dynatrace, a plugin for [fluentd](https://www.fluentd.org/)
|
2
|
+
|
3
|
+
> This project is developed and maintained by Dynatrace R&D.
|
4
|
+
Currently, this is a prototype and not intended for production use.
|
5
|
+
It is not covered by Dynatrace support.
|
6
|
+
|
7
|
+
A fluentd output plugin for sending logs to the Dynatrace [Generic log ingest API v2](https://www.dynatrace.com/support/help/how-to-use-dynatrace/log-monitoring/log-monitoring-v2/post-log-ingest/).
|
8
|
+
|
9
|
+
## Requirements
|
10
|
+
|
11
|
+
- An instance of fluentd from which logs should be exported
|
12
|
+
- An ActiveGate with the Generic log ingest API v2 enabled as described in the [Dynatrace documentation](https://www.dynatrace.com/support/help/how-to-use-dynatrace/log-monitoring/log-monitoring-v2/log-data-ingestion/)
|
13
|
+
- A [Dynatrace API token](https://www.dynatrace.com/support/help/dynatrace-api/basics/dynatrace-api-authentication/) with the `Log import` permission
|
14
|
+
|
15
|
+
## Configuration options
|
16
|
+
|
17
|
+
Below is an example configuration which sends all logs with tags starting with `dt.` to Dynatrace.
|
18
|
+
|
19
|
+
```
|
20
|
+
<match dt.*>
|
21
|
+
@type dynatrace
|
22
|
+
active_gate_url https://abc12345.live.dynatrace.com/api/v2/logs/ingest
|
23
|
+
api_token api_token
|
24
|
+
ssl_verify_none false
|
25
|
+
</match>
|
26
|
+
```
|
27
|
+
|
28
|
+
### match directive
|
29
|
+
|
30
|
+
- `required`
|
31
|
+
|
32
|
+
The `match` directive is required to use an output plugin and tells fluentd which tags should be sent to the output plugin. In the above example, any tag that starts with `dt.` will be sent to Dynatrace. For more information see [how do match patterns work?](https://docs.fluentd.org/configuration/config-file#how-do-the-match-patterns-work).
|
33
|
+
|
34
|
+
### @type
|
35
|
+
|
36
|
+
- `required`
|
37
|
+
|
38
|
+
The `@type` directive tells fluentd which plugin should be used for the corresponding match block. This should always be `dynatrace` when you want to use the Dynatrace output plugin.
|
39
|
+
|
40
|
+
### `active_gate_url`
|
41
|
+
|
42
|
+
- `required`
|
43
|
+
|
44
|
+
This is the full URL of the [Generic log ingest API v2](https://www.dynatrace.com/support/help/how-to-use-dynatrace/log-monitoring/log-monitoring-v2/post-log-ingest/) endpoint on your ActiveGate.
|
45
|
+
|
46
|
+
### `api_token`
|
47
|
+
|
48
|
+
- `required`
|
49
|
+
|
50
|
+
This is the [Dynatrace API token](https://www.dynatrace.com/support/help/dynatrace-api/basics/dynatrace-api-authentication/) which will be used to authenticate log ingest requests. It should be assigned only the `Log import` permission.
|
51
|
+
|
52
|
+
### `ssl_verify_none`
|
53
|
+
|
54
|
+
- `optional`
|
55
|
+
- `default: false`
|
56
|
+
|
57
|
+
It is recommended to leave this optional configuration set to `false` unless absolutely required. Setting `ssl_verify_none` to `true` causes the output plugin to skip certificate verification when sending log ingest requests to SSL and TLS protected HTTPS endpoints. This option may be required if you are using a self-signed certificate, an expired certificate, or a certificate which was generated for a different domain than the one in use.
|
58
|
+
|
59
|
+
## Development
|
60
|
+
|
61
|
+
`fluent-plugin-dynatrace` supports Ruby versions `>= 2.4.0` but it is recommended that at least `2.7.2` is used for development. Ruby versions can be managed with tools like [chruby](https://github.com/postmodern/chruby) or [rbenv](https://github.com/rbenv/rbenv).
|
62
|
+
|
63
|
+
### Install Dependencies
|
64
|
+
|
65
|
+
```sh
|
66
|
+
bundle install
|
67
|
+
```
|
68
|
+
|
69
|
+
### Run All Tests
|
70
|
+
|
71
|
+
```sh
|
72
|
+
rake test
|
73
|
+
```
|
74
|
+
|
75
|
+
### Run Specific Tests
|
76
|
+
|
77
|
+
```sh
|
78
|
+
# Run one test file
|
79
|
+
rake test TEST=test/plugin/out_dynatrace_test.rb
|
80
|
+
```
|
81
|
+
|
82
|
+
### Code Style Checks
|
83
|
+
|
84
|
+
```sh
|
85
|
+
# Check for code style violations
|
86
|
+
rake rubocop
|
87
|
+
|
88
|
+
# Fix auto-fixable style violations
|
89
|
+
rake rubocop:auto_correct
|
90
|
+
```
|
91
|
+
|
92
|
+
### Run all checks and build
|
93
|
+
|
94
|
+
```sh
|
95
|
+
# Runs rubocop, tests, and builds the gem
|
96
|
+
rake check
|
97
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Copyright 2021 Dynatrace LLC
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
|
18
|
+
require 'bundler/gem_tasks'
|
19
|
+
require 'rake/testtask'
|
20
|
+
require 'rubocop/rake_task'
|
21
|
+
|
22
|
+
RuboCop::RakeTask.new
|
23
|
+
|
24
|
+
Rake::TestTask.new :test do |t|
|
25
|
+
t.libs << 'test'
|
26
|
+
t.libs << 'lib'
|
27
|
+
t.test_files = FileList['test/plugin/*_test.rb']
|
28
|
+
end
|
29
|
+
|
30
|
+
Rake::TestTask.new 'test:integration' do |t|
|
31
|
+
t.test_files = FileList['test/integration/*_test.rb']
|
32
|
+
end
|
33
|
+
|
34
|
+
desc 'check for style violations and test failures and build the gem'
|
35
|
+
task check: %i[rubocop test build]
|
36
|
+
|
37
|
+
task default: :build
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require './lib/fluent/plugin/dynatrace_constants'
|
4
|
+
|
5
|
+
Gem::Specification.new do |gem|
|
6
|
+
gem.name = 'fluent-plugin-dynatrace'
|
7
|
+
gem.version = Fluent::Plugin::DynatraceOutputConstants.version
|
8
|
+
gem.authors = ['Dynatrace Open Source Engineering']
|
9
|
+
gem.email = ['opensource@dynatrace.com']
|
10
|
+
gem.summary = 'A fluentd output plugin for sending logs to the Dynatrace Generic log ingest API v2'
|
11
|
+
gem.homepage = 'https://www.dynatrace.com/'
|
12
|
+
gem.licenses = ['Apache-2.0']
|
13
|
+
|
14
|
+
gem.metadata = {
|
15
|
+
'bug_tracker_uri' => 'https://github.com/dynatrace-oss/fluent-plugin-dynatrace/issues',
|
16
|
+
'documentation_uri' => 'https://github.com/dynatrace-oss/fluent-plugin-dynatrace',
|
17
|
+
'source_code_uri' => 'https://github.com/dynatrace-oss/fluent-plugin-dynatrace'
|
18
|
+
}
|
19
|
+
|
20
|
+
gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
|
21
|
+
gem.require_paths = ['lib']
|
22
|
+
|
23
|
+
gem.required_ruby_version = '>= 2.4.0'
|
24
|
+
|
25
|
+
gem.add_runtime_dependency 'fluentd', ['>= 0.14.22', '< 2']
|
26
|
+
gem.add_development_dependency 'bundler', ['>= 2', '<3']
|
27
|
+
gem.add_development_dependency 'rake', '13.0.3'
|
28
|
+
gem.add_development_dependency 'rubocop', '1.9.1'
|
29
|
+
gem.add_development_dependency 'rubocop-rake', '0.5.1'
|
30
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2021 Dynatrace LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
module Fluent
|
18
|
+
module Plugin
|
19
|
+
# Constants for use in Dynatrace output plugin
|
20
|
+
class DynatraceOutputConstants
|
21
|
+
# The version of the Dynatrace output plugin
|
22
|
+
def self.version
|
23
|
+
'0.1.0'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2021 Dynatrace LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
require 'fluent/plugin/output'
|
18
|
+
require 'net/http'
|
19
|
+
require_relative 'dynatrace_constants'
|
20
|
+
|
21
|
+
module Fluent
|
22
|
+
module Plugin
|
23
|
+
# Fluentd output plugin for Dynatrace
|
24
|
+
class DynatraceOutput < Output
|
25
|
+
Fluent::Plugin.register_output('dynatrace', self)
|
26
|
+
|
27
|
+
helpers :compat_parameters # add :inject if need be
|
28
|
+
|
29
|
+
# Configurations
|
30
|
+
desc 'The full URL of the Dynatrace log ingestion endpoint, e.g. https://my-active-gate.example.com/api/logs/ingest'
|
31
|
+
config_param :active_gate_url, :string
|
32
|
+
desc 'The API token to use to authenticate requests to the log ingestion endpoint. Must have TODO scope'
|
33
|
+
config_param :api_token, :string, secret: true
|
34
|
+
|
35
|
+
desc 'Disable SSL validation by setting :verify_mode OpenSSL::SSL::VERIFY_NONE'
|
36
|
+
config_param :ssl_verify_none, :bool, default: false
|
37
|
+
|
38
|
+
#############################################
|
39
|
+
|
40
|
+
config_section :buffer do
|
41
|
+
config_set_default :flush_at_shutdown, true
|
42
|
+
config_set_default :chunk_limit_size, 10 * 1024
|
43
|
+
end
|
44
|
+
|
45
|
+
# Default injection parameters.
|
46
|
+
# Requires the :inject helper to be added to the helpers above and the
|
47
|
+
# inject lines to be uncommented in the #write and #process methods
|
48
|
+
# config_section :inject do
|
49
|
+
# config_set_default :time_type, :string
|
50
|
+
# config_set_default :localtime, false
|
51
|
+
# end
|
52
|
+
#############################################
|
53
|
+
|
54
|
+
attr_accessor :uri, :agent
|
55
|
+
|
56
|
+
def configure(conf)
|
57
|
+
compat_parameters_convert(conf, :inject)
|
58
|
+
super
|
59
|
+
|
60
|
+
@uri = URI.parse(@active_gate_url)
|
61
|
+
@agent = Net::HTTP.new(@uri.host, @uri.port)
|
62
|
+
|
63
|
+
return unless uri.scheme == 'https'
|
64
|
+
|
65
|
+
@agent.use_ssl = true
|
66
|
+
@agent.verify_mode = OpenSSL::SSL::VERIFY_NONE if @ssl_verify_none
|
67
|
+
end
|
68
|
+
|
69
|
+
def shutdown
|
70
|
+
@agent.finish if @agent.started?
|
71
|
+
super
|
72
|
+
end
|
73
|
+
|
74
|
+
#############################################
|
75
|
+
|
76
|
+
def process(_tag, es)
|
77
|
+
# es = inject_values_to_event_stream(tag, es)
|
78
|
+
es.each do |_time, record|
|
79
|
+
send_to_dynatrace("#{record.to_json.chomp}\n")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def write(chunk)
|
84
|
+
body = []
|
85
|
+
chunk.each do |_time, record|
|
86
|
+
# body.push(inject_values_to_record(chunk.metadata.tag, time, record))
|
87
|
+
body.push(record)
|
88
|
+
end
|
89
|
+
|
90
|
+
send_to_dynatrace("#{body.to_json.chomp}\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
#############################################
|
94
|
+
|
95
|
+
def prefer_buffered_processing
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
def multi_workers_ready?
|
100
|
+
false
|
101
|
+
end
|
102
|
+
|
103
|
+
#############################################
|
104
|
+
|
105
|
+
def user_agent
|
106
|
+
"fluent-plugin-dynatrace v#{DynatraceOutputConstants.version}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def prepare_request(uri)
|
110
|
+
req = Net::HTTP::Post.new(uri, { 'User-Agent' => user_agent })
|
111
|
+
req['Content-Type'] = 'application/json; charset=utf-8'
|
112
|
+
req['Authorization'] = "Api-Token #{@api_token}"
|
113
|
+
|
114
|
+
req
|
115
|
+
end
|
116
|
+
|
117
|
+
def send_to_dynatrace(body)
|
118
|
+
agent.start unless agent.started?
|
119
|
+
|
120
|
+
req = prepare_request(@uri)
|
121
|
+
res = @agent.request(req, body)
|
122
|
+
|
123
|
+
return if res.is_a?(Net::HTTPSuccess)
|
124
|
+
|
125
|
+
raise failure_message res
|
126
|
+
end
|
127
|
+
|
128
|
+
def failure_message(res)
|
129
|
+
res_summary = if res
|
130
|
+
"#{res.code} #{res.message}"
|
131
|
+
else
|
132
|
+
'res=nil'
|
133
|
+
end
|
134
|
+
|
135
|
+
"failed to #{req.method} #{uri} (#{res_summary})"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/test/.rubocop.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Copyright 2021 Dynatrace LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
services:
|
16
|
+
fluent:
|
17
|
+
build:
|
18
|
+
context: ../../../
|
19
|
+
dockerfile: test/integration/fixtures/fluent/Dockerfile
|
20
|
+
ports:
|
21
|
+
- 8080:8080
|
22
|
+
links:
|
23
|
+
- logsink
|
24
|
+
logsink:
|
25
|
+
build: logsink
|
26
|
+
expose:
|
27
|
+
- 8080
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2021 Dynatrace LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
FROM fluent/fluentd:edge
|
16
|
+
|
17
|
+
LABEL maintainer="Daniel Dyla <Daniel.Dyla@dynatrace.com>"
|
18
|
+
USER root
|
19
|
+
|
20
|
+
# the build context is the root of the repo to allow access to the plugin rb
|
21
|
+
COPY test/integration/fixtures/fluent/entrypoint.sh /fluentd/entrypoint.sh
|
22
|
+
RUN chmod +x /fluentd/entrypoint.sh
|
23
|
+
|
24
|
+
COPY test/integration/fixtures/fluent/fluent.conf /fluentd/etc/fluent.conf
|
25
|
+
COPY lib/fluent/plugin/out_dynatrace.rb /fluentd/plugins/
|
26
|
+
COPY lib/fluent/plugin/dynatrace_constants.rb /fluentd/plugins/
|
27
|
+
|
28
|
+
ENTRYPOINT ["tini", "--", "/fluentd/entrypoint.sh"]
|
29
|
+
|
30
|
+
USER fluent
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env sh
|
2
|
+
|
3
|
+
# Copyright 2021 Dynatrace LLC
|
4
|
+
#
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at
|
8
|
+
#
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
#
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
# See the License for the specific language governing permissions and
|
15
|
+
# limitations under the License.
|
16
|
+
|
17
|
+
exec fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright 2021 Dynatrace LLC
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
<source>
|
16
|
+
@type http
|
17
|
+
port 8080
|
18
|
+
</source>
|
19
|
+
|
20
|
+
<match dt.*>
|
21
|
+
@type dynatrace
|
22
|
+
|
23
|
+
active_gate_url http://logsink:8080/api/v2/logs/ingest
|
24
|
+
api_token my_token
|
25
|
+
|
26
|
+
<buffer>
|
27
|
+
chunk_limit_records 5
|
28
|
+
flush_interval 5s
|
29
|
+
</buffer>
|
30
|
+
</match>
|