fluent-plugin-splunk-hec 1.1.2 → 1.2.4

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.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  Fluent::Plugin::SplunkHecOutput::VERSION = File.read(
2
4
  File.expand_path('../../../../VERSION', File.dirname(__FILE__))
3
5
  ).chomp.strip
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+ $LOAD_PATH.unshift(File.expand_path('..', __dir__))
3
+ require 'fluent/plugin/out_splunk'
4
+ require 'openid_connect'
5
+ require 'rack/oauth2'
6
+ require 'multi_json'
7
+
8
+ module Fluent::Plugin
9
+ class SplunkIngestApiOutput < SplunkOutput
10
+ Fluent::Plugin.register_output('splunk_ingest_api', self)
11
+
12
+ desc 'Service Client Identifier'
13
+ config_param :service_client_identifier, :string, default: nil
14
+
15
+ desc 'Service Client Secret Key'
16
+ config_param :service_client_secret_key, :string, default: nil
17
+
18
+ desc 'Token Endpoint'
19
+ config_param :token_endpoint, :string, default: '/token'
20
+
21
+ desc 'Token Auth Hostname'
22
+ config_param :ingest_auth_host, :string, default: 'auth.scp.splunk.com'
23
+
24
+ desc 'Ingest Api Hostname'
25
+ config_param :ingest_api_host, :string, default: 'api.scp.splunk.com'
26
+
27
+ desc 'Ingest API Tenant Name'
28
+ config_param :ingest_api_tenant, :string
29
+
30
+ desc 'Ingest API Events Endpoint'
31
+ config_param :ingest_api_events_endpoint, :string, default: '/ingest/v1beta2/events'
32
+
33
+ desc 'Debug the HTTP transport'
34
+ config_param :debug_http, :bool, default: false
35
+
36
+ def prefer_buffer_processing
37
+ true
38
+ end
39
+
40
+ def configure(conf)
41
+ super
42
+ end
43
+
44
+ def construct_api
45
+ uri = "https://#{@ingest_api_host}/#{@ingest_api_tenant}#{@ingest_api_events_endpoint}"
46
+ URI(uri)
47
+ rescue StandardError
48
+ raise Fluent::ConfigError, "URI #{uri} is invalid"
49
+ end
50
+
51
+ def format(tag, time, record)
52
+ format_event(tag, time, record)
53
+ end
54
+
55
+ def format_event(tag, time, record)
56
+ event = prepare_event_payload(tag, time, record)
57
+ # Unsure how to drop a record. So append the empty string
58
+ if event[:body].nil? || event[:body].strip.empty?
59
+ ''
60
+ else
61
+ MultiJson.dump(event) + ','
62
+ end
63
+ end
64
+
65
+ def prepare_event_payload(tag, time, record)
66
+ payload = super(tag, time, record)
67
+ payload[:attributes] = payload.delete(:fields) || {}
68
+ payload[:attributes][:index] = payload.delete(:index) if payload[:index]
69
+ payload[:body] = payload.delete(:event)
70
+ payload.delete(:time)
71
+ payload[:timestamp] = (time.to_f * 1000).to_i
72
+ payload[:nanos] = time.nsec / 100_000
73
+
74
+ payload
75
+ end
76
+
77
+ def process_response(response, request_body)
78
+ super
79
+ if response.code.to_s == '401'
80
+ @conn = new_connection
81
+ raise 'Auth Error recived. New token has been fetched.'
82
+ elsif response.code.to_s == '429'
83
+ raise "Throttle error from server. #{response.body}"
84
+ elsif /INVALID_DATA/.match?(response.body)
85
+ log.error "#{self.class}: POST Body #{request_body}"
86
+ end
87
+ end
88
+
89
+ def new_connection
90
+ Rack::OAuth2.debugging = true if @debug_http
91
+ client = OpenIDConnect::Client.new(
92
+ token_endpoint: @token_endpoint,
93
+ identifier: @service_client_identifier,
94
+ secret: @service_client_secret_key,
95
+ redirect_uri: 'http://localhost:8080/', # Not used
96
+ host: @ingest_auth_host,
97
+ scheme: 'https'
98
+ )
99
+
100
+ client.access_token!(client_auth_method: 'other')
101
+ end
102
+
103
+ def write_to_splunk(chunk)
104
+ log.trace "#{self.class}: In write() with #{chunk.size_of_events} records and #{chunk.bytesize} bytes "
105
+ # ingest API is an array of json objects
106
+ body = "[#{chunk.read.chomp(',')}]"
107
+ @conn ||= new_connection
108
+ response = @conn.post("https://#{@ingest_api_host}/#{@ingest_api_tenant}#{@ingest_api_events_endpoint}", body: body)
109
+ process_response(response, body)
110
+ end
111
+ end
112
+ end
@@ -1,334 +1,336 @@
1
- require "test_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
2
4
 
3
5
  describe Fluent::Plugin::SplunkHecOutput do
4
6
  include Fluent::Test::Helpers
5
7
  include PluginTestHelper
6
8
 
7
9
  before { Fluent::Test.setup } # setup router and others
8
-
10
+
9
11
  it { expect(::Fluent::Plugin::SplunkHecOutput::VERSION).wont_be_nil }
10
12
 
11
- describe "config param tests" do
12
- it "should require https protocol" do
13
- expect(create_output_driver('hec_host protocol').instance.protocol).must_equal :https
14
- end
15
- it "should require hec_host" do
16
- expect(create_output_driver('hec_host hec_host').instance.hec_host).must_equal "hec_host"
17
- end
18
- it "should require hec_port" do
19
- expect(create_output_driver('hec_host hec_port').instance.hec_port).must_equal 8088
20
- end
21
- it "should require hec_token" do
22
- expect(create_output_driver('hec_host hec_token').instance.hec_token).must_equal "some-token"
23
- end
24
- it "should define client_cert as nil initially" do
25
- assert_nil(create_output_driver('hec_host hec_token').instance.client_cert)
26
- end
27
- it "should define client_key as nil (string) initially" do
28
- assert_nil(create_output_driver('hec_host hec_token').instance.client_key)
29
- expect(create_output_driver('hec_host hec_token').instance.client_key).is_a? String
30
- end
31
- it "should define ca_file as nil (string) initially" do
32
- assert_nil(create_output_driver('hec_host hec_token').instance.ca_file)
33
- expect(create_output_driver('hec_host hec_token').instance.ca_file).is_a? String
34
- end
35
- it "should define ca_path as nil (string) initially" do
36
- assert_nil(create_output_driver('hec_host hec_token').instance.ca_path)
37
- expect(create_output_driver('hec_host hec_token').instance.ca_path).is_a? String
38
- end
39
- it "should define ssl_ciphers as nil (array) initially" do
40
- assert_nil(create_output_driver('hec_host hec_token').instance.ssl_ciphers)
41
- expect(create_output_driver('hec_host hec_token').instance.ssl_ciphers).is_a? Array
42
- end
43
- it "should not allow an insecure ssl connection" do
44
- expect(create_output_driver('hec_host hec_token').instance.insecure_ssl).must_equal false
45
- end
46
- it "should allow both event (default) and metric to be sent to splunk" do
47
- expect(create_output_driver('hec_host hec_token').instance.data_type).must_equal :event
48
- expect(create_output_driver('hec_host hec_token').instance.data_type = :metric).must_equal :metric
49
- end
50
- it "should define Splunk index to index (string) as nil initially" do
51
- assert_nil(create_output_driver('hec_host hec_token').instance.index)
52
- expect(create_output_driver('hec_host hec_token').instance.index).is_a? String
53
- end
54
- it "should define field names to include Splunk index_key as nil (string) initially" do
55
- assert_nil(create_output_driver('hec_host hec_token').instance.index_key)
56
- expect(create_output_driver('hec_host hec_token').instance.index_key).is_a? String
57
- end
13
+ describe 'config param tests' do
14
+ it 'should require https protocol' do
15
+ expect(create_hec_output_driver('hec_host protocol').instance.protocol).must_equal :https
16
+ end
17
+ it 'should require hec_host' do
18
+ expect(create_hec_output_driver('hec_host hec_host').instance.hec_host).must_equal 'hec_host'
19
+ end
20
+ it 'should require hec_port' do
21
+ expect(create_hec_output_driver('hec_host hec_port').instance.hec_port).must_equal 8088
22
+ end
23
+ it 'should require hec_token' do
24
+ expect(create_hec_output_driver('hec_host hec_token').instance.hec_token).must_equal 'some-token'
25
+ end
26
+ it 'should define client_cert as nil initially' do
27
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.client_cert)
28
+ end
29
+ it 'should define client_key as nil (string) initially' do
30
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.client_key)
31
+ expect(create_hec_output_driver('hec_host hec_token').instance.client_key).is_a? String
32
+ end
33
+ it 'should define ca_file as nil (string) initially' do
34
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.ca_file)
35
+ expect(create_hec_output_driver('hec_host hec_token').instance.ca_file).is_a? String
36
+ end
37
+ it 'should define ca_path as nil (string) initially' do
38
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.ca_path)
39
+ expect(create_hec_output_driver('hec_host hec_token').instance.ca_path).is_a? String
40
+ end
41
+ it 'should define ssl_ciphers as nil (array) initially' do
42
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.ssl_ciphers)
43
+ expect(create_hec_output_driver('hec_host hec_token').instance.ssl_ciphers).is_a? Array
44
+ end
45
+ it 'should not allow an insecure ssl connection' do
46
+ expect(create_hec_output_driver('hec_host hec_token').instance.insecure_ssl).must_equal false
47
+ end
48
+ it 'should allow both event (default) and metric to be sent to splunk' do
49
+ expect(create_hec_output_driver('hec_host hec_token').instance.data_type).must_equal :event
50
+ expect(create_hec_output_driver('hec_host hec_token').instance.data_type = :metric).must_equal :metric
51
+ end
52
+ it 'should define Splunk index to index (string) as nil initially' do
53
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.index)
54
+ expect(create_hec_output_driver('hec_host hec_token').instance.index).is_a? String
55
+ end
56
+ it 'should define field names to include Splunk index_key as nil (string) initially' do
57
+ assert_nil(create_hec_output_driver('hec_host hec_token').instance.index_key)
58
+ expect(create_hec_output_driver('hec_host hec_token').instance.index_key).is_a? String
59
+ end
58
60
  end
59
61
 
60
- describe "hec_host validation" do
61
- describe "invalid host" do
62
- it "should require hec_host" do
63
- expect{ create_output_driver }.must_raise Fluent::ConfigError
62
+ describe 'hec_host validation' do
63
+ describe 'invalid host' do
64
+ it 'should require hec_host' do
65
+ expect { create_hec_output_driver }.must_raise Fluent::ConfigError
64
66
  end
65
67
 
66
- it { expect{ create_output_driver('hec_host %bad-host%') }.must_raise Fluent::ConfigError }
68
+ it { expect { create_hec_output_driver('hec_host %bad-host%') }.must_raise Fluent::ConfigError }
67
69
  end
68
70
 
69
- describe "good host" do
71
+ describe 'good host' do
70
72
  it {
71
- expect(create_output_driver('hec_host splunk.com').instance.hec_host).must_equal "splunk.com"
73
+ expect(create_hec_output_driver('hec_host splunk.com').instance.hec_host).must_equal 'splunk.com'
72
74
  }
73
75
  end
74
76
  end
75
77
 
76
- it "should send request to Splunk" do
77
- req = verify_sent_events { |batch|
78
+ it 'should send request to Splunk' do
79
+ req = verify_sent_events do |batch|
78
80
  expect(batch.size).must_equal 2
79
- }
81
+ end
80
82
  expect(req).must_be_requested times: 1
81
83
  end
82
84
 
83
- it "should use string for event time, and the value of the string should be a float" do
84
- verify_sent_events { |batch|
85
+ it 'should use string for event time, and the value of the string should be a float' do
86
+ verify_sent_events do |batch|
85
87
  batch.each do |item|
86
88
  expect(item['time']).must_be_instance_of String
87
89
  expect(item['time']).must_match /^\d+\.\d+$/
88
90
  end
89
- }
91
+ end
90
92
  end
91
93
 
92
94
  # it "should contain splunk event time field via fluentd, as nil" do
93
- # expect(create_output_driver('hec_host splunk.com').instance.time_key).must_equal nil
95
+ # expect(create_hec_output_driver('hec_host splunk.com').instance.time_key).must_equal nil
94
96
  # end
95
97
  #
96
- it "should contain splunk event time field via fluentd, as nil" do
97
- test_driver = create_output_driver('hec_host splunk.com')
98
- assert_nil(test_driver.instance.time_key)
98
+ it 'should contain splunk event time field via fluentd, as nil' do
99
+ test_driver = create_hec_output_driver('hec_host splunk.com')
100
+ assert_nil(test_driver.instance.time_key)
99
101
  end
100
102
 
101
103
  it "should use host machine's hostname for event host by default" do
102
- verify_sent_events { |batch|
104
+ verify_sent_events do |batch|
103
105
  batch.each do |item|
104
- expect(item['host']).must_equal Socket.gethostname
106
+ expect(item['host']).must_equal Socket.gethostname
105
107
  end
106
- }
108
+ end
107
109
  end
108
110
 
109
111
  %w[index source sourcetype].each do |field|
110
112
  it "should not set #{field} by default" do
111
- verify_sent_events { |batch|
112
- batch.each do |item|
113
- expect(item).wont_include field
114
- end
115
- }
113
+ verify_sent_events do |batch|
114
+ batch.each do |item|
115
+ expect(item).wont_include field
116
+ end
117
+ end
116
118
  end
117
119
  end
118
120
 
119
- it "should support ${tag}" do
120
- verify_sent_events(<<~CONF) { |batch|
121
- index ${tag}
122
- host ${tag}
123
- source ${tag}
124
- sourcetype ${tag}
121
+ it 'should support ${tag}' do
122
+ verify_sent_events(<<~CONF) do |batch|
123
+ index ${tag}
124
+ host ${tag}
125
+ source ${tag}
126
+ sourcetype ${tag}
125
127
  CONF
126
128
  batch.each do |item|
127
- %w[index host source sourcetype].each { |field|
128
- expect(%w[tag.event1 tag.event2]).must_include item[field]
129
- }
129
+ %w[index host source sourcetype].each do |field|
130
+ expect(%w[tag.event1 tag.event2]).must_include item[field]
131
+ end
130
132
  end
131
- }
133
+ end
132
134
  end
133
135
 
134
- it "should support *_key" do
135
- verify_sent_events(<<~CONF) { |batch|
136
+ it 'should support *_key' do
137
+ verify_sent_events(<<~CONF) do |batch|
136
138
  index_key level
137
139
  host_key from
138
140
  source_key file
139
141
  sourcetype_key agent.name
140
142
  CONF
141
- batch.each { |item|
143
+ batch.each do |item|
142
144
  expect(item['index']).must_equal 'info'
143
145
  expect(item['host']).must_equal 'my_machine'
144
146
  expect(item['source']).must_equal 'cool.log'
145
147
  expect(item['sourcetype']).must_equal 'test'
146
148
 
147
- JSON.load(item['event']).tap do |event|
148
- %w[level from file].each { |field| expect(event).wont_include field }
149
- expect(event['agent']).wont_include 'name'
150
- end
151
- }
152
- }
149
+ JSON.load(item['event']).tap do |event|
150
+ %w[level from file].each { |field| expect(event).wont_include field }
151
+ expect(event['agent']).wont_include 'name'
152
+ end
153
+ end
154
+ end
153
155
  end
154
156
 
155
- it "should remove nil fields." do
156
- verify_sent_events(<<~CONF) { |batch|
157
+ it 'should remove nil fileds.' do
158
+ verify_sent_events(<<~CONF) do |batch|
157
159
  index_key nonexist
158
160
  host_key nonexist
159
161
  source_key nonexist
160
162
  sourcetype_key nonexist
161
163
  CONF
162
- batch.each { |item|
163
- expect(item).wont_be :has_key?, 'index'
164
- expect(item).wont_be :has_key?, 'host'
165
- expect(item).wont_be :has_key?, 'source'
166
- expect(item).wont_be :has_key?, 'sourcetype'
167
- }
168
- }
164
+ batch.each do |item|
165
+ expect(item).wont_be :has_key?, 'index'
166
+ expect(item).wont_be :has_key?, 'host'
167
+ expect(item).wont_be :has_key?, 'source'
168
+ expect(item).wont_be :has_key?, 'sourcetype'
169
+ end
170
+ end
169
171
  end
170
172
 
171
173
  describe 'formatter' do
172
- it "should support replace the default json formatter" do
173
- verify_sent_events(<<~CONF) { |batch|
174
- <format>
175
- @type single_value
176
- message_key log
177
- add_newline false
178
- </format>
174
+ it 'should support replace the default json formater' do
175
+ verify_sent_events(<<~CONF) do |batch|
176
+ <format>
177
+ @type single_value
178
+ message_key log
179
+ add_newline false
180
+ </format>
179
181
  CONF
180
- batch.map { |item| item['event'] }
181
- .each { |event| expect(event).must_equal "everything is good" }
182
- }
182
+ batch.map { |item| item['event'] }
183
+ .each { |event| expect(event).must_equal 'everything is good' }
184
+ end
183
185
  end
184
186
 
185
- it "should support multiple formatters" do
186
- verify_sent_events(<<~CONF) { |batch|
187
- source ${tag}
188
- <format tag.event1>
189
- @type single_value
190
- message_key log
191
- add_newline false
192
- </format>
187
+ it 'should support multiple formatters' do
188
+ verify_sent_events(<<~CONF) do |batch|
189
+ source ${tag}
190
+ <format tag.event1>
191
+ @type single_value
192
+ message_key log
193
+ add_newline false
194
+ </format>
193
195
  CONF
194
- expect(batch.find { |item| item['source'] == 'tag.event1' }['event']).must_equal "everything is good"
195
- expect(batch.find { |item| item['source'] == 'tag.event2' }['event']).must_be_instance_of Hash
196
- }
196
+ expect(batch.find { |item| item['source'] == 'tag.event1' }['event']).must_equal 'everything is good'
197
+ expect(batch.find { |item| item['source'] == 'tag.event2' }['event']).must_be_instance_of Hash
198
+ end
197
199
  end
198
200
  end
199
201
 
200
- it "should support fields for indexed field extraction" do
201
- verify_sent_events(<<~CONF) { |batch|
202
- <fields>
203
- from
204
- logLevel level
205
- nonexist
206
- </fields>
202
+ it 'should support fields for indexed field extraction' do
203
+ verify_sent_events(<<~CONF) do |batch|
204
+ <fields>
205
+ from
206
+ logLevel level
207
+ nonexist
208
+ </fields>
207
209
  CONF
208
210
  batch.each do |item|
209
- JSON.load(item['event']).tap { |event|
210
- expect(event).wont_include 'from'
211
- expect(event).wont_include 'level'
212
- }
213
-
214
- expect(item['fields']['from']).must_equal 'my_machine'
215
- expect(item['fields']['logLevel']).must_equal 'info'
216
- expect(item['fields']).wont_be :has_key?, 'nonexist'
211
+ JSON.load(item['event']).tap do |event|
212
+ expect(event).wont_include 'from'
213
+ expect(event).wont_include 'level'
214
+ end
215
+
216
+ expect(item['fields']['from']).must_equal 'my_machine'
217
+ expect(item['fields']['logLevel']).must_equal 'info'
218
+ expect(item['fields']).wont_be :has_key?, 'nonexist'
217
219
  end
218
- }
220
+ end
219
221
  end
220
222
 
221
- describe 'metric'do
223
+ describe 'metric' do
222
224
  it 'should check related configs' do
223
225
  expect(
224
- create_output_driver('hec_host somehost', 'data_type metric')
226
+ create_hec_output_driver('hec_host somehost', 'data_type metric')
225
227
  ).wont_be_nil
226
228
 
227
- expect{
228
- create_output_driver('hec_host somehost', 'data_type metric', 'metrics_from_event false')
229
- }.must_raise Fluent::ConfigError
229
+ expect do
230
+ create_hec_output_driver('hec_host somehost', 'data_type metric', 'metrics_from_event false')
231
+ end.must_raise Fluent::ConfigError
230
232
 
231
- expect{
232
- create_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x')
233
- }.must_raise Fluent::ConfigError
233
+ expect do
234
+ create_hec_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x')
235
+ end.must_raise Fluent::ConfigError
234
236
 
235
237
  expect(
236
- create_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x', 'metric_value_key y')
238
+ create_hec_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x', 'metric_value_key y')
237
239
  ).wont_be_nil
238
240
  end
239
241
 
240
242
  it 'should have "metric" as event, and have proper fields' do
241
- verify_sent_events(<<~CONF) { |batch|
242
- data_type metric
243
- metric_name_key from
244
- metric_value_key value
243
+ verify_sent_events(<<~CONF) do |batch|
244
+ data_type metric
245
+ metric_name_key from
246
+ metric_value_key value
245
247
  CONF
246
- batch.each do |item|
247
- expect(item['event']).must_equal 'metric'
248
- expect(item['fields']['metric_name']).must_equal 'my_machine'
249
- expect(item['fields']['_value']).must_equal 100
250
- expect(item['fields']['log']).must_equal 'everything is good'
251
- expect(item['fields']['level']).must_equal 'info'
252
- expect(item['fields']['file']).must_equal 'cool.log'
253
- end
254
- }
248
+ batch.each do |item|
249
+ expect(item['event']).must_equal 'metric'
250
+ expect(item['fields']['metric_name']).must_equal 'my_machine'
251
+ expect(item['fields']['_value']).must_equal 100
252
+ expect(item['fields']['log']).must_equal 'everything is good'
253
+ expect(item['fields']['level']).must_equal 'info'
254
+ expect(item['fields']['file']).must_equal 'cool.log'
255
+ end
256
+ end
255
257
  end
256
258
 
257
259
  it 'should handle empty fields' do
258
- verify_sent_events(<<~CONF) { |batch|
259
- data_type metric
260
- metric_name_key from
261
- metric_value_key value
262
- <fields>
263
- </fields>
260
+ verify_sent_events(<<~CONF) do |batch|
261
+ data_type metric
262
+ metric_name_key from
263
+ metric_value_key value
264
+ <fields>
265
+ </fields>
264
266
  CONF
265
- batch.each do |item|
266
- # only "metric_name" and "_value"
267
- expect(item['fields'].keys.size).must_equal 2
268
- end
269
- }
267
+ batch.each do |item|
268
+ # only "metric_name" and "_value"
269
+ expect(item['fields'].keys.size).must_equal 2
270
+ end
271
+ end
270
272
  end
271
273
 
272
274
  it 'should handle custom fields' do
273
- verify_sent_events(<<~CONF) { |batch|
274
- data_type metric
275
- metric_name_key from
276
- metric_value_key value
277
- <fields>
278
- level
279
- filePath file
280
- username
281
- </fields>
275
+ verify_sent_events(<<~CONF) do |batch|
276
+ data_type metric
277
+ metric_name_key from
278
+ metric_value_key value
279
+ <fields>
280
+ level
281
+ filePath file
282
+ username
283
+ </fields>
282
284
  CONF
283
- batch.each do |item|
284
- expect(item['fields'].keys.size).must_equal 4
285
- expect(item['fields']['level']).must_equal 'info'
286
- expect(item['fields']['filePath']).must_equal 'cool.log'
287
- # null fields should be removed
288
- expect(item['fields']).wont_be :has_key?, 'username'
289
- end
290
- }
285
+ batch.each do |item|
286
+ expect(item['fields'].keys.size).must_equal 4
287
+ expect(item['fields']['level']).must_equal 'info'
288
+ expect(item['fields']['filePath']).must_equal 'cool.log'
289
+ # null fields should be removed
290
+ expect(item['fields']).wont_be :has_key?, 'username'
291
+ end
292
+ end
291
293
  end
292
294
 
293
295
  it 'should treat each key-value in event as a metric' do
294
296
  metrics = [
295
- ['tag', event_time, {'cup': 0.5, 'memory': 100}],
296
- ['tag', event_time, {'cup': 0.6, 'memory': 200}]
297
+ ['tag', event_time, { 'cup': 0.5, 'memory': 100 }],
298
+ ['tag', event_time, { 'cup': 0.6, 'memory': 200 }]
297
299
  ]
298
- with_stub_hec(events: metrics, conf: 'data_type metric') { |batch|
299
- expect(batch.size).must_equal 4
300
- }
300
+ with_stub_hec(events: metrics, conf: 'data_type metric') do |batch|
301
+ expect(batch.size).must_equal 4
302
+ end
301
303
  end
302
304
  end
303
305
 
304
306
  describe 'timeout params' do
305
- it 'should reset unused connection after 5 seconds' do
306
- expect(create_output_driver('hec_host splunk.com', 'idle_timeout 5').instance.idle_timeout).must_equal 5
307
- end
307
+ it 'should reset unused connection after 5 seconds' do
308
+ expect(create_hec_output_driver('hec_host splunk.com', 'idle_timeout 5').instance.idle_timeout).must_equal 5
309
+ end
308
310
 
309
- it 'should allow custom setting between reading chunks from the socket' do
310
- expect(create_output_driver('hec_host splunk.com', 'read_timeout 5').instance.read_timeout).must_equal 5
311
- end
311
+ it 'should allow custom setting between reading chunks from the socket' do
312
+ expect(create_hec_output_driver('hec_host splunk.com', 'read_timeout 5').instance.read_timeout).must_equal 5
313
+ end
312
314
 
313
- it 'should allow custom setting a connection to be opened' do
314
- expect(create_output_driver('hec_host splunk.com', 'open_timeout 5').instance.open_timeout).must_equal 5
315
- end
315
+ it 'should allow custom setting a connection to be opened' do
316
+ expect(create_hec_output_driver('hec_host splunk.com', 'open_timeout 5').instance.open_timeout).must_equal 5
317
+ end
316
318
 
317
- it 'should check default values are created correctly for timeout params' do
318
- test_driver = create_output_driver('hec_host splunk.com')
319
- expect(test_driver.instance.idle_timeout).must_equal 5
320
- assert_nil(test_driver.instance.read_timeout)
321
- assert_nil(test_driver.instance.open_timeout)
322
- end
319
+ it 'should check default values are created correctly for timeout params' do
320
+ test_driver = create_hec_output_driver('hec_host splunk.com')
321
+ expect(test_driver.instance.idle_timeout).must_equal 5
322
+ assert_nil(test_driver.instance.read_timeout)
323
+ assert_nil(test_driver.instance.open_timeout)
323
324
  end
325
+ end
324
326
 
325
- def with_stub_hec(events:, conf: '', &blk)
326
- host = "hec.splunk.com"
327
- @driver = create_output_driver("hec_host #{host}", conf)
327
+ def with_stub_hec(events:, conf: '')
328
+ host = 'hec.splunk.com'
329
+ @driver = create_hec_output_driver("hec_host #{host}", conf)
328
330
 
329
- hec_req = stub_hec_request("https://#{host}:8088").with { |r|
330
- blk.call r.body.split(/(?={)\s*(?<=})/).map { |item| JSON.load item }
331
- }
331
+ hec_req = stub_hec_request("https://#{host}:8088").with do |r|
332
+ yield r.body.split(/(?={)\s*(?<=})/).map { |item| JSON.load item }
333
+ end
332
334
 
333
335
  @driver.run do
334
336
  events.each { |evt| @driver.feed *evt }
@@ -339,19 +341,19 @@ describe Fluent::Plugin::SplunkHecOutput do
339
341
 
340
342
  def verify_sent_events(conf = '', &blk)
341
343
  event = {
342
- "log" => "everything is good",
343
- "level" => "info",
344
- "from" => "my_machine",
345
- "file" => "cool.log",
346
- "value" => 100,
347
- "agent" => {
348
- "name" => "test",
349
- "version" => "1.1.0"
344
+ 'log' => 'everything is good',
345
+ 'level' => 'info',
346
+ 'from' => 'my_machine',
347
+ 'file' => 'cool.log',
348
+ 'value' => 100,
349
+ 'agent' => {
350
+ 'name' => 'test',
351
+ 'version' => '1.0.0'
350
352
  }
351
353
  }
352
354
  events = [
353
- ["tag.event1", event_time, {"id" => "1st"}.merge(Marshal.load(Marshal.dump(event)))],
354
- ["tag.event2", event_time, {"id" => "2nd"}.merge(Marshal.load(Marshal.dump(event)))]
355
+ ['tag.event1', event_time, { 'id' => '1st' }.merge(Marshal.load(Marshal.dump(event)))],
356
+ ['tag.event2', event_time, { 'id' => '2nd' }.merge(Marshal.load(Marshal.dump(event)))]
355
357
  ]
356
358
 
357
359
  with_stub_hec conf: conf, events: events, &blk