fluent-plugin-dynatrace 0.1.0 → 0.1.5
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 +4 -4
- data/lib/fluent/plugin/dynatrace_constants.rb +1 -1
- data/lib/fluent/plugin/out_dynatrace.rb +15 -9
- metadata +4 -24
- data/.github/workflows/integration.yaml +0 -50
- data/.github/workflows/lint.yaml +0 -21
- data/.github/workflows/release.yaml +0 -28
- data/.github/workflows/unit.yaml +0 -24
- data/.gitignore +0 -63
- data/.rubocop.yml +0 -8
- data/CODE_OF_CONDUCT.md +0 -76
- data/Gemfile +0 -5
- data/README.md +0 -97
- data/Rakefile +0 -37
- data/fluent-plugin-dynatrace.gemspec +0 -30
- data/test/.rubocop.yml +0 -5
- data/test/integration/fixtures/docker-compose.yaml +0 -27
- data/test/integration/fixtures/fluent/Dockerfile +0 -30
- data/test/integration/fixtures/fluent/entrypoint.sh +0 -17
- data/test/integration/fixtures/fluent/fluent.conf +0 -30
- data/test/integration/fixtures/logsink/Dockerfile +0 -18
- data/test/integration/fixtures/logsink/server.js +0 -46
- data/test/integration/integration_test.rb +0 -50
- data/test/plugin/out_dynatrace_test.rb +0 -152
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 98f310a4b3573ee5ac78b009c56ce8d6efe89de82ecbb6bec12dbff476fde3a5
|
4
|
+
data.tar.gz: 519df5709f9d58c3d5ed4d55bfa83b7b6d6f2fd6483cacb1575bbd7659fe7b54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb61c9971a4e497ec4e9bda95b9d45f2face4791a2eb661df5429656a2be39b7fd0bbbcf33153c3cdec6b18ff878b7651f22bd8951e28dcdb0a0354f77bffcb1
|
7
|
+
data.tar.gz: dc61313d395792ee7e47d85af6098333dd7e52da9d1fe2028c1263b418b4d61727e4e03190d8fad470135457625432d6a0b13def9e6d3efd33b93e988fd00b67
|
@@ -24,12 +24,16 @@ module Fluent
|
|
24
24
|
class DynatraceOutput < Output
|
25
25
|
Fluent::Plugin.register_output('dynatrace', self)
|
26
26
|
|
27
|
+
HTTP_REQUEST_LOCK = Mutex.new
|
28
|
+
|
27
29
|
helpers :compat_parameters # add :inject if need be
|
28
30
|
|
29
31
|
# Configurations
|
30
32
|
desc 'The full URL of the Dynatrace log ingestion endpoint, e.g. https://my-active-gate.example.com/api/logs/ingest'
|
31
33
|
config_param :active_gate_url, :string
|
32
|
-
desc 'The API token to use to authenticate requests to the log ingestion endpoint.
|
34
|
+
desc 'The API token to use to authenticate requests to the log ingestion endpoint. '\
|
35
|
+
'Must have logs.ingest (Ingest Logs) scope. '\
|
36
|
+
'It is recommended to limit scope to only this one.'
|
33
37
|
config_param :api_token, :string, secret: true
|
34
38
|
|
35
39
|
desc 'Disable SSL validation by setting :verify_mode OpenSSL::SSL::VERIFY_NONE'
|
@@ -87,7 +91,7 @@ module Fluent
|
|
87
91
|
body.push(record)
|
88
92
|
end
|
89
93
|
|
90
|
-
send_to_dynatrace("#{body.to_json.chomp}\n")
|
94
|
+
send_to_dynatrace("#{body.to_json.chomp}\n") unless body.empty?
|
91
95
|
end
|
92
96
|
|
93
97
|
#############################################
|
@@ -115,24 +119,26 @@ module Fluent
|
|
115
119
|
end
|
116
120
|
|
117
121
|
def send_to_dynatrace(body)
|
118
|
-
|
122
|
+
HTTP_REQUEST_LOCK.synchronize do
|
123
|
+
agent.start unless agent.started?
|
119
124
|
|
120
|
-
|
121
|
-
|
125
|
+
req = prepare_request(@uri)
|
126
|
+
res = @agent.request(req, body)
|
122
127
|
|
123
|
-
|
128
|
+
return if res.is_a?(Net::HTTPSuccess)
|
124
129
|
|
125
|
-
|
130
|
+
raise failure_message res
|
131
|
+
end
|
126
132
|
end
|
127
133
|
|
128
134
|
def failure_message(res)
|
129
135
|
res_summary = if res
|
130
|
-
"#{res.code} #{res.message}"
|
136
|
+
"#{res.code} #{res.message} #{res.body}"
|
131
137
|
else
|
132
138
|
'res=nil'
|
133
139
|
end
|
134
140
|
|
135
|
-
"failed to
|
141
|
+
"failed to request #{uri} (#{res_summary})"
|
136
142
|
end
|
137
143
|
end
|
138
144
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-dynatrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dynatrace Open Source Engineering
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -99,30 +99,10 @@ executables: []
|
|
99
99
|
extensions: []
|
100
100
|
extra_rdoc_files: []
|
101
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
102
|
- LICENSE
|
111
|
-
- README.md
|
112
|
-
- Rakefile
|
113
|
-
- fluent-plugin-dynatrace.gemspec
|
114
103
|
- lib/fluent/plugin/dynatrace_constants.rb
|
115
104
|
- lib/fluent/plugin/out_dynatrace.rb
|
116
|
-
|
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/
|
105
|
+
homepage: https://github.com/dynatrace-oss/fluent-plugin-dynatrace
|
126
106
|
licenses:
|
127
107
|
- Apache-2.0
|
128
108
|
metadata:
|
@@ -144,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
144
124
|
- !ruby/object:Gem::Version
|
145
125
|
version: '0'
|
146
126
|
requirements: []
|
147
|
-
rubygems_version: 3.1.
|
127
|
+
rubygems_version: 3.1.6
|
148
128
|
signing_key:
|
149
129
|
specification_version: 4
|
150
130
|
summary: A fluentd output plugin for sending logs to the Dynatrace Generic log ingest
|
@@ -1,50 +0,0 @@
|
|
1
|
-
name: Integration
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- main
|
7
|
-
pull_request:
|
8
|
-
workflow_dispatch:
|
9
|
-
schedule:
|
10
|
-
# ┌───────────── minute (0 - 59)
|
11
|
-
# │ ┌───────────── hour (0 - 23)
|
12
|
-
# │ │ ┌───────────── day of the month (1 - 31)
|
13
|
-
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
14
|
-
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
15
|
-
# │ │ │ │ │
|
16
|
-
# │ │ │ │ │
|
17
|
-
# │ │ │ │ │
|
18
|
-
# * * * * *
|
19
|
-
- cron: '30 1 * * *'
|
20
|
-
|
21
|
-
jobs:
|
22
|
-
integration-test:
|
23
|
-
runs-on: ubuntu-latest
|
24
|
-
strategy:
|
25
|
-
matrix:
|
26
|
-
ruby-version: [2.7.x, 2.6.x, 2.5.x]
|
27
|
-
steps:
|
28
|
-
- uses: actions/checkout@v2
|
29
|
-
- name: Set up Ruby ${{ matrix.ruby-version }}
|
30
|
-
uses: actions/setup-ruby@v1
|
31
|
-
with:
|
32
|
-
ruby-version: ${{ matrix.ruby-version }}
|
33
|
-
- run: |
|
34
|
-
gem install bundler
|
35
|
-
bundle install
|
36
|
-
- run: rake test:integration
|
37
|
-
|
38
|
-
notify:
|
39
|
-
needs: integration-test
|
40
|
-
if: always() && needs.integration-test.result == 'failure' && github.ref == 'refs/heads/main'
|
41
|
-
runs-on: ubuntu-latest
|
42
|
-
steps:
|
43
|
-
- name: Test failure notification
|
44
|
-
uses: rtCamp/action-slack-notify@v2
|
45
|
-
env:
|
46
|
-
SLACK_COLOR: '#dc172a'
|
47
|
-
SLACK_TITLE: Integration Test Failure
|
48
|
-
SLACK_MESSAGE: <https://github.com/dynatrace-oss/fluent-plugin-dynatrace/actions/runs/${{ github.run_id }}|Go to test run>
|
49
|
-
SLACK_USERNAME: GitHub Integration Tests
|
50
|
-
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
|
data/.github/workflows/lint.yaml
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
name: Lint
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- main
|
7
|
-
pull_request:
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
lint:
|
11
|
-
runs-on: ubuntu-latest
|
12
|
-
steps:
|
13
|
-
- uses: actions/checkout@v2
|
14
|
-
- name: Set up Ruby
|
15
|
-
uses: actions/setup-ruby@v1
|
16
|
-
with:
|
17
|
-
ruby-version: '2.7'
|
18
|
-
- run: |
|
19
|
-
gem install bundler
|
20
|
-
bundle install
|
21
|
-
- run: rake rubocop
|
@@ -1,28 +0,0 @@
|
|
1
|
-
name: Publish to RubyGems
|
2
|
-
|
3
|
-
on:
|
4
|
-
release:
|
5
|
-
types: [published]
|
6
|
-
|
7
|
-
jobs:
|
8
|
-
build:
|
9
|
-
name: Build + Publish
|
10
|
-
runs-on: ubuntu-latest
|
11
|
-
|
12
|
-
steps:
|
13
|
-
- uses: actions/checkout@v2
|
14
|
-
- name: Set up Ruby 2.7
|
15
|
-
uses: actions/setup-ruby@v1
|
16
|
-
with:
|
17
|
-
ruby-version: 2.7.x
|
18
|
-
|
19
|
-
- name: Publish to RubyGems
|
20
|
-
run: |
|
21
|
-
mkdir -p $HOME/.gem
|
22
|
-
touch $HOME/.gem/credentials
|
23
|
-
chmod 0600 $HOME/.gem/credentials
|
24
|
-
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
25
|
-
gem build fluent-plugin-dynatrace.gemspec
|
26
|
-
gem push fluent-plugin-dynatrace-*.gem
|
27
|
-
env:
|
28
|
-
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_API_KEY_PUSH}}"
|
data/.github/workflows/unit.yaml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
name: Unit Tests
|
2
|
-
|
3
|
-
on:
|
4
|
-
push:
|
5
|
-
branches:
|
6
|
-
- main
|
7
|
-
pull_request:
|
8
|
-
|
9
|
-
jobs:
|
10
|
-
test:
|
11
|
-
runs-on: ubuntu-latest
|
12
|
-
strategy:
|
13
|
-
matrix:
|
14
|
-
ruby-version: [2.7.x, 2.6.x, 2.5.x]
|
15
|
-
steps:
|
16
|
-
- uses: actions/checkout@v2
|
17
|
-
- name: Set up Ruby ${{ matrix.ruby-version }}
|
18
|
-
uses: actions/setup-ruby@v1
|
19
|
-
with:
|
20
|
-
ruby-version: ${{ matrix.ruby-version }}
|
21
|
-
- run: |
|
22
|
-
gem install bundler
|
23
|
-
bundle install
|
24
|
-
- run: rake test
|
data/.gitignore
DELETED
@@ -1,63 +0,0 @@
|
|
1
|
-
# Created by .ignore support plugin (hsz.mobi)
|
2
|
-
### Ruby template
|
3
|
-
*.gem
|
4
|
-
*.rbc
|
5
|
-
/.config
|
6
|
-
/coverage/
|
7
|
-
/InstalledFiles
|
8
|
-
/pkg/
|
9
|
-
/spec/reports/
|
10
|
-
/spec/examples.txt
|
11
|
-
/test/tmp/
|
12
|
-
/test/version_tmp/
|
13
|
-
/tmp/
|
14
|
-
|
15
|
-
# Used by dotenv library to load environment variables.
|
16
|
-
# .env
|
17
|
-
|
18
|
-
# Ignore Byebug command history file.
|
19
|
-
.byebug_history
|
20
|
-
|
21
|
-
## Specific to RubyMotion:
|
22
|
-
.dat*
|
23
|
-
.repl_history
|
24
|
-
build/
|
25
|
-
*.bridgesupport
|
26
|
-
build-iPhoneOS/
|
27
|
-
build-iPhoneSimulator/
|
28
|
-
|
29
|
-
## Specific to RubyMotion (use of CocoaPods):
|
30
|
-
#
|
31
|
-
# We recommend against adding the Pods directory to your .gitignore. However
|
32
|
-
# you should judge for yourself, the pros and cons are mentioned at:
|
33
|
-
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
34
|
-
#
|
35
|
-
# vendor/Pods/
|
36
|
-
|
37
|
-
## Documentation cache and generated files:
|
38
|
-
/.yardoc/
|
39
|
-
/_yardoc/
|
40
|
-
/doc/
|
41
|
-
/rdoc/
|
42
|
-
|
43
|
-
## Environment normalization:
|
44
|
-
/.bundle/
|
45
|
-
/vendor/bundle
|
46
|
-
/lib/bundler/man/
|
47
|
-
|
48
|
-
# for a library or gem, you might want to ignore these files since the code is
|
49
|
-
# intended to run in multiple environments; otherwise, check them in:
|
50
|
-
# Gemfile.lock
|
51
|
-
# .ruby-version
|
52
|
-
# .ruby-gemset
|
53
|
-
|
54
|
-
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
55
|
-
.rvmrc
|
56
|
-
|
57
|
-
### JetBrains template
|
58
|
-
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
|
59
|
-
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
60
|
-
|
61
|
-
# User-specific stuff
|
62
|
-
.idea/
|
63
|
-
/Gemfile.lock
|
data/.rubocop.yml
DELETED
data/CODE_OF_CONDUCT.md
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
# Contributor covenant code of conduct
|
2
|
-
|
3
|
-
## Our pledge
|
4
|
-
|
5
|
-
In the interest of fostering an open and welcoming environment, we as
|
6
|
-
contributors and maintainers pledge to making participation in our project and
|
7
|
-
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
-
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
9
|
-
level of experience, education, socio-economic status, nationality, personal
|
10
|
-
appearance, race, religion, or sexual identity and orientation.
|
11
|
-
|
12
|
-
## Our standards
|
13
|
-
|
14
|
-
Examples of behavior that contributes to creating a positive environment
|
15
|
-
include:
|
16
|
-
|
17
|
-
* Using welcoming and inclusive language
|
18
|
-
* Being respectful of differing viewpoints and experiences
|
19
|
-
* Gracefully accepting constructive criticism
|
20
|
-
* Focusing on what is best for the community
|
21
|
-
* Showing empathy towards other community members
|
22
|
-
|
23
|
-
Examples of unacceptable behavior by participants include:
|
24
|
-
|
25
|
-
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
-
advances
|
27
|
-
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
-
* Public or private harassment
|
29
|
-
* Publishing others' private information, such as a physical or electronic
|
30
|
-
address, without explicit permission
|
31
|
-
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
-
professional setting
|
33
|
-
|
34
|
-
## Our responsibilities
|
35
|
-
|
36
|
-
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
-
behavior and are expected to take appropriate and fair corrective action in
|
38
|
-
response to any instances of unacceptable behavior.
|
39
|
-
|
40
|
-
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
-
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
-
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
-
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
-
threatening, offensive, or harmful.
|
45
|
-
|
46
|
-
## Scope
|
47
|
-
|
48
|
-
This code of conduct applies both within project spaces and in public spaces
|
49
|
-
when an individual is representing the project or its community. Examples of
|
50
|
-
representing a project or community include using an official project email
|
51
|
-
address, posting via an official social media account, or acting as an appointed
|
52
|
-
representative at an online or offline event. Representation of a project may be
|
53
|
-
further defined and clarified by project maintainers.
|
54
|
-
|
55
|
-
## Enforcement
|
56
|
-
|
57
|
-
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at opensource@dynatrace.com. All
|
59
|
-
complaints will be reviewed and investigated and will result in a response that
|
60
|
-
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
-
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
-
Further details of specific enforcement policies may be posted separately.
|
63
|
-
|
64
|
-
Project maintainers who do not follow or enforce this code of conduct in good
|
65
|
-
faith may face temporary or permanent repercussions as determined by other
|
66
|
-
members of the project's leadership.
|
67
|
-
|
68
|
-
## Attribution
|
69
|
-
|
70
|
-
This code of conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
-
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
72
|
-
|
73
|
-
[homepage]: https://www.contributor-covenant.org
|
74
|
-
|
75
|
-
For answers to common questions about this code of conduct, see
|
76
|
-
https://www.contributor-covenant.org/faq
|
data/Gemfile
DELETED
data/README.md
DELETED
@@ -1,97 +0,0 @@
|
|
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
DELETED
@@ -1,37 +0,0 @@
|
|
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
|
@@ -1,30 +0,0 @@
|
|
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
|
data/test/.rubocop.yml
DELETED
@@ -1,27 +0,0 @@
|
|
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
|
@@ -1,30 +0,0 @@
|
|
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
|
@@ -1,17 +0,0 @@
|
|
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
|
@@ -1,30 +0,0 @@
|
|
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>
|
@@ -1,18 +0,0 @@
|
|
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
|
@@ -1,46 +0,0 @@
|
|
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);
|
@@ -1,50 +0,0 @@
|
|
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
|
@@ -1,152 +0,0 @@
|
|
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
|