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.
@@ -0,0 +1,18 @@
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 node:lts-alpine
16
+ COPY server.js /logsink/server.js
17
+
18
+ CMD node /logsink/server.js
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Copyright 2021 Dynatrace LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ const http = require("http");
18
+
19
+ process.on('SIGINT', () => {
20
+ process.exit(0)
21
+ });
22
+
23
+ process.on('SIGTERM', () => {
24
+ process.exit(0)
25
+ });
26
+
27
+ const server = http.createServer((req, res) => {
28
+ const ua = req.headers['user-agent'];
29
+ if (typeof ua != 'string') {
30
+ process.stdout.write("Missing user agent header");
31
+ }
32
+
33
+ if (!ua.match(/^fluent-plugin-dynatrace v\d+\.\d+\.\d+$/)) {
34
+ process.stdout.write("Invalid user agent header");
35
+ }
36
+
37
+ req.on('data', (chunk) => {
38
+ process.stdout.write(chunk);
39
+ });
40
+
41
+ req.on("end", () => {
42
+ res.end();
43
+ });
44
+ })
45
+
46
+ server.listen(8080);
@@ -0,0 +1,50 @@
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 'test/unit'
18
+ require 'net/http'
19
+
20
+ class TestFluentIntegration < Test::Unit::TestCase
21
+ def setup
22
+ puts `cd test/integration/fixtures && docker-compose up -d --force-recreate --build`
23
+ puts 'waiting 5s for integration test to start'
24
+ sleep 5
25
+ end
26
+
27
+ def teardown
28
+ puts `cd test/integration/fixtures && docker-compose down`
29
+ end
30
+
31
+ def test_integration
32
+ puts 'sending logs'
33
+ uri = URI.parse('http://localhost:8080/dt.match')
34
+ http = Net::HTTP.new(uri.host, uri.port)
35
+
36
+ req = Net::HTTP::Post.new(uri.path, { 'Content-Type' => 'application/json' })
37
+
38
+ req.body = '[{"foo":"bar"},{"abc":"def"},{"xyz":"123"},{"abc":"def"},{"xyz":"123"},{"abc":"def"},{"xyz":"123"}]'
39
+ http.request(req)
40
+
41
+ puts 'waiting 10s for output plugin to flush'
42
+ sleep 10
43
+
44
+ logs = `docker logs fixtures_logsink_1`
45
+
46
+ line1 = '[{"foo":"bar"},{"abc":"def"},{"xyz":"123"},{"abc":"def"},{"xyz":"123"}]'
47
+ line2 = '[{"abc":"def"},{"xyz":"123"}]'
48
+ assert_equal("#{line1}\n#{line2}\n", logs)
49
+ end
50
+ end
@@ -0,0 +1,152 @@
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/test'
18
+ require 'fluent/test/helpers'
19
+ require 'fluent/test/driver/output'
20
+ require 'fluent/plugin/out_dynatrace'
21
+ require 'fluent/plugin/dynatrace_constants'
22
+ require 'webrick'
23
+
24
+ class FakeAgent
25
+ Result = Struct.new('Result', :data, :headers)
26
+
27
+ attr_reader :result, :original_agent
28
+ attr_accessor :use_ssl, :verify_mode
29
+
30
+ def initialize(original_agent)
31
+ @result = Result.new(nil, {})
32
+ @started = false
33
+ @original_agent = original_agent
34
+ end
35
+
36
+ def started?
37
+ @started
38
+ end
39
+
40
+ def start
41
+ raise 'already started' if @started
42
+
43
+ @started = true
44
+ end
45
+
46
+ def finish; end
47
+
48
+ def request(req, body)
49
+ raise 'expected POST' unless req.method == 'POST'
50
+ raise 'expected application/json' unless req.content_type == 'application/json'
51
+
52
+ req.each do |key, value|
53
+ @result.headers[key] = value
54
+ end
55
+
56
+ @result.data = JSON.parse(body)
57
+ end
58
+ end
59
+
60
+ class MyOutputTest < Test::Unit::TestCase
61
+ include Fluent::Test::Helpers
62
+
63
+ DEFAULT_LOGGER = ::WEBrick::Log.new($stdout, ::WEBrick::BasicLog::FATAL)
64
+
65
+ def server_port
66
+ 19_881
67
+ end
68
+
69
+ def base_endpoint
70
+ "http://127.0.0.1:#{server_port}"
71
+ end
72
+
73
+ def setup
74
+ Fluent::Test.setup
75
+ end
76
+
77
+ # default configuration for tests
78
+ def config
79
+ %(
80
+ active_gate_url #{base_endpoint}/logs
81
+ api_token secret
82
+ )
83
+ end
84
+
85
+ def events
86
+ [
87
+ { 'message' => 'hello', 'num' => 10, 'bool' => true },
88
+ { 'message' => 'hello', 'num' => 11, 'bool' => false }
89
+ ]
90
+ end
91
+
92
+ def create_driver(conf = config)
93
+ d = Fluent::Test::Driver::Output.new(Fluent::Plugin::DynatraceOutput).configure(conf)
94
+ @agent = FakeAgent.new(d.instance.agent)
95
+ d.instance.agent = @agent
96
+ d
97
+ end
98
+
99
+ sub_test_case 'configuration' do
100
+ test 'required configurations are applied' do
101
+ d = create_driver
102
+ assert_equal "http://127.0.0.1:#{server_port}/logs", d.instance.active_gate_url
103
+ assert_equal 'secret', d.instance.api_token
104
+ end
105
+
106
+ test 'ssl_verify_none false by default' do
107
+ d = create_driver
108
+ assert_equal false, d.instance.ssl_verify_none
109
+ end
110
+
111
+ test 'use ssl and verify certificates if https endpoint provided' do
112
+ d = create_driver(%(
113
+ active_gate_url https://example.dynatrace.com/logs
114
+ api_token secret
115
+ ))
116
+
117
+ assert_equal true, d.instance.agent.original_agent.use_ssl?
118
+ assert_nil d.instance.agent.original_agent.verify_mode
119
+ end
120
+
121
+ test 'use ssl and skip verification if https endpoint and ssl_verify_none' do
122
+ d = create_driver(%(
123
+ active_gate_url https://example.dynatrace.com/logs
124
+ api_token secret
125
+ ssl_verify_none true
126
+ ))
127
+
128
+ assert_equal true, d.instance.agent.original_agent.use_ssl?
129
+ assert_equal OpenSSL::SSL::VERIFY_NONE, d.instance.agent.original_agent.verify_mode
130
+ end
131
+ end
132
+
133
+ sub_test_case 'tests for #write' do
134
+ test 'Write all records as a JSON array' do
135
+ d = create_driver
136
+ t = event_time('2016-06-10 19:46:32 +0900')
137
+ d.run do
138
+ d.feed('tag', t, { 'message' => 'this is a test message', 'amount' => 53 })
139
+ d.feed('tag', t, { 'message' => 'this is a second test message', 'amount' => 54 })
140
+ end
141
+
142
+ assert_equal 2, d.instance.agent.result.data.length
143
+
144
+ content = d.instance.agent.result.data[0]
145
+
146
+ assert_equal "fluent-plugin-dynatrace v#{Fluent::Plugin::DynatraceOutputConstants.version}",
147
+ d.instance.agent.result.headers['user-agent']
148
+ assert_equal content['message'], 'this is a test message'
149
+ assert_equal content['amount'], 53
150
+ end
151
+ end
152
+ end
metadata ADDED
@@ -0,0 +1,152 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-dynatrace
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dynatrace Open Source Engineering
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.14.22
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.14.22
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: bundler
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '2'
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '3'
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: '2'
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '3'
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - '='
58
+ - !ruby/object:Gem::Version
59
+ version: 13.0.3
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - '='
65
+ - !ruby/object:Gem::Version
66
+ version: 13.0.3
67
+ - !ruby/object:Gem::Dependency
68
+ name: rubocop
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '='
72
+ - !ruby/object:Gem::Version
73
+ version: 1.9.1
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '='
79
+ - !ruby/object:Gem::Version
80
+ version: 1.9.1
81
+ - !ruby/object:Gem::Dependency
82
+ name: rubocop-rake
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '='
86
+ - !ruby/object:Gem::Version
87
+ version: 0.5.1
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - '='
93
+ - !ruby/object:Gem::Version
94
+ version: 0.5.1
95
+ description:
96
+ email:
97
+ - opensource@dynatrace.com
98
+ executables: []
99
+ extensions: []
100
+ extra_rdoc_files: []
101
+ files:
102
+ - ".github/workflows/integration.yaml"
103
+ - ".github/workflows/lint.yaml"
104
+ - ".github/workflows/release.yaml"
105
+ - ".github/workflows/unit.yaml"
106
+ - ".gitignore"
107
+ - ".rubocop.yml"
108
+ - CODE_OF_CONDUCT.md
109
+ - Gemfile
110
+ - LICENSE
111
+ - README.md
112
+ - Rakefile
113
+ - fluent-plugin-dynatrace.gemspec
114
+ - lib/fluent/plugin/dynatrace_constants.rb
115
+ - lib/fluent/plugin/out_dynatrace.rb
116
+ - test/.rubocop.yml
117
+ - test/integration/fixtures/docker-compose.yaml
118
+ - test/integration/fixtures/fluent/Dockerfile
119
+ - test/integration/fixtures/fluent/entrypoint.sh
120
+ - test/integration/fixtures/fluent/fluent.conf
121
+ - test/integration/fixtures/logsink/Dockerfile
122
+ - test/integration/fixtures/logsink/server.js
123
+ - test/integration/integration_test.rb
124
+ - test/plugin/out_dynatrace_test.rb
125
+ homepage: https://www.dynatrace.com/
126
+ licenses:
127
+ - Apache-2.0
128
+ metadata:
129
+ bug_tracker_uri: https://github.com/dynatrace-oss/fluent-plugin-dynatrace/issues
130
+ documentation_uri: https://github.com/dynatrace-oss/fluent-plugin-dynatrace
131
+ source_code_uri: https://github.com/dynatrace-oss/fluent-plugin-dynatrace
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: 2.4.0
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubygems_version: 3.1.4
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: A fluentd output plugin for sending logs to the Dynatrace Generic log ingest
151
+ API v2
152
+ test_files: []