fluent-plugin-splunk-hec 1.2.4 → 1.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +56 -72
- data/LICENSE +0 -1
- data/README.md +14 -3
- data/Rakefile +0 -3
- data/VERSION +1 -1
- data/fluent-plugin-splunk-hec.gemspec +1 -2
- data/lib/fluent/plugin/out_splunk.rb +37 -23
- data/lib/fluent/plugin/out_splunk_hec.rb +25 -9
- data/test/fluent/plugin/out_splunk_hec_test.rb +25 -2
- metadata +12 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3404443a78707ec84c807cc959de100eefec4c7144f76b4587fa4c02580d300d
|
4
|
+
data.tar.gz: '098eb708f6093e40c59aa597c7f185403f9fb195c03758a726ebd8bcc2fc4468'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7dc521fe94e36ae9e4df51f5a32c936615228a164f76ec9391bd72033aa06d35e8292d8cc95b6025cf880943e56f48c2bebbbc5a9e606e219972528a464c9a3
|
7
|
+
data.tar.gz: 4d6ae8221544453debf6e0dbf1ecbdb9a0774f36ae3d1e4715781ca078a2c0d3ebd2870455ffcd75bdb292d1634a8e71d6034f620c69638d51372f010cac4d46
|
data/Gemfile.lock
CHANGED
@@ -1,62 +1,62 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
fluent-plugin-splunk-hec (1.2.
|
4
|
+
fluent-plugin-splunk-hec (1.2.8)
|
5
5
|
fluentd (>= 1.4)
|
6
6
|
multi_json (~> 1.13)
|
7
7
|
net-http-persistent (~> 3.1)
|
8
8
|
openid_connect (~> 1.1.8)
|
9
|
-
prometheus-client (
|
9
|
+
prometheus-client (>= 2.1.0)
|
10
10
|
|
11
11
|
GEM
|
12
12
|
remote: https://rubygems.org/
|
13
13
|
specs:
|
14
|
-
activemodel (
|
15
|
-
activesupport (=
|
16
|
-
activesupport (
|
14
|
+
activemodel (6.1.4.1)
|
15
|
+
activesupport (= 6.1.4.1)
|
16
|
+
activesupport (6.1.4.1)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
|
-
i18n (>=
|
19
|
-
minitest (
|
20
|
-
tzinfo (~>
|
21
|
-
|
18
|
+
i18n (>= 1.6, < 2)
|
19
|
+
minitest (>= 5.1)
|
20
|
+
tzinfo (~> 2.0)
|
21
|
+
zeitwerk (~> 2.3)
|
22
|
+
addressable (2.8.0)
|
22
23
|
public_suffix (>= 2.0.2, < 5.0)
|
23
|
-
aes_key_wrap (1.0
|
24
|
-
ast (2.4.0)
|
24
|
+
aes_key_wrap (1.1.0)
|
25
25
|
attr_required (1.0.1)
|
26
|
-
bindata (2.4.
|
27
|
-
concurrent-ruby (1.1.
|
28
|
-
connection_pool (2.2.
|
29
|
-
cool.io (1.
|
30
|
-
crack (0.4.
|
31
|
-
|
32
|
-
docile (1.
|
33
|
-
fluentd (1.
|
26
|
+
bindata (2.4.10)
|
27
|
+
concurrent-ruby (1.1.9)
|
28
|
+
connection_pool (2.2.5)
|
29
|
+
cool.io (1.7.1)
|
30
|
+
crack (0.4.5)
|
31
|
+
rexml
|
32
|
+
docile (1.4.0)
|
33
|
+
fluentd (1.14.2)
|
34
|
+
bundler
|
34
35
|
cool.io (>= 1.4.5, < 2.0.0)
|
35
|
-
http_parser.rb (>= 0.5.1, < 0.
|
36
|
+
http_parser.rb (>= 0.5.1, < 0.8.0)
|
36
37
|
msgpack (>= 1.3.1, < 2.0.0)
|
37
|
-
serverengine (>= 2.
|
38
|
+
serverengine (>= 2.2.2, < 3.0.0)
|
38
39
|
sigdump (~> 0.2.2)
|
39
|
-
strptime (>= 0.2.
|
40
|
+
strptime (>= 0.2.4, < 1.0.0)
|
40
41
|
tzinfo (>= 1.0, < 3.0)
|
41
42
|
tzinfo-data (~> 1.0)
|
43
|
+
webrick (>= 1.4.2, < 1.8.0)
|
42
44
|
yajl-ruby (~> 1.0)
|
43
|
-
hashdiff (1.0.
|
44
|
-
http_parser.rb (0.
|
45
|
+
hashdiff (1.0.1)
|
46
|
+
http_parser.rb (0.7.0)
|
45
47
|
httpclient (2.8.3)
|
46
|
-
i18n (1.8.
|
48
|
+
i18n (1.8.11)
|
47
49
|
concurrent-ruby (~> 1.0)
|
48
|
-
|
49
|
-
json (2.3.0)
|
50
|
-
json-jwt (1.11.0)
|
50
|
+
json-jwt (1.13.0)
|
51
51
|
activesupport (>= 4.2)
|
52
52
|
aes_key_wrap
|
53
53
|
bindata
|
54
54
|
mail (2.7.1)
|
55
55
|
mini_mime (>= 0.1.1)
|
56
|
-
mini_mime (1.
|
57
|
-
minitest (5.14.
|
58
|
-
msgpack (1.
|
59
|
-
multi_json (1.
|
56
|
+
mini_mime (1.1.2)
|
57
|
+
minitest (5.14.4)
|
58
|
+
msgpack (1.4.2)
|
59
|
+
multi_json (1.15.0)
|
60
60
|
net-http-persistent (3.1.0)
|
61
61
|
connection_pool (~> 2.2)
|
62
62
|
openid_connect (1.1.8)
|
@@ -69,69 +69,54 @@ GEM
|
|
69
69
|
validate_email
|
70
70
|
validate_url
|
71
71
|
webfinger (>= 1.0.1)
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
power_assert (1.1.5)
|
76
|
-
powerpack (0.1.2)
|
77
|
-
prometheus-client (0.9.0)
|
78
|
-
quantile (~> 0.2.1)
|
79
|
-
public_suffix (4.0.3)
|
80
|
-
quantile (0.2.1)
|
72
|
+
power_assert (2.0.1)
|
73
|
+
prometheus-client (2.1.0)
|
74
|
+
public_suffix (4.0.6)
|
81
75
|
rack (2.2.3)
|
82
|
-
rack-oauth2 (1.
|
76
|
+
rack-oauth2 (1.19.0)
|
83
77
|
activesupport
|
84
78
|
attr_required
|
85
79
|
httpclient
|
86
80
|
json-jwt (>= 1.11.0)
|
87
|
-
rack
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
jaro_winkler (~> 1.5.1)
|
92
|
-
parallel (~> 1.10)
|
93
|
-
parser (>= 2.5, != 2.5.1.1)
|
94
|
-
powerpack (~> 0.1)
|
95
|
-
rainbow (>= 2.2.2, < 4.0)
|
96
|
-
ruby-progressbar (~> 1.7)
|
97
|
-
unicode-display_width (~> 1.4.0)
|
98
|
-
ruby-progressbar (1.10.1)
|
99
|
-
safe_yaml (1.0.5)
|
100
|
-
serverengine (2.2.1)
|
81
|
+
rack (>= 2.1.0)
|
82
|
+
rake (13.0.6)
|
83
|
+
rexml (3.2.5)
|
84
|
+
serverengine (2.2.4)
|
101
85
|
sigdump (~> 0.2.2)
|
102
86
|
sigdump (0.2.4)
|
103
|
-
simplecov (0.
|
87
|
+
simplecov (0.21.2)
|
104
88
|
docile (~> 1.1)
|
105
|
-
|
106
|
-
|
107
|
-
simplecov-html (0.
|
108
|
-
|
109
|
-
|
89
|
+
simplecov-html (~> 0.11)
|
90
|
+
simplecov_json_formatter (~> 0.1)
|
91
|
+
simplecov-html (0.12.3)
|
92
|
+
simplecov_json_formatter (0.1.3)
|
93
|
+
strptime (0.2.5)
|
94
|
+
swd (1.3.0)
|
110
95
|
activesupport (>= 3)
|
111
96
|
attr_required (>= 0.0.5)
|
112
97
|
httpclient (>= 2.4)
|
113
|
-
test-unit (3.
|
98
|
+
test-unit (3.5.0)
|
114
99
|
power_assert
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
tzinfo-data (1.2019.3)
|
100
|
+
tzinfo (2.0.4)
|
101
|
+
concurrent-ruby (~> 1.0)
|
102
|
+
tzinfo-data (1.2021.5)
|
119
103
|
tzinfo (>= 1.0.0)
|
120
|
-
unicode-display_width (1.4.1)
|
121
104
|
validate_email (0.1.6)
|
122
105
|
activemodel (>= 3.0)
|
123
106
|
mail (>= 2.2.5)
|
124
|
-
validate_url (1.0.
|
107
|
+
validate_url (1.0.13)
|
125
108
|
activemodel (>= 3.0.0)
|
126
109
|
public_suffix
|
127
|
-
webfinger (1.
|
110
|
+
webfinger (1.2.0)
|
128
111
|
activesupport
|
129
112
|
httpclient (>= 2.4)
|
130
113
|
webmock (3.5.1)
|
131
114
|
addressable (>= 2.3.6)
|
132
115
|
crack (>= 0.3.2)
|
133
116
|
hashdiff
|
117
|
+
webrick (1.7.0)
|
134
118
|
yajl-ruby (1.4.1)
|
119
|
+
zeitwerk (2.5.1)
|
135
120
|
|
136
121
|
PLATFORMS
|
137
122
|
ruby
|
@@ -141,10 +126,9 @@ DEPENDENCIES
|
|
141
126
|
fluent-plugin-splunk-hec!
|
142
127
|
minitest (~> 5.0)
|
143
128
|
rake (>= 12.0)
|
144
|
-
rubocop (~> 0.63.1)
|
145
129
|
simplecov
|
146
130
|
test-unit (~> 3.0)
|
147
131
|
webmock (~> 3.5.0)
|
148
132
|
|
149
133
|
BUNDLED WITH
|
150
|
-
2.
|
134
|
+
2.2.30
|
data/LICENSE
CHANGED
@@ -270,7 +270,6 @@ The following components are provided under the MIT License. See project link fo
|
|
270
270
|
(MIT License) rake (https://github.com/ruby/rake/blob/master/MIT-LICENSE)
|
271
271
|
(MIT License) recursive-open-struct (https://github.com/aetherknight/recursive-open-struct/blob/master/LICENSE.txt)
|
272
272
|
(MIT License) rest-client (https://github.com/rest-client/rest-client/blob/master/LICENSE)
|
273
|
-
(MIT License) rubocop (https://github.com/rubocop-hq/rubocop/blob/master/LICENSE.txt)
|
274
273
|
(MIT License) ruby-progressbar (https://github.com/jfelchner/ruby-progressbar/blob/master/LICENSE.txt)
|
275
274
|
(MIT License) safe_yaml (https://github.com/dtao/safe_yaml/blob/master/LICENSE.txt)
|
276
275
|
(MIT License) sigdump (https://github.com/frsyuki/sigdump/blob/master/LICENSE)
|
data/README.md
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
[![CircleCI](https://circleci.com/gh/git-lfs/git-lfs.svg?style=shield&circle-token=856152c2b02bfd236f54d21e1f581f3e4ebf47ad)](https://circleci.com/gh/splunk/fluent-plugin-splunk-hec)
|
2
1
|
# fluent-plugin-splunk-hec
|
3
2
|
|
4
3
|
[Fluentd](https://fluentd.org/) output plugin to send events and metrics to [Splunk](https://www.splunk.com) in 2 modes:<br/>
|
@@ -260,6 +259,10 @@ Cannot set both `source` and `source_key` parameters at the same time.
|
|
260
259
|
|
261
260
|
Field name that contains the sourcetype. Cannot set both `source` and `source_key` parameters at the same time.
|
262
261
|
|
262
|
+
### time_key (string) (optional)
|
263
|
+
|
264
|
+
Field name to contain Splunk event time. By default will use fluentd\'d time.
|
265
|
+
|
263
266
|
### fields (init) (optional)
|
264
267
|
|
265
268
|
Lets you specify the index-time fields for the event data type, or metric dimensions for the metric data type. Null value fields are removed.
|
@@ -293,7 +296,7 @@ In this case, parameters inside `<fields>` are used as indexed fields and remove
|
|
293
296
|
<fields>
|
294
297
|
file
|
295
298
|
level
|
296
|
-
app
|
299
|
+
app application
|
297
300
|
</fields>
|
298
301
|
</match>
|
299
302
|
```
|
@@ -340,7 +343,7 @@ For metrics, parameters inside `<fields>` are used as dimensions. If `<fields>`
|
|
340
343
|
<fields>
|
341
344
|
file
|
342
345
|
level
|
343
|
-
app
|
346
|
+
app application
|
344
347
|
</fields>
|
345
348
|
</match>
|
346
349
|
```
|
@@ -432,6 +435,14 @@ List of SSl ciphers allowed.
|
|
432
435
|
|
433
436
|
Specifies whether an insecure SSL connection is allowed. If set to false, Splunk does not verify an insecure server certificate. This parameter is set to `false` by default. Ensure parameter `ca_file` is not configured in order to allow insecure SSL connections when this value is set to `true`.
|
434
437
|
|
438
|
+
#### require_ssl_min_version (bool)
|
439
|
+
|
440
|
+
When set to true, TLS version 1.1 and above is required.
|
441
|
+
|
442
|
+
#### consume_chunk_on_4xx_errors (bool)
|
443
|
+
|
444
|
+
Specifies whether any 4xx HTTP response status code consumes the buffer chunks. If set to false, Splunk will fail to flush the buffer on such status codes. This parameter is set to `true` by default for backwards compatibility.
|
445
|
+
|
435
446
|
## About Buffer
|
436
447
|
|
437
448
|
This plugin sends events to HEC using [batch mode](https://docs.splunk.com/Documentation/Splunk/7.1.0/Data/FormateventsforHTTPEventCollector#Event_data).
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.2.
|
1
|
+
1.2.8
|
@@ -37,13 +37,12 @@ Gem::Specification.new do |spec|
|
|
37
37
|
spec.add_runtime_dependency 'multi_json', '~> 1.13'
|
38
38
|
spec.add_runtime_dependency 'net-http-persistent', '~> 3.1'
|
39
39
|
spec.add_runtime_dependency 'openid_connect', '~> 1.1.8'
|
40
|
-
spec.add_runtime_dependency 'prometheus-client', '
|
40
|
+
spec.add_runtime_dependency 'prometheus-client', '>= 2.1.0'
|
41
41
|
|
42
42
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
43
43
|
spec.add_development_dependency 'rake', '>= 12.0'
|
44
44
|
# required by fluent/test.rb
|
45
45
|
spec.add_development_dependency 'minitest', '~> 5.0'
|
46
|
-
spec.add_development_dependency 'rubocop', '~> 0.63.1'
|
47
46
|
spec.add_development_dependency 'simplecov', '~> 0.16.1'
|
48
47
|
spec.add_development_dependency 'test-unit', '~> 3.0'
|
49
48
|
spec.add_development_dependency 'webmock', '~> 3.5.0'
|
@@ -13,7 +13,7 @@ module Fluent::Plugin
|
|
13
13
|
autoload :VERSION, 'fluent/plugin/out_splunk/version'
|
14
14
|
autoload :MatchFormatter, 'fluent/plugin/out_splunk/match_formatter'
|
15
15
|
|
16
|
-
KEY_FIELDS = %w[index host source sourcetype metric_name metric_value].freeze
|
16
|
+
KEY_FIELDS = %w[index host source sourcetype metric_name metric_value time].freeze
|
17
17
|
TAG_PLACEHOLDER = '${tag}'
|
18
18
|
|
19
19
|
desc 'The host field for events, by default it uses the hostname of the machine that runnning fluentd. This is exclusive with `host_key`.'
|
@@ -51,6 +51,9 @@ module Fluent::Plugin
|
|
51
51
|
# this is blank on purpose
|
52
52
|
end
|
53
53
|
|
54
|
+
desc 'Indicates if 4xx errors should consume chunk'
|
55
|
+
config_param :consume_chunk_on_4xx_errors, :bool, :default => true
|
56
|
+
|
54
57
|
config_section :format do
|
55
58
|
config_set_default :usage, '**'
|
56
59
|
config_set_default :@type, 'json'
|
@@ -97,11 +100,11 @@ module Fluent::Plugin
|
|
97
100
|
write_to_splunk(chunk)
|
98
101
|
end
|
99
102
|
|
100
|
-
@metrics[:record_counter].increment(metric_labels, chunk.size_of_events)
|
101
|
-
@metrics[:bytes_counter].increment(metric_labels, chunk.bytesize)
|
102
|
-
@metrics[:write_records_histogram].observe(
|
103
|
-
@metrics[:write_bytes_histogram].observe(metric_labels,
|
104
|
-
@metrics[:write_latency_histogram].observe(metric_labels,
|
103
|
+
@metrics[:record_counter].increment(labels: metric_labels, by: chunk.size_of_events)
|
104
|
+
@metrics[:bytes_counter].increment(labels: metric_labels, by: chunk.bytesize)
|
105
|
+
@metrics[:write_records_histogram].observe(chunk.size_of_events, labels: metric_labels)
|
106
|
+
@metrics[:write_bytes_histogram].observe(chunk.bytesize, labels: metric_labels, )
|
107
|
+
@metrics[:write_latency_histogram].observe(t, labels: metric_labels, )
|
105
108
|
end
|
106
109
|
|
107
110
|
def write_to_splunk(_chunk)
|
@@ -150,13 +153,14 @@ module Fluent::Plugin
|
|
150
153
|
def process_response(response, _request_body)
|
151
154
|
log.trace { "[Response] POST #{@api}: #{response.inspect}" }
|
152
155
|
|
153
|
-
@metrics[:status_counter].increment(metric_labels(status: response.code.to_s))
|
156
|
+
@metrics[:status_counter].increment(labels: metric_labels(status: response.code.to_s))
|
157
|
+
|
158
|
+
raise_err = response.code.to_s.start_with?('5') || (!@consume_chunk_on_4xx_errors && response.code.to_s.start_with?('4'))
|
154
159
|
|
155
160
|
# raise Exception to utilize Fluentd output plugin retry mechanism
|
156
|
-
raise "Server error (#{response.code}) for POST #{@api}, response: #{response.body}" if
|
161
|
+
raise "Server error (#{response.code}) for POST #{@api}, response: #{response.body}" if raise_err
|
157
162
|
|
158
|
-
# For both success response (2xx)
|
159
|
-
# Because there probably a bug in the code if we get 4xx errors, retry won't do any good.
|
163
|
+
# For both success response (2xx) we will consume the chunk.
|
160
164
|
unless response.code.to_s.start_with?('2')
|
161
165
|
log.error "#{self.class}: Failed POST to #{@api}, response: #{response.body}"
|
162
166
|
log.error { "#{self.class}: Failed request body: #{post.body}" }
|
@@ -205,7 +209,7 @@ module Fluent::Plugin
|
|
205
209
|
# This loop looks dump, but it is used to suppress the unused parameter configuration warning
|
206
210
|
# Learned from `filter_record_transformer`.
|
207
211
|
conf.elements.select { |element| element.name == 'fields' }.each do |element|
|
208
|
-
element.each_pair { |k, _v| element.
|
212
|
+
element.each_pair { |k, _v| element.has_key?(k) }
|
209
213
|
end
|
210
214
|
|
211
215
|
return unless @fields
|
@@ -231,28 +235,34 @@ module Fluent::Plugin
|
|
231
235
|
|
232
236
|
@metrics = {
|
233
237
|
record_counter: register_metric(::Prometheus::Client::Counter.new(
|
234
|
-
:splunk_output_write_records_count,
|
235
|
-
'The number of log records being sent'
|
238
|
+
:splunk_output_write_records_count, docstring:
|
239
|
+
'The number of log records being sent',
|
240
|
+
labels: metric_label_keys
|
236
241
|
)),
|
237
242
|
bytes_counter: register_metric(::Prometheus::Client::Counter.new(
|
238
|
-
:splunk_output_write_bytes_count,
|
239
|
-
'The number of log bytes being sent'
|
243
|
+
:splunk_output_write_bytes_count, docstring:
|
244
|
+
'The number of log bytes being sent',
|
245
|
+
labels: metric_label_keys
|
240
246
|
)),
|
241
247
|
status_counter: register_metric(::Prometheus::Client::Counter.new(
|
242
|
-
:splunk_output_write_status_count,
|
243
|
-
'The count of sends by response_code'
|
248
|
+
:splunk_output_write_status_count, docstring:
|
249
|
+
'The count of sends by response_code',
|
250
|
+
labels: metric_label_keys(status: "")
|
244
251
|
)),
|
245
252
|
write_bytes_histogram: register_metric(::Prometheus::Client::Histogram.new(
|
246
|
-
:splunk_output_write_payload_bytes,
|
247
|
-
'The size of the write payload in bytes',
|
253
|
+
:splunk_output_write_payload_bytes, docstring:
|
254
|
+
'The size of the write payload in bytes', buckets: [1024, 23_937, 47_875, 95_750, 191_500, 383_000, 766_000, 1_149_000],
|
255
|
+
labels: metric_label_keys
|
248
256
|
)),
|
249
257
|
write_records_histogram: register_metric(::Prometheus::Client::Histogram.new(
|
250
|
-
:splunk_output_write_payload_records,
|
251
|
-
'The number of records written per write',
|
258
|
+
:splunk_output_write_payload_records, docstring:
|
259
|
+
'The number of records written per write', buckets: [1, 10, 25, 100, 200, 300, 500, 750, 1000, 1500],
|
260
|
+
labels: metric_label_keys
|
252
261
|
)),
|
253
262
|
write_latency_histogram: register_metric(::Prometheus::Client::Histogram.new(
|
254
|
-
:splunk_output_write_latency_seconds,
|
255
|
-
'The latency of writes'
|
263
|
+
:splunk_output_write_latency_seconds, docstring:
|
264
|
+
'The latency of writes',
|
265
|
+
labels: metric_label_keys
|
256
266
|
))
|
257
267
|
}
|
258
268
|
end
|
@@ -262,6 +272,10 @@ module Fluent::Plugin
|
|
262
272
|
@metric_labels.merge other_labels
|
263
273
|
end
|
264
274
|
|
275
|
+
def metric_label_keys(other_labels = {})
|
276
|
+
(@metric_labels.merge other_labels).keys
|
277
|
+
end
|
278
|
+
|
265
279
|
# Encode as UTF-8. If 'coerce_to_utf8' is set to true in the config, any
|
266
280
|
# non-UTF-8 character would be replaced by the string specified by
|
267
281
|
# 'non_utf8_replacement_string'. If 'coerce_to_utf8' is set to false, any
|
@@ -63,6 +63,9 @@ module Fluent::Plugin
|
|
63
63
|
desc 'List of SSL ciphers allowed.'
|
64
64
|
config_param :ssl_ciphers, :array, default: nil
|
65
65
|
|
66
|
+
desc 'When set to true, TLS version 1.1 and above is required.'
|
67
|
+
config_param :require_ssl_min_version, :bool, default: true
|
68
|
+
|
66
69
|
desc 'Indicates if insecure SSL connection is allowed.'
|
67
70
|
config_param :insecure_ssl, :bool, default: false
|
68
71
|
|
@@ -97,7 +100,10 @@ module Fluent::Plugin
|
|
97
100
|
config_section :fields, init: false, multi: false, required: false do
|
98
101
|
# this is blank on purpose
|
99
102
|
end
|
100
|
-
|
103
|
+
|
104
|
+
desc 'Indicates if 4xx errors should consume chunk'
|
105
|
+
config_param :consume_chunk_on_4xx_errors, :bool, :default => true
|
106
|
+
|
101
107
|
config_section :format do
|
102
108
|
config_set_default :usage, '**'
|
103
109
|
config_set_default :@type, 'json'
|
@@ -140,6 +146,8 @@ module Fluent::Plugin
|
|
140
146
|
c.ca_file = @ca_file
|
141
147
|
c.ca_path = @ca_path
|
142
148
|
c.ciphers = @ssl_ciphers
|
149
|
+
c.proxy = :ENV
|
150
|
+
c.min_version = OpenSSL::SSL::TLS1_1_VERSION if @require_ssl_min_version
|
143
151
|
|
144
152
|
c.override_headers['Content-Type'] = 'application/json'
|
145
153
|
c.override_headers['User-Agent'] = "fluent-plugin-splunk_hec_out/#{VERSION}"
|
@@ -179,7 +187,7 @@ module Fluent::Plugin
|
|
179
187
|
end
|
180
188
|
|
181
189
|
def format_event(tag, time, record)
|
182
|
-
|
190
|
+
d = {
|
183
191
|
host: @host ? @host.(tag, record) : @default_host,
|
184
192
|
# From the API reference
|
185
193
|
# http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector
|
@@ -212,7 +220,12 @@ module Fluent::Plugin
|
|
212
220
|
record = formatter.format(tag, time, record)
|
213
221
|
end
|
214
222
|
payload[:event] = convert_to_utf8 record
|
215
|
-
}
|
223
|
+
}
|
224
|
+
if d[:event] == "{}"
|
225
|
+
log.warn { "Event after formatting was blank, not sending" }
|
226
|
+
return ""
|
227
|
+
end
|
228
|
+
MultiJson.dump(d)
|
216
229
|
end
|
217
230
|
|
218
231
|
def format_metric(tag, time, record)
|
@@ -224,7 +237,7 @@ module Fluent::Plugin
|
|
224
237
|
# That's why we use `to_s` here.
|
225
238
|
time: time.to_f.to_s,
|
226
239
|
event: 'metric'
|
227
|
-
}.tap do |payload|
|
240
|
+
}.tap do |payload|
|
228
241
|
if @time
|
229
242
|
time_value = @time.(tag, record)
|
230
243
|
# if no value is found don't override and use fluentd's time
|
@@ -279,9 +292,11 @@ module Fluent::Plugin
|
|
279
292
|
c.ca_file = @ca_file
|
280
293
|
c.ca_path = @ca_path
|
281
294
|
c.ciphers = @ssl_ciphers
|
295
|
+
c.proxy = :ENV
|
282
296
|
c.idle_timeout = @idle_timeout
|
283
297
|
c.read_timeout = @read_timeout
|
284
298
|
c.open_timeout = @open_timeout
|
299
|
+
c.min_version = OpenSSL::SSL::TLS1_1_VERSION if @require_ssl_min_version
|
285
300
|
|
286
301
|
c.override_headers['Content-Type'] = 'application/json'
|
287
302
|
c.override_headers['User-Agent'] = "fluent-plugin-splunk_hec_out/#{VERSION}"
|
@@ -302,11 +317,12 @@ module Fluent::Plugin
|
|
302
317
|
response = @conn.request @api, post
|
303
318
|
t2 = Time.now
|
304
319
|
|
305
|
-
|
306
|
-
|
320
|
+
raise_err = response.code.to_s.start_with?('5') || (!@consume_chunk_on_4xx_errors && response.code.to_s.start_with?('4'))
|
321
|
+
|
322
|
+
# raise Exception to utilize Fluentd output plugin retry mechanism
|
323
|
+
raise "Server error (#{response.code}) for POST #{@api}, response: #{response.body}" if raise_err
|
307
324
|
|
308
|
-
# For both success response (2xx)
|
309
|
-
# Because there probably a bug in the code if we get 4xx errors, retry won't do any good.
|
325
|
+
# For both success response (2xx) we will consume the chunk.
|
310
326
|
if not response.code.start_with?('2')
|
311
327
|
log.error "Failed POST to #{@api}, response: #{response.body}"
|
312
328
|
log.debug { "Failed request body: #{post.body}" }
|
@@ -340,7 +356,7 @@ module Fluent::Plugin
|
|
340
356
|
invalid: :replace,
|
341
357
|
undef: :replace,
|
342
358
|
replace: @non_utf8_replacement_string)
|
343
|
-
|
359
|
+
else
|
344
360
|
begin
|
345
361
|
input.encode('utf-8')
|
346
362
|
rescue EncodingError
|
@@ -57,6 +57,9 @@ describe Fluent::Plugin::SplunkHecOutput do
|
|
57
57
|
assert_nil(create_hec_output_driver('hec_host hec_token').instance.index_key)
|
58
58
|
expect(create_hec_output_driver('hec_host hec_token').instance.index_key).is_a? String
|
59
59
|
end
|
60
|
+
it 'should consume chunks on 4xx errors' do
|
61
|
+
expect(create_hec_output_driver('hec_host hec_token').instance.consume_chunk_on_4xx_errors).must_equal true
|
62
|
+
end
|
60
63
|
end
|
61
64
|
|
62
65
|
describe 'hec_host validation' do
|
@@ -139,6 +142,7 @@ describe Fluent::Plugin::SplunkHecOutput do
|
|
139
142
|
host_key from
|
140
143
|
source_key file
|
141
144
|
sourcetype_key agent.name
|
145
|
+
time_key timestamp
|
142
146
|
CONF
|
143
147
|
batch.each do |item|
|
144
148
|
expect(item['index']).must_equal 'info'
|
@@ -147,7 +151,7 @@ describe Fluent::Plugin::SplunkHecOutput do
|
|
147
151
|
expect(item['sourcetype']).must_equal 'test'
|
148
152
|
|
149
153
|
JSON.load(item['event']).tap do |event|
|
150
|
-
%w[level from file].each { |field| expect(event).wont_include field }
|
154
|
+
%w[level from file timestamp].each { |field| expect(event).wont_include field }
|
151
155
|
expect(event['agent']).wont_include 'name'
|
152
156
|
end
|
153
157
|
end
|
@@ -220,6 +224,24 @@ describe Fluent::Plugin::SplunkHecOutput do
|
|
220
224
|
end
|
221
225
|
end
|
222
226
|
|
227
|
+
it 'should not send blank events' do
|
228
|
+
verify_sent_events(<<~CONF) do |batch|
|
229
|
+
<fields>
|
230
|
+
from
|
231
|
+
logLevel level
|
232
|
+
nonexist
|
233
|
+
log
|
234
|
+
file
|
235
|
+
value
|
236
|
+
id
|
237
|
+
agent
|
238
|
+
timestamp
|
239
|
+
</fields>
|
240
|
+
CONF
|
241
|
+
expect(batch.length).must_equal 0
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
223
245
|
describe 'metric' do
|
224
246
|
it 'should check related configs' do
|
225
247
|
expect(
|
@@ -349,7 +371,8 @@ describe Fluent::Plugin::SplunkHecOutput do
|
|
349
371
|
'agent' => {
|
350
372
|
'name' => 'test',
|
351
373
|
'version' => '1.0.0'
|
352
|
-
}
|
374
|
+
},
|
375
|
+
'timestamp' => 'time'
|
353
376
|
}
|
354
377
|
events = [
|
355
378
|
['tag.event1', event_time, { 'id' => '1st' }.merge(Marshal.load(Marshal.dump(event)))],
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fluent-plugin-splunk-hec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Splunk Inc.
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fluentd
|
@@ -70,16 +70,16 @@ dependencies:
|
|
70
70
|
name: prometheus-client
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- - "
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 2.1.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- - "
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 2.1.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: bundler
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,20 +122,6 @@ dependencies:
|
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '5.0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rubocop
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: 0.63.1
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: 0.63.1
|
139
125
|
- !ruby/object:Gem::Dependency
|
140
126
|
name: simplecov
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -230,18 +216,18 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
230
216
|
- !ruby/object:Gem::Version
|
231
217
|
version: '0'
|
232
218
|
requirements: []
|
233
|
-
rubygems_version: 3.
|
219
|
+
rubygems_version: 3.1.4
|
234
220
|
signing_key:
|
235
221
|
specification_version: 4
|
236
222
|
summary: Fluentd plugin for Splunk HEC.
|
237
223
|
test_files:
|
224
|
+
- test/test_helper.rb
|
238
225
|
- test/fluent/plugin/out_splunk_hec_test.rb
|
239
226
|
- test/fluent/plugin/out_splunk_ingest_api_test.rb
|
240
|
-
- test/lib/webmock/http_lib_adapters/patron_adapter.rb
|
241
|
-
- test/lib/webmock/http_lib_adapters/manticore_adapter.rb
|
242
|
-
- test/lib/webmock/http_lib_adapters/em_http_request_adapter.rb
|
243
|
-
- test/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
|
244
227
|
- test/lib/webmock/http_lib_adapters/curb_adapter.rb
|
228
|
+
- test/lib/webmock/http_lib_adapters/em_http_request_adapter.rb
|
245
229
|
- test/lib/webmock/http_lib_adapters/http_rb_adapter.rb
|
230
|
+
- test/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
|
231
|
+
- test/lib/webmock/http_lib_adapters/manticore_adapter.rb
|
246
232
|
- test/lib/webmock/http_lib_adapters/excon_adapter.rb
|
247
|
-
- test/
|
233
|
+
- test/lib/webmock/http_lib_adapters/patron_adapter.rb
|