fluent-plugin-splunk-hec 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a5e33a0b115b4d515ce94f1bf904bddf192994ff1b54fb624f5ea9d470bb4cd
4
- data.tar.gz: 306d2647c27a63e98d3f530eacf2abd0fd16cd5f7f23213291ff061a11d4fb92
3
+ metadata.gz: 4460c822fc2a85e65234099aca29574dcdc17e4403c3fbc1da7c48d4a5fd9608
4
+ data.tar.gz: 9950c15e61273b9dcd597c8fc3ff83dad5be0f7f741bb67a5b296ccd98c1a366
5
5
  SHA512:
6
- metadata.gz: a813d1d0ef4e157c95c49a0f75641e51af2a18d56c02020ec702a06a4d48fad02cb7e60f044637adfc261d8ec6fce21775ef38aa6215e8dea5cdb850c2faa74c
7
- data.tar.gz: 584ffa55837e358d705780cdd01f86bcd3245fe3ebcc4f3f0f999ae03fa5634443db531cb1a51ac806402399cac7d1f6d9ed43f612b4c331de445a9df6376172
6
+ metadata.gz: 39fcf467dea44451264c3a56e0ab1442b196ab7c424112969e997567174ba9b4e0ce1def62535bb72a5a5af88d45ac16f53273cc590c2c9636d57e927e7b6b2e
7
+ data.tar.gz: d50f4a1df76c1d2661d387cfdedb0e47d4621526b7e94b73a0e06c3965b38c9b53ca87a83f48df60f64da553ec62c1bd9bbae1301b9677f0c7dbd316bbf1fa2f
data/Gemfile CHANGED
@@ -1,6 +1,10 @@
1
- source "https://rubygems.org"
1
+ source 'https://rubygems.org'
2
2
 
3
- git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
3
+ group :test do
4
+ gem 'simplecov', require: false
5
+ end
6
+
7
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
4
8
 
5
9
  # Specify your gem's dependencies in fluent-plugin-splunk_hec_output.gemspec
6
10
  gemspec
@@ -1,22 +1,23 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-splunk-hec (1.0.0)
5
- fluentd (~> 1.0)
4
+ fluent-plugin-splunk-hec (1.1.0)
5
+ fluentd (~> 1.4)
6
6
  multi_json (~> 1.13)
7
7
  net-http-persistent (~> 3.0)
8
8
 
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- addressable (2.5.2)
12
+ addressable (2.6.0)
13
13
  public_suffix (>= 2.0.2, < 4.0)
14
- connection_pool (2.2.1)
14
+ connection_pool (2.2.2)
15
15
  cool.io (1.5.3)
16
16
  crack (0.4.3)
17
17
  safe_yaml (~> 1.0.0)
18
18
  dig_rb (1.0.1)
19
- fluentd (1.1.0)
19
+ docile (1.3.1)
20
+ fluentd (1.4.0)
20
21
  cool.io (>= 1.4.5, < 2.0.0)
21
22
  dig_rb (~> 1.0.0)
22
23
  http_parser.rb (>= 0.5.1, < 0.7.0)
@@ -27,44 +28,51 @@ GEM
27
28
  tzinfo (~> 1.0)
28
29
  tzinfo-data (~> 1.0)
29
30
  yajl-ruby (~> 1.0)
30
- hashdiff (0.3.7)
31
+ hashdiff (0.3.8)
31
32
  http_parser.rb (0.6.0)
33
+ json (2.1.0)
32
34
  minitest (5.11.3)
33
- msgpack (1.2.2)
35
+ msgpack (1.2.7)
34
36
  multi_json (1.13.1)
35
37
  net-http-persistent (3.0.0)
36
38
  connection_pool (~> 2.2)
37
- power_assert (1.1.1)
38
- public_suffix (3.0.2)
39
- rake (10.5.0)
39
+ power_assert (1.1.3)
40
+ public_suffix (3.0.3)
41
+ rake (12.3.2)
40
42
  safe_yaml (1.0.4)
41
- serverengine (2.0.6)
43
+ serverengine (2.1.0)
42
44
  sigdump (~> 0.2.2)
43
45
  sigdump (0.2.4)
46
+ simplecov (0.16.1)
47
+ docile (~> 1.1)
48
+ json (>= 1.8, < 3)
49
+ simplecov-html (~> 0.10.0)
50
+ simplecov-html (0.10.2)
44
51
  strptime (0.2.3)
45
- test-unit (3.2.7)
52
+ test-unit (3.3.0)
46
53
  power_assert
47
54
  thread_safe (0.3.6)
48
55
  tzinfo (1.2.5)
49
56
  thread_safe (~> 0.1)
50
- tzinfo-data (1.2018.3)
57
+ tzinfo-data (1.2018.9)
51
58
  tzinfo (>= 1.0.0)
52
- webmock (3.3.0)
59
+ webmock (3.5.1)
53
60
  addressable (>= 2.3.6)
54
61
  crack (>= 0.3.2)
55
62
  hashdiff
56
- yajl-ruby (1.3.1)
63
+ yajl-ruby (1.4.1)
57
64
 
58
65
  PLATFORMS
59
66
  ruby
60
67
 
61
68
  DEPENDENCIES
62
- bundler (~> 1.16)
69
+ bundler (~> 2.0)
63
70
  fluent-plugin-splunk-hec!
64
71
  minitest (~> 5.0)
65
- rake (~> 10.0)
72
+ rake (~> 12.0)
73
+ simplecov
66
74
  test-unit (~> 3.0)
67
- webmock (~> 3.2)
75
+ webmock (~> 3.5.0)
68
76
 
69
77
  BUNDLED WITH
70
- 1.16.1
78
+ 2.0.1
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- [ ![Codeship Status for splunk/fluent-plugin-splunk-hec](https://app.codeship.com/projects/7905e540-105f-0136-dde3-2adac7655f3e/status?branch=master)](https://app.codeship.com/projects/282733)
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
2
  # fluent-plugin-splunk-hec
3
3
 
4
4
  [Fluentd](https://fluentd.org/) output plugin to send events and metrics to [Splunk](https://www.splunk.com) over the HEC (HTTP Event Collector) API.
@@ -6,11 +6,9 @@
6
6
  ## Installation
7
7
 
8
8
  ### RubyGems
9
-
10
- ```
9
+ ```
11
10
  $ gem install fluent-plugin-splunk-hec
12
11
  ```
13
-
14
12
  ### Bundler
15
13
 
16
14
  Add following line to your Gemfile:
@@ -334,6 +332,22 @@ If you want to use a different default formatter, you can add a `<format **>` (o
334
332
 
335
333
  Defines which formatter to use.
336
334
 
335
+ ### Net::HTTP::Persistent parameters (optional)
336
+
337
+ The following parameters can be used for tuning HTTP connections
338
+
339
+ #### idle_timeout (integer)
340
+
341
+ The default is 5 seconds. If a connection has not been used for this number of seconds it will automatically be reset upon the next use to avoid attempting to send to a closed connection; nil means no timeout.
342
+
343
+ #### read_timeout (integer)
344
+
345
+ The default is nil. The amount of time allowed between reading two chunks from the socket.
346
+
347
+ #### open_timeout (integer)
348
+
349
+ The default is nil. The amount of time to wait for a connection to be opened.
350
+
337
351
  ### SSL parameters
338
352
 
339
353
  There are quite some parameters you can use to configure SSL (for HTTPS protocol).
@@ -372,10 +386,10 @@ It batches all events in a chunk in one request. So you need to configure the `<
372
386
  Here are some hints:
373
387
 
374
388
  * Read through the [fluentd buffer document](https://docs.fluentd.org/v1.0/articles/buffer-section) to understand the buffer configurations.
375
- * Use `chunk_limit_size` and/or `chunk_limit_records` to define how big a chunk can be. And remeber that all events in a chunk will be sent in one request.
389
+ * Use `chunk_limit_size` and/or `chunk_limit_records` to define how big a chunk can be. And remember that all events in a chunk will be sent in one request.
376
390
  * Splunk has a limit on how big the payload of a HEC request can be. And it's defined with `max_content_length` in [the `[http_input]` section of `limits.conf`](https://docs.splunk.com/Documentation/Splunk/latest/Admin/Limitsconf#.5Bhttp_input.5D). In Splunk of version 6.5.0+, the default value is 800MiB, while in versions before 6.5.0, it's just 1MB. Make sure your chunk size won't exceed this limit, or you should change the limit on your Splunk deployment.
377
- * Sending requests to HEC takes time, so if you flush your fluentd buffer too fast (for example, with a very small `flush_interval`), it's possible that the plugin cannot catch up with the buffer flushing. There are two ways you can handle this situdation, one is to increase the `flush_interval` or use multiple flush threads by setting `flush_thread_count` to a number bigger than 1.
391
+ * Sending requests to HEC takes time, so if you flush your fluentd buffer too fast (for example, with a very small `flush_interval`), it's possible that the plugin cannot catch up with the buffer flushing. There are two ways you can handle this situation, one is to increase the `flush_interval` or use multiple flush threads by setting `flush_thread_count` to a number bigger than 1.
378
392
 
379
393
  ## License
380
394
 
381
- Please see [LICENSE](LICENSE).
395
+ Please see [LICENSE](LICENSE).
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
3
 
4
4
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
5
+ t.libs << 'test'
6
+ t.libs << 'lib'
7
+ t.test_files = FileList['test/**/*_test.rb']
8
+ t.verbose = false
9
+ t.warning = false
8
10
  end
9
11
 
10
12
  task :default => :test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.1
1
+ 1.1.0
@@ -1,16 +1,18 @@
1
1
  Gem::Specification.new do |spec|
2
- spec.name = "fluent-plugin-splunk-hec"
3
- spec.version = File.read("VERSION")
4
- spec.authors = ["Zhimin (Gimi) Liang"]
5
- spec.email = ["zliang@splunk.com"]
2
+ spec.name = 'fluent-plugin-splunk-hec'
3
+ spec.version = File.read('VERSION')
4
+ spec.authors = ['Splunk Inc.']
5
+ spec.email = ['DataEdge@splunk.com']
6
6
 
7
- spec.summary = %q{Fluentd plugin for Splunk HEC.}
8
- spec.description = %q{A fluentd output plugin created by Splunk that writes events to splunk indexers over HTTP Event Collector API.}
9
- spec.homepage = "https://github.com/splunk/fluent-plugin-splunk-hec"
10
- spec.license = "Apache-2.0"
7
+ spec.summary = 'Fluentd plugin for Splunk HEC.'
8
+ spec.description = 'A fluentd output plugin created by Splunk
9
+ that writes events to splunk indexers over HTTP Event Collector API.'
10
+ spec.homepage = 'https://github.com/splunk/fluent-plugin-splunk-hec'
11
+ spec.license = 'Apache-2.0'
11
12
 
12
- # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
13
- # to allow pushing to a single host or delete this section to allow pushing to any host.
13
+ # Prevent pushing this gem to RubyGems.org.
14
+ # To allow pushes either set the 'allowed_push_host' to allow
15
+ # pushing to a single host or delete this section to allow pushing to any host.
14
16
  # if spec.respond_to?(:metadata)
15
17
  # spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
16
18
  # else
@@ -18,7 +20,7 @@ Gem::Specification.new do |spec|
18
20
  # "public gem pushes."
19
21
  # end
20
22
 
21
- spec.require_paths = ["lib"]
23
+ spec.require_paths = ['lib']
22
24
  spec.test_files = Dir.glob('test/**/**.rb')
23
25
  spec.files = %w[
24
26
  CODE_OF_CONDUCT.md README.md LICENSE
@@ -27,15 +29,17 @@ Gem::Specification.new do |spec|
27
29
  Rakefile VERSION
28
30
  ] + Dir.glob('lib/**/**').reject(&File.method(:directory?))
29
31
 
30
- spec.required_ruby_version = '>= 2.4.0'
32
+ spec.required_ruby_version = '>= 2.3.0'
31
33
 
32
- spec.add_runtime_dependency "fluentd", "~> 1.0"
33
- spec.add_runtime_dependency "multi_json", "~> 1.13"
34
- spec.add_runtime_dependency "net-http-persistent", "~> 3.0"
34
+ spec.add_runtime_dependency 'fluentd', '~> 1.4'
35
+ spec.add_runtime_dependency 'multi_json', '~> 1.13'
36
+ spec.add_runtime_dependency 'net-http-persistent', '~> 3.0'
35
37
 
36
- spec.add_development_dependency "bundler", "~> 1.16"
37
- spec.add_development_dependency "rake", "~> 10.0"
38
- spec.add_development_dependency "test-unit", "~> 3.0" # required by fluent/test.rb
39
- spec.add_development_dependency "minitest", "~> 5.0"
40
- spec.add_development_dependency "webmock", "~> 3.2"
38
+ spec.add_development_dependency 'bundler', '~> 2.0'
39
+ spec.add_development_dependency 'rake', '~> 12.0'
40
+ # required by fluent/test.rb
41
+ spec.add_development_dependency 'test-unit', '~> 3.0'
42
+ spec.add_development_dependency 'minitest', '~> 5.0'
43
+ spec.add_development_dependency 'webmock', '~> 3.5.0'
44
+ spec.add_development_dependency 'simplecov', '~> 0.16.1'
41
45
  end
@@ -16,7 +16,7 @@ module Fluent::Plugin
16
16
  autoload :VERSION, "fluent/plugin/out_splunk_hec/version"
17
17
  autoload :MatchFormatter, "fluent/plugin/out_splunk_hec/match_formatter"
18
18
 
19
- KEY_FIELDS = %w[index host source sourcetype metric_name metric_value].freeze
19
+ KEY_FIELDS = %w[index time host source sourcetype metric_name metric_value].freeze
20
20
  TAG_PLACEHOLDER = '${tag}'.freeze
21
21
 
22
22
  MISSING_FIELD = Hash.new { |h, k|
@@ -36,6 +36,15 @@ module Fluent::Plugin
36
36
  desc 'The HEC token.'
37
37
  config_param :hec_token, :string
38
38
 
39
+ desc 'If a connection has not been used for this number of seconds it will automatically be reset upon the next use to avoid attempting to send to a closed connection. nil means no timeout.'
40
+ config_param :idle_timeout, :integer, default: 5
41
+
42
+ desc 'The amount of time allowed between reading two chunks from the socket.'
43
+ config_param :read_timeout, :integer, default: nil
44
+
45
+ desc 'The amount of time to wait for a connection to be opened.'
46
+ config_param :open_timeout, :integer, default: nil
47
+
39
48
  desc 'The path to a file containing a PEM-format CA certificate for this client.'
40
49
  config_param :client_cert, :string, default: nil
41
50
 
@@ -60,6 +69,9 @@ module Fluent::Plugin
60
69
  desc 'The Splunk index to index events. When not set, will be decided by HEC. This is exclusive with `index_key`'
61
70
  config_param :index, :string, default: nil
62
71
 
72
+ desc 'Field name to contain Splunk event time. By default will use fluentd\'d time'
73
+ config_param :time_key, :string, default: nil
74
+
63
75
  desc 'Field name to contain Splunk index name. This is exclusive with `index`.'
64
76
  config_param :index_key, :string, default: nil
65
77
 
@@ -113,7 +125,7 @@ module Fluent::Plugin
113
125
  config_param :coerce_to_utf8, :bool, :default => true
114
126
 
115
127
  desc <<~DESC
116
- If `coerce_to_utf8` is set to true, any non-UTF-8 character would be
128
+ If `coerce_to_utf8` is set to true, any not-UTF-8 char's would be
117
129
  replaced by the string specified here.
118
130
  DESC
119
131
  config_param :non_utf8_replacement_string, :string, :default => ' '
@@ -237,9 +249,18 @@ module Fluent::Plugin
237
249
  # From the API reference
238
250
  # http://docs.splunk.com/Documentation/Splunk/latest/RESTREF/RESTinput#services.2Fcollector
239
251
  # `time` should be a string or unsigned integer.
240
- # That's why we use `to_s` here.
252
+ # That's why we use the to_string function here.
241
253
  time: time.to_f.to_s
242
254
  }.tap { |payload|
255
+
256
+ if @time
257
+ time_value = @time.(tag, record)
258
+ # if no value is found don't override and use fluentd's time
259
+ if !time_value.nil?
260
+ payload[:time] = time_value
261
+ end
262
+ end
263
+
243
264
  payload[:index] = @index.(tag, record) if @index
244
265
  payload[:source] = @source.(tag, record) if @source
245
266
  payload[:sourcetype] = @sourcetype.(tag, record) if @sourcetype
@@ -248,8 +269,8 @@ module Fluent::Plugin
248
269
  %i[host index source sourcetype].each { |f| payload.delete f if payload[f].nil? }
249
270
 
250
271
  if @extra_fields
251
- payload[:fields] = @extra_fields.map { |name, field| [name, record[field]] }.to_h
252
- payload[:fields].compact!
272
+ payload[:fields] = @extra_fields.map { |name, field| [name, record[field]] }.to_h
273
+ payload[:fields].delete_if { |_k,v| v.nil? }
253
274
  # if a field is already in indexed fields, then remove it from the original event
254
275
  @extra_fields.values.each { |field| record.delete field }
255
276
  end
@@ -286,7 +307,7 @@ module Fluent::Plugin
286
307
  fields.update record
287
308
  end
288
309
 
289
- fields.compact!
310
+ fields.delete_if { |_k,v| v.nil? }
290
311
 
291
312
  payload[:fields] = convert_to_utf8 fields
292
313
 
@@ -315,6 +336,9 @@ module Fluent::Plugin
315
336
  c.ca_file = @ca_file
316
337
  c.ca_path = @ca_path
317
338
  c.ciphers = @ssl_ciphers
339
+ c.idle_timeout = @idle_timeout
340
+ c.read_timeout = @read_timeout
341
+ c.open_timeout = @open_timeout
318
342
 
319
343
  c.override_headers['Content-Type'] = 'application/json'
320
344
  c.override_headers['User-Agent'] = "fluent-plugin-splunk_hec_out/#{VERSION}"
@@ -375,7 +399,7 @@ module Fluent::Plugin
375
399
  'replace them with spaces, please set "coerce_to_utf8" ' \
376
400
  'to true.' }
377
401
  raise
378
- end
402
+ end
379
403
  end
380
404
  end
381
405
  end
@@ -2,13 +2,16 @@ require 'fluent/match'
2
2
 
3
3
  class Fluent::Plugin::SplunkHecOutput::MatchFormatter
4
4
  def initialize(pattern, formatter)
5
- # stolen from fluentd/lib/fluent/event_router.rb
6
- patterns = pattern.split(/\s+/).map { |str| Fluent::MatchPattern.create(str) }
7
- @pattern = if patterns.length == 1
8
- patterns[0]
9
- else
10
- Fluent::OrMatchPattern.new(patterns)
11
- end
5
+ # based on fluentd/lib/fluent/event_router.rb
6
+ patterns = pattern.split(/\s+/).map { |str|
7
+ Fluent::MatchPattern.create(str)
8
+ }
9
+ @pattern =
10
+ if patterns.length == 1
11
+ patterns[0]
12
+ else
13
+ Fluent::OrMatchPattern.new(patterns)
14
+ end
12
15
  @formatter = formatter
13
16
  end
14
17
 
@@ -1 +1,3 @@
1
- Fluent::Plugin::SplunkHecOutput::VERSION = File.read(File.expand_path('../../../../VERSION', File.dirname(__FILE__))).chomp.strip
1
+ Fluent::Plugin::SplunkHecOutput::VERSION = File.read(
2
+ File.expand_path('../../../../VERSION', File.dirname(__FILE__))
3
+ ).chomp.strip
@@ -8,10 +8,59 @@ describe Fluent::Plugin::SplunkHecOutput do
8
8
 
9
9
  it { expect(::Fluent::Plugin::SplunkHecOutput::VERSION).wont_be_nil }
10
10
 
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
58
+ end
59
+
11
60
  describe "hec_host validation" do
12
61
  describe "invalid host" do
13
62
  it "should require hec_host" do
14
- expect{ create_output_driver }.must_raise Fluent::ConfigError
63
+ expect{ create_output_driver }.must_raise Fluent::ConfigError
15
64
  end
16
65
 
17
66
  it { expect{ create_output_driver('hec_host %bad-host%') }.must_raise Fluent::ConfigError }
@@ -19,7 +68,7 @@ describe Fluent::Plugin::SplunkHecOutput do
19
68
 
20
69
  describe "good host" do
21
70
  it {
22
- expect(create_output_driver('hec_host splunk.com').instance.hec_host).must_equal "splunk.com"
71
+ expect(create_output_driver('hec_host splunk.com').instance.hec_host).must_equal "splunk.com"
23
72
  }
24
73
  end
25
74
  end
@@ -34,16 +83,25 @@ describe Fluent::Plugin::SplunkHecOutput do
34
83
  it "should use string for event time, and the value of the string should be a float" do
35
84
  verify_sent_events { |batch|
36
85
  batch.each do |item|
37
- expect(item['time']).must_be_instance_of String
38
- expect(item['time']).must_match /^\d+\.\d+$/
86
+ expect(item['time']).must_be_instance_of String
87
+ expect(item['time']).must_match /^\d+\.\d+$/
39
88
  end
40
89
  }
41
90
  end
42
91
 
92
+ # 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
94
+ # end
95
+ #
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)
99
+ end
100
+
43
101
  it "should use host machine's hostname for event host by default" do
44
102
  verify_sent_events { |batch|
45
103
  batch.each do |item|
46
- expect(item['host']).must_equal Socket.gethostname
104
+ expect(item['host']).must_equal Socket.gethostname
47
105
  end
48
106
  }
49
107
  end
@@ -51,9 +109,9 @@ describe Fluent::Plugin::SplunkHecOutput do
51
109
  %w[index source sourcetype].each do |field|
52
110
  it "should not set #{field} by default" do
53
111
  verify_sent_events { |batch|
54
- batch.each do |item|
55
- expect(item).wont_include field
56
- end
112
+ batch.each do |item|
113
+ expect(item).wont_include field
114
+ end
57
115
  }
58
116
  end
59
117
  end
@@ -66,9 +124,9 @@ describe Fluent::Plugin::SplunkHecOutput do
66
124
  sourcetype ${tag}
67
125
  CONF
68
126
  batch.each do |item|
69
- %w[index host source sourcetype].each { |field|
70
- expect(%w[tag.event1 tag.event2]).must_include item[field]
71
- }
127
+ %w[index host source sourcetype].each { |field|
128
+ expect(%w[tag.event1 tag.event2]).must_include item[field]
129
+ }
72
130
  end
73
131
  }
74
132
  end
@@ -81,10 +139,10 @@ describe Fluent::Plugin::SplunkHecOutput do
81
139
  sourcetype_key agent.name
82
140
  CONF
83
141
  batch.each { |item|
84
- expect(item['index']).must_equal 'info'
85
- expect(item['host']).must_equal 'my_machine'
86
- expect(item['source']).must_equal 'cool.log'
87
- expect(item['sourcetype']).must_equal 'test'
142
+ expect(item['index']).must_equal 'info'
143
+ expect(item['host']).must_equal 'my_machine'
144
+ expect(item['source']).must_equal 'cool.log'
145
+ expect(item['sourcetype']).must_equal 'test'
88
146
 
89
147
  JSON.load(item['event']).tap do |event|
90
148
  %w[level from file].each { |field| expect(event).wont_include field }
@@ -94,7 +152,7 @@ describe Fluent::Plugin::SplunkHecOutput do
94
152
  }
95
153
  end
96
154
 
97
- it "should remove nil fileds." do
155
+ it "should remove nil fields." do
98
156
  verify_sent_events(<<~CONF) { |batch|
99
157
  index_key nonexist
100
158
  host_key nonexist
@@ -111,7 +169,7 @@ describe Fluent::Plugin::SplunkHecOutput do
111
169
  end
112
170
 
113
171
  describe 'formatter' do
114
- it "should support replace the default json formater" do
172
+ it "should support replace the default json formatter" do
115
173
  verify_sent_events(<<~CONF) { |batch|
116
174
  <format>
117
175
  @type single_value
@@ -163,86 +221,107 @@ describe Fluent::Plugin::SplunkHecOutput do
163
221
  describe 'metric'do
164
222
  it 'should check related configs' do
165
223
  expect(
166
- create_output_driver('hec_host somehost', 'data_type metric')
224
+ create_output_driver('hec_host somehost', 'data_type metric')
167
225
  ).wont_be_nil
168
226
 
169
227
  expect{
170
- create_output_driver('hec_host somehost', 'data_type metric', 'metrics_from_event false')
228
+ create_output_driver('hec_host somehost', 'data_type metric', 'metrics_from_event false')
171
229
  }.must_raise Fluent::ConfigError
172
230
 
173
231
  expect{
174
- create_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x')
232
+ create_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x')
175
233
  }.must_raise Fluent::ConfigError
176
234
 
177
235
  expect(
178
- create_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x', 'metric_value_key y')
236
+ create_output_driver('hec_host somehost', 'data_type metric', 'metric_name_key x', 'metric_value_key y')
179
237
  ).wont_be_nil
180
238
  end
181
239
 
182
240
  it 'should have "metric" as event, and have proper fields' do
183
241
  verify_sent_events(<<~CONF) { |batch|
184
- data_type metric
185
- metric_name_key from
186
- metric_value_key value
242
+ data_type metric
243
+ metric_name_key from
244
+ metric_value_key value
187
245
  CONF
188
- batch.each do |item|
189
- expect(item['event']).must_equal 'metric'
190
- expect(item['fields']['metric_name']).must_equal 'my_machine'
191
- expect(item['fields']['_value']).must_equal 100
192
- expect(item['fields']['log']).must_equal 'everything is good'
193
- expect(item['fields']['level']).must_equal 'info'
194
- expect(item['fields']['file']).must_equal 'cool.log'
195
- end
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
196
254
  }
197
255
  end
198
256
 
199
257
  it 'should handle empty fields' do
200
258
  verify_sent_events(<<~CONF) { |batch|
201
- data_type metric
202
- metric_name_key from
203
- metric_value_key value
204
- <fields>
205
- </fields>
259
+ data_type metric
260
+ metric_name_key from
261
+ metric_value_key value
262
+ <fields>
263
+ </fields>
206
264
  CONF
207
- batch.each do |item|
265
+ batch.each do |item|
208
266
  # only "metric_name" and "_value"
209
- expect(item['fields'].keys.size).must_equal 2
210
- end
267
+ expect(item['fields'].keys.size).must_equal 2
268
+ end
211
269
  }
212
270
  end
213
271
 
214
272
  it 'should handle custom fields' do
215
273
  verify_sent_events(<<~CONF) { |batch|
216
- data_type metric
217
- metric_name_key from
218
- metric_value_key value
219
- <fields>
220
- level
221
- filePath file
222
- username
223
- </fields>
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>
224
282
  CONF
225
- batch.each do |item|
226
- expect(item['fields'].keys.size).must_equal 4
227
- expect(item['fields']['level']).must_equal 'info'
228
- expect(item['fields']['filePath']).must_equal 'cool.log'
229
- # null fields should be removed
230
- expect(item['fields']).wont_be :has_key?, 'username'
231
- end
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
232
290
  }
233
291
  end
234
292
 
235
293
  it 'should treat each key-value in event as a metric' do
236
294
  metrics = [
237
- ['tag', event_time, {'cup': 0.5, 'memory': 100}],
238
- ['tag', event_time, {'cup': 0.6, 'memory': 200}]
295
+ ['tag', event_time, {'cup': 0.5, 'memory': 100}],
296
+ ['tag', event_time, {'cup': 0.6, 'memory': 200}]
239
297
  ]
240
298
  with_stub_hec(events: metrics, conf: 'data_type metric') { |batch|
241
- expect(batch.size).must_equal 4
299
+ expect(batch.size).must_equal 4
242
300
  }
243
301
  end
244
302
  end
245
303
 
304
+ 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
308
+
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
312
+
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
316
+
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
323
+ end
324
+
246
325
  def with_stub_hec(events:, conf: '', &blk)
247
326
  host = "hec.splunk.com"
248
327
  @driver = create_output_driver("hec_host #{host}", conf)
@@ -266,8 +345,8 @@ describe Fluent::Plugin::SplunkHecOutput do
266
345
  "file" => "cool.log",
267
346
  "value" => 100,
268
347
  "agent" => {
269
- "name" => "test",
270
- "version" => "1.0.0"
348
+ "name" => "test",
349
+ "version" => "1.1.0"
271
350
  }
272
351
  }
273
352
  events = [
@@ -1,13 +1,15 @@
1
- $LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2
- $LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
3
- require "fluent/plugin/out_splunk_hec"
1
+ require 'simplecov'
2
+ SimpleCov.start
4
3
 
5
- require "fluent/test"
6
- require "fluent/test/driver/output"
7
- require "fluent/test/helpers"
8
- require "minitest/autorun"
9
- require "webmock/minitest"
4
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
5
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
6
+ require 'fluent/plugin/out_splunk_hec'
10
7
 
8
+ require 'fluent/test'
9
+ require 'fluent/test/driver/output'
10
+ require 'fluent/test/helpers'
11
+ require 'minitest/autorun'
12
+ require 'webmock/minitest'
11
13
 
12
14
  # make assertions from webmock available in minitest/spec
13
15
  module Minitest::Expectations
@@ -15,7 +17,7 @@ module Minitest::Expectations
15
17
  infect_an_assertion :assert_not_requested, :wont_be_requested, :reverse
16
18
  end
17
19
 
18
- TEST_HEC_TOKEN = "some-token".freeze
20
+ TEST_HEC_TOKEN = 'some-token'.freeze
19
21
 
20
22
  module PluginTestHelper
21
23
  def fluentd_conf_for(*lines)
@@ -32,8 +34,9 @@ module PluginTestHelper
32
34
  end
33
35
 
34
36
  def stub_hec_request(endpoint)
35
- stub_request(:post, "#{endpoint}/services/collector").
36
- with(headers: {"Authorization" => "Splunk #{TEST_HEC_TOKEN}", "User-Agent" => "fluent-plugin-splunk_hec_out/#{Fluent::Plugin::SplunkHecOutput::VERSION}"}).
37
- to_return(body: '{"text":"Success","code":0}')
37
+ stub_request(:post, "#{endpoint}/services/collector")
38
+ .with(headers: { 'Authorization' => "Splunk #{TEST_HEC_TOKEN}",
39
+ 'User-Agent' => "fluent-plugin-splunk_hec_out/#{Fluent::Plugin::SplunkHecOutput::VERSION}" })
40
+ .to_return(body: '{"text":"Success","code":0}')
38
41
  end
39
42
  end
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.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Zhimin (Gimi) Liang
7
+ - Splunk Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-27 00:00:00.000000000 Z
11
+ date: 2019-03-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.0'
19
+ version: '1.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.0'
26
+ version: '1.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: multi_json
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.16'
61
+ version: '2.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.16'
68
+ version: '2.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '10.0'
75
+ version: '12.0'
76
76
  type: :development
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: '10.0'
82
+ version: '12.0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: test-unit
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -114,18 +114,33 @@ dependencies:
114
114
  requirements:
115
115
  - - "~>"
116
116
  - !ruby/object:Gem::Version
117
- version: '3.2'
117
+ version: 3.5.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
121
  requirements:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
- version: '3.2'
125
- description: A fluentd output plugin created by Splunk that writes events to splunk
126
- indexers over HTTP Event Collector API.
124
+ version: 3.5.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: simplecov
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 0.16.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.16.1
139
+ description: |-
140
+ A fluentd output plugin created by Splunk
141
+ that writes events to splunk indexers over HTTP Event Collector API.
127
142
  email:
128
- - zliang@splunk.com
143
+ - DataEdge@splunk.com
129
144
  executables: []
130
145
  extensions: []
131
146
  extra_rdoc_files: []
@@ -163,26 +178,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
178
  requirements:
164
179
  - - ">="
165
180
  - !ruby/object:Gem::Version
166
- version: 2.4.0
181
+ version: 2.3.0
167
182
  required_rubygems_version: !ruby/object:Gem::Requirement
168
183
  requirements:
169
184
  - - ">="
170
185
  - !ruby/object:Gem::Version
171
186
  version: '0'
172
187
  requirements: []
173
- rubyforge_project:
174
- rubygems_version: 2.7.6
188
+ rubygems_version: 3.0.3
175
189
  signing_key:
176
190
  specification_version: 4
177
191
  summary: Fluentd plugin for Splunk HEC.
178
192
  test_files:
179
- - test/fluent/plugin/out_splunk_hec_test.rb
180
- - test/lib/webmock/http_lib_adapters/patron_adapter.rb
181
- - test/lib/webmock/http_lib_adapters/manticore_adapter.rb
182
193
  - test/lib/webmock/http_lib_adapters/em_http_request_adapter.rb
183
194
  - test/lib/webmock/http_lib_adapters/typhoeus_hydra_adapter.rb
184
- - test/lib/webmock/http_lib_adapters/curb_adapter.rb
185
195
  - test/lib/webmock/http_lib_adapters/httpclient_adapter.rb
186
- - test/lib/webmock/http_lib_adapters/http_rb_adapter.rb
187
196
  - test/lib/webmock/http_lib_adapters/excon_adapter.rb
197
+ - test/lib/webmock/http_lib_adapters/patron_adapter.rb
198
+ - test/lib/webmock/http_lib_adapters/manticore_adapter.rb
199
+ - test/lib/webmock/http_lib_adapters/curb_adapter.rb
200
+ - test/lib/webmock/http_lib_adapters/http_rb_adapter.rb
188
201
  - test/test_helper.rb
202
+ - test/fluent/plugin/out_splunk_hec_test.rb