fluent-plugin-dynatrace 0.1.3 → 0.2.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 +4 -4
- data/lib/fluent/plugin/dynatrace_constants.rb +1 -1
- data/lib/fluent/plugin/out_dynatrace.rb +73 -15
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b25942088d9fc1e97ab3e9c5ee2cfec5baca12f39744bb09012e5f5238522dd9
|
4
|
+
data.tar.gz: d942be9cfa1215746fcf513a629d09986d5996ba8a0401622b6d0cf5cdf93cf2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63ca8a3ab6b1e22d7d6e4c29bdcba35e33b145b494f6e736b5cd117feb5af22e647262d0477d9eb72ab316550af2a1469cc7459f0730f3a36fceee79d4834cf0
|
7
|
+
data.tar.gz: 9c9532efc4215183ee632ea51a30c27b630b5a239b9fc548e499446fb2dd819ec6c00753e0b3756d435b8625148b59fa1e2c05ad3579d3de5b909fe1c92aa4f7
|
@@ -24,17 +24,24 @@ 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'
|
36
40
|
config_param :ssl_verify_none, :bool, default: false
|
37
41
|
|
42
|
+
desc 'Inject timestamp into each log message'
|
43
|
+
config_param :inject_timestamp, :bool, default: false
|
44
|
+
|
38
45
|
#############################################
|
39
46
|
|
40
47
|
config_section :buffer do
|
@@ -57,7 +64,10 @@ module Fluent
|
|
57
64
|
compat_parameters_convert(conf, :inject)
|
58
65
|
super
|
59
66
|
|
60
|
-
|
67
|
+
raise Fluent::ConfigError, 'api_token is empty' if @api_token.empty?
|
68
|
+
|
69
|
+
@uri = parse_and_validate_uri(@active_gate_url)
|
70
|
+
|
61
71
|
@agent = Net::HTTP.new(@uri.host, @uri.port)
|
62
72
|
|
63
73
|
return unless uri.scheme == 'https'
|
@@ -74,20 +84,29 @@ module Fluent
|
|
74
84
|
#############################################
|
75
85
|
|
76
86
|
def process(_tag, es)
|
87
|
+
log.on_trace { log.trace('#process') }
|
88
|
+
records = 0
|
77
89
|
# es = inject_values_to_event_stream(tag, es)
|
78
|
-
es.each do |
|
79
|
-
|
90
|
+
es.each do |time, record|
|
91
|
+
records += 1
|
92
|
+
log.on_trace { log.trace("#process Processing record #{records}") }
|
93
|
+
record['@timestamp'] = time * 1000 if @inject_timestamp
|
94
|
+
synchronized_send_records(record)
|
80
95
|
end
|
96
|
+
log.on_trace { log.trace("#process Processed #{records} records") }
|
81
97
|
end
|
82
98
|
|
83
99
|
def write(chunk)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
100
|
+
log.on_trace { log.trace('#write') }
|
101
|
+
records = []
|
102
|
+
chunk.each do |time, record|
|
103
|
+
# records.push(inject_values_to_record(chunk.metadata.tag, time, record))
|
104
|
+
record['@timestamp'] = time * 1000 if @inject_timestamp
|
105
|
+
records.push(record)
|
88
106
|
end
|
89
107
|
|
90
|
-
|
108
|
+
log.on_trace { log.trace("#write sent #{records.length} records") }
|
109
|
+
synchronized_send_records(records) unless records.empty?
|
91
110
|
end
|
92
111
|
|
93
112
|
#############################################
|
@@ -106,7 +125,8 @@ module Fluent
|
|
106
125
|
"fluent-plugin-dynatrace v#{DynatraceOutputConstants.version}"
|
107
126
|
end
|
108
127
|
|
109
|
-
def prepare_request
|
128
|
+
def prepare_request
|
129
|
+
log.on_trace { log.trace('#prepare_request') }
|
110
130
|
req = Net::HTTP::Post.new(uri, { 'User-Agent' => user_agent })
|
111
131
|
req['Content-Type'] = 'application/json; charset=utf-8'
|
112
132
|
req['Authorization'] = "Api-Token #{@api_token}"
|
@@ -114,15 +134,37 @@ module Fluent
|
|
114
134
|
req
|
115
135
|
end
|
116
136
|
|
117
|
-
def
|
137
|
+
def synchronized_send_records(records)
|
138
|
+
log.on_trace { log.trace('#synchronized_send_records') }
|
139
|
+
HTTP_REQUEST_LOCK.synchronize do
|
140
|
+
send_records(records)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def send_records(records)
|
145
|
+
log.on_trace { log.trace('#send_records') }
|
146
|
+
|
118
147
|
agent.start unless agent.started?
|
119
148
|
|
120
|
-
|
121
|
-
|
149
|
+
response = send_request(serialize(records))
|
150
|
+
|
151
|
+
return if response.is_a?(Net::HTTPSuccess)
|
152
|
+
|
153
|
+
raise failure_message response
|
154
|
+
end
|
122
155
|
|
123
|
-
|
156
|
+
def serialize(records)
|
157
|
+
log.on_trace { log.trace('#serialize') }
|
158
|
+
body = "#{records.to_json.chomp}\n"
|
159
|
+
log.on_trace { log.trace("#serialize body length #{body.length}") }
|
160
|
+
body
|
161
|
+
end
|
124
162
|
|
125
|
-
|
163
|
+
def send_request(body)
|
164
|
+
log.on_trace { log.trace('#send_request') }
|
165
|
+
response = @agent.request(prepare_request, body)
|
166
|
+
log.on_trace { log.trace("#send_request response #{response}") }
|
167
|
+
response
|
126
168
|
end
|
127
169
|
|
128
170
|
def failure_message(res)
|
@@ -134,6 +176,22 @@ module Fluent
|
|
134
176
|
|
135
177
|
"failed to request #{uri} (#{res_summary})"
|
136
178
|
end
|
179
|
+
|
180
|
+
#############################################
|
181
|
+
|
182
|
+
private
|
183
|
+
|
184
|
+
def parse_and_validate_uri(uri_string)
|
185
|
+
raise Fluent::ConfigError, 'active_gate_url is empty' if uri_string.empty?
|
186
|
+
|
187
|
+
uri = URI.parse(uri_string)
|
188
|
+
raise Fluent::ConfigError, 'active_gate_url scheme must be http or https' unless
|
189
|
+
%w[http https].include?(uri.scheme)
|
190
|
+
|
191
|
+
raise Fluent::ConfigError, 'active_gate_url must include an authority' if uri.host.nil?
|
192
|
+
|
193
|
+
uri
|
194
|
+
end
|
137
195
|
end
|
138
196
|
end
|
139
197
|
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.
|
4
|
+
version: 0.2.0
|
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:
|
11
|
+
date: 2022-02-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -124,7 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '0'
|
126
126
|
requirements: []
|
127
|
-
rubygems_version: 3.1.
|
127
|
+
rubygems_version: 3.1.6
|
128
128
|
signing_key:
|
129
129
|
specification_version: 4
|
130
130
|
summary: A fluentd output plugin for sending logs to the Dynatrace Generic log ingest
|