fluent-plugin-dynatrace 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|