fluent-plugin-splunkapi-ssln 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-splunk.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,18 @@
1
+ Copyright (C) 2013 Keisuke Nishida
2
+
3
+ Licensed to the Apache Software Foundation (ASF) under one
4
+ or more contributor license agreements. See the NOTICE file
5
+ distributed with this work for additional information
6
+ regarding copyright ownership. The ASF licenses this file
7
+ to you under the Apache License, Version 2.0 (the
8
+ "License"); you may not use this file except in compliance
9
+ with the License. You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing,
14
+ software distributed under the License is distributed on an
15
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
+ KIND, either express or implied. See the License for the
17
+ specific language governing permissions and limitations
18
+ under the License.
data/README.md ADDED
@@ -0,0 +1,249 @@
1
+ # Fluent::Plugin::SplunkAPI, a plugin for [Fluentd](http://fluentd.org)
2
+
3
+ Splunk output plugin for Fluent event collector.
4
+
5
+ This plugin makes use of the following APIs:
6
+
7
+ Splunk REST API:
8
+
9
+ http://docs.splunk.com/Documentation/Splunk/latest/RESTAPI/RESTinput
10
+
11
+ Splunk Storm API:
12
+
13
+ http://docs.splunk.com/Documentation/Storm/latest/User/UseStormsRESTAPI
14
+
15
+ ## Notes
16
+
17
+ Although this plugin is capable of sending Fluent events directly to
18
+ Splunk servers or Splunk Storm, it is not recommended to do so.
19
+ Please use "Universal Forwarder" as a gateway, as described below.
20
+
21
+ It is known that this plugin has several issues of performance and
22
+ error handling in dealing with large data sets. With a local/reliable
23
+ forwarder, you can aggregate a number of events locally and send them
24
+ to a server in bulk.
25
+
26
+ In short, I'd recommend to install a forwarder in each host, and use
27
+ this plugin to deliver events to the local forwarder:
28
+
29
+ <match **>
30
+ # Deliver events to the local forwarder.
31
+ type splunkapi
32
+ protocol rest
33
+ server 127.0.0.1:8089
34
+ verify false
35
+ auth admin:changeme
36
+
37
+ # Convert fluent tags to Splunk sources.
38
+ # If you set an index, "check_index false" is required.
39
+ host YOUR-HOSTNAME
40
+ index SOME-INDEX
41
+ check_index false
42
+ source {TAG}
43
+ sourcetype fluent
44
+
45
+ # TIMESTAMP: key1="value1" key2="value2" ...
46
+ time_format unixtime
47
+ format kvp
48
+
49
+ # Memory buffer with a short flush internal.
50
+ buffer_type memory
51
+ buffer_queue_limit 16
52
+ buffer_chunk_limit 8m
53
+ flush_interval 2s
54
+ </match>
55
+
56
+ ## Additional Notes
57
+
58
+ Splunk 5 has a new feature called "Modular Inputs":
59
+
60
+ http://blogs.splunk.com/2013/04/16/modular-inputs-tools/
61
+
62
+ My plan is switching to Modular Inputs rather than staying with APIs.
63
+
64
+ ## Installation
65
+
66
+ Add this line to your application's Gemfile:
67
+
68
+ gem 'fluent-plugin-splunkapi'
69
+
70
+ And then execute:
71
+
72
+ $ bundle
73
+
74
+ Or install it yourself as:
75
+
76
+ $ gem install fluent-plugin-splunkapi
77
+
78
+ ## Configuration
79
+
80
+ Put the following lines to your fluent.conf:
81
+
82
+ <match **>
83
+ type splunkapi
84
+
85
+ #
86
+ # Splnk Server
87
+ #
88
+
89
+ # protocol: API protocol version
90
+ # values: rest, storm
91
+ # default: rest
92
+ protocol rest
93
+
94
+ # server: Splunk server host and port
95
+ # default: localhost:8089
96
+ server localhost:8089
97
+
98
+ # verify: SSL server verification
99
+ # default: true
100
+ #verify false
101
+
102
+ # auth: username and password
103
+ auth admin:pass
104
+
105
+ #
106
+ # Splnk Storm
107
+ #
108
+
109
+ # protocol: API protocol version.
110
+ # values: rest, storm
111
+ # default: rest
112
+ #protocol storm
113
+
114
+ # access_token: for Splunk Storm
115
+ #access_token YOUR-ACCESS-TOKEN
116
+
117
+ # access_token: for Splunk Storm
118
+ #project_id YOUR-PROJECT-ID
119
+
120
+ #
121
+ # Event Parameters
122
+ #
123
+
124
+ # host: 'host' parameter passed to Splunk
125
+ host YOUR-HOSTNAME
126
+
127
+ # index: 'index' parameter passed to Splunk (REST only)
128
+ # default: <none>
129
+ #index main
130
+
131
+ # check_index: 'check-index' parameter passed to Splunk (REST only)
132
+ # default: <none>
133
+ #check_index false
134
+
135
+ # host: 'source' parameter passed to Splunk
136
+ # default: {TAG}
137
+ #
138
+ # "{TAG}" will be replaced by fluent tags at runtime
139
+ source {TAG}
140
+
141
+ # sourcetype: 'sourcetype' parameter passed to Splunk
142
+ # default: fluent
143
+ sourcetype fluent
144
+
145
+ #
146
+ # Formatting Parameters
147
+ #
148
+
149
+ # time_format: the time format of each event
150
+ # value: none, unixtime, localtime, or any time format string
151
+ # default: localtime
152
+ time_format localtime
153
+
154
+ # format: the text format of each event
155
+ # value: json, kvp, or text
156
+ # default: json
157
+ #
158
+ # input = {"x":1, "y":"xyz", "message":"Hello, world!"}
159
+ #
160
+ # 'json' is JSON encoding:
161
+ # {"x":1,"y":"xyz","message":"Hello, world!"}
162
+ #
163
+ # 'kvp' is "key=value" pairs, which is automatically detected as fields by Splunk:
164
+ # x="1" y="xyz" message="Hello, world!"
165
+ #
166
+ # 'text' outputs the value of "message" as is, with "key=value" pairs for others:
167
+ # [x="1" y="xyz"] Hello, world!
168
+ format json
169
+
170
+ #
171
+ # Buffering Parameters
172
+ #
173
+
174
+ # Standard parameters for buffering. See documentation for details:
175
+ # http://docs.fluentd.org/articles/buffer-plugin-overview
176
+ buffer_type memory
177
+ buffer_queue_limit 16
178
+
179
+ # buffer_chunk_limit: The maxium size of POST data in a single API call.
180
+ #
181
+ # This value should be reasonablly small since the current implementation
182
+ # of out_splunkapi converts a chunk to POST data on memory before API calls.
183
+ # The default value should be good enough.
184
+ buffer_chunk_limit 8m
185
+
186
+ # flush_interval: The interval of API requests.
187
+ #
188
+ # Make sure that this value is sufficiently large to make successive API calls.
189
+ # Note that a different 'source' creates a different API POST, each of which may
190
+ # take two or more seconds. If you include "{TAG}" in the source parameter and
191
+ # this 'match' section recieves many tags, a single flush may take long time.
192
+ # (Run fluentd with -v to see verbose logs.)
193
+ flush_interval 60s
194
+ </match>
195
+
196
+ ## Example
197
+
198
+ # Input from applications
199
+ <source>
200
+ type forward
201
+ </source>
202
+
203
+ # Input from log files
204
+ <source>
205
+ type tail
206
+ path /var/log/apache2/ssl_access.log
207
+ tag ssl_access.log
208
+ format /(?<message>.*)/
209
+ pos_file /var/log/td-agent/ssl_access.log.pos
210
+ </source>
211
+
212
+ # fluent logs in text format
213
+ <match fluent.*>
214
+ type splunkapi
215
+ protocol rest
216
+ server splunk.example.com:8089
217
+ auth admin:pass
218
+ sourcetype fluentd
219
+ format text
220
+ </match>
221
+
222
+ # log files in text format without timestamp
223
+ <match *.log>
224
+ type splunkapi
225
+ protocol rest
226
+ server splunk.example.com:8089
227
+ auth admin:pass
228
+ sourcetype log
229
+ time_format none
230
+ format text
231
+ </match>
232
+
233
+ # application logs in kvp format
234
+ <match app.**>
235
+ type splunkapi
236
+ protocol rest
237
+ server splunk.example.com:8089
238
+ auth admin:pass
239
+ sourcetype app
240
+ format kvp
241
+ </match>
242
+
243
+ ## Contributing
244
+
245
+ 1. Fork it
246
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
247
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
248
+ 4. Push to the branch (`git push origin my-new-feature`)
249
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+ Rake::TestTask.new(:test) do |test|
5
+ test.libs << 'lib' << 'test'
6
+ test.pattern = 'test/**/test_*.rb'
7
+ test.verbose = true
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-splunkapi-ssln"
6
+ gem.version = "0.0.1"
7
+ gem.authors = ["Kristian Brimble"]
8
+ gem.email = ["kbrimble@sportingsolutions,com"]
9
+ gem.summary = %q{Splunk output plugin (REST API / Storm API) for Fluentd event collector}
10
+ gem.description = %q{Splunk output plugin (REST API / Storm API) for Fluentd event collector}
11
+ gem.homepage = "https://github.com/kbrimble/fluent-plugin-splunkapi"
12
+ gem.license = 'Apache License, Version 2.0'
13
+
14
+ gem.files = `git ls-files`.split($/)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
+ gem.require_paths = ["lib"]
18
+
19
+ gem.rubyforge_project = "fluent-plugin-splunkapi-ssln"
20
+ gem.add_development_dependency "fluentd"
21
+ gem.add_development_dependency "net-http-persistent"
22
+ gem.add_runtime_dependency "fluentd"
23
+ gem.add_runtime_dependency "net-http-persistent"
24
+ end
@@ -0,0 +1,139 @@
1
+ =begin
2
+
3
+ Copyright (C) 2013 Keisuke Nishida
4
+
5
+ Licensed to the Apache Software Foundation (ASF) under one
6
+ or more contributor license agreements. See the NOTICE file
7
+ distributed with this work for additional information
8
+ regarding copyright ownership. The ASF licenses this file
9
+ to you under the Apache License, Version 2.0 (the
10
+ "License"); you may not use this file except in compliance
11
+ with the License. You may obtain a copy of the License at
12
+
13
+ http://www.apache.org/licenses/LICENSE-2.0
14
+
15
+ Unless required by applicable law or agreed to in writing,
16
+ software distributed under the License is distributed on an
17
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18
+ KIND, either express or implied. See the License for the
19
+ specific language governing permissions and limitations
20
+ under the License.
21
+
22
+ =end
23
+
24
+ module Fluent
25
+
26
+ class SplunkAPIOutput < BufferedOutput
27
+ Plugin.register_output('splunkapi', self)
28
+
29
+ config_param :protocol, :string, :default => 'rest'
30
+
31
+ # for Splunk REST API
32
+ config_param :server, :string, :default => 'localhost:8089'
33
+ config_param :verify, :bool, :default => true
34
+ config_param :auth, :string, :default => nil # TODO: required with rest
35
+
36
+ # Event parameters
37
+ config_param :check_index, :bool, :default => true
38
+ config_param :index, :string, :default => 'index'
39
+
40
+ # Retry parameters
41
+ config_param :post_retry_max, :integer, :default => 5
42
+ config_param :post_retry_interval, :integer, :default => 5
43
+
44
+ def initialize
45
+ super
46
+ require 'net/http/persistent'
47
+ require 'json'
48
+ @idx_indexers = 0
49
+ @indexers = []
50
+ end
51
+
52
+ def configure(conf)
53
+ super
54
+
55
+ if @server.match(/,/)
56
+ @indexers = @server.split(',')
57
+ else
58
+ @indexers = [@server]
59
+ end
60
+ end
61
+
62
+ def start
63
+ super
64
+ @http = Net::HTTP::Persistent.new 'fluentd-plugin-splunkapi'
65
+ @http.verify_mode = OpenSSL::SSL::VERIFY_NONE unless @verify
66
+ @http.headers['Content-Type'] = 'text/plain'
67
+ log.info "initialized for splunkapi"
68
+ end
69
+
70
+ def shutdown
71
+ # NOTE: call super before @http.shutdown because super may flush final output
72
+ super
73
+
74
+ @http.shutdown
75
+ log.debug "shutdown from splunkapi"
76
+ end
77
+
78
+ def format(tag, time, record)
79
+ event = "#{record.to_json}\n"
80
+ [tag, event].to_msgpack
81
+ end
82
+
83
+ def chunk_to_buffers(chunk)
84
+ buffers = {}
85
+ chunk.msgpack_each do |tag, message|
86
+ event = JSON.parse(message)
87
+ uri = get_baseurl(tag, event)
88
+ (buffers[uri] ||= []) << event['payload']
89
+ end
90
+ return buffers
91
+ end
92
+
93
+ def write(chunk)
94
+ chunk_to_buffers(chunk).each do |url, messages|
95
+ uri = URI url
96
+ post = Net::HTTP::Post.new uri.request_uri
97
+ post.basic_auth @username, @password
98
+ post.body = messages.join('')
99
+ log.debug "POST #{uri}"
100
+ # retry up to :post_retry_max times
101
+ 1.upto(@post_retry_max) do |c|
102
+ response = @http.request uri, post
103
+ log.debug "=> #{response.code} (#{response.message})"
104
+ if response.code == "200"
105
+ # success
106
+ break
107
+ elsif response.code.match(/^40/)
108
+ # user error
109
+ log.error "#{uri}: #{response.code} (#{response.message})\n#{response.body}"
110
+ break
111
+ elsif c < @post_retry_max
112
+ # retry
113
+ sleep @post_retry_interval
114
+ next
115
+ else
116
+ # other errors. fluentd will retry processing on exception
117
+ # FIXME: this may duplicate logs when using multiple buffers
118
+ raise "#{uri}: #{response.message}"
119
+ end
120
+ end
121
+ end
122
+ end
123
+
124
+ def get_baseurl(key, event)
125
+ base_url = ''
126
+ @username, @password = @auth.split(':')
127
+ server = @indexers[@idx_indexers];
128
+ @idx_indexers = (@idx_indexers + 1) % @indexers.length
129
+ base_url = "https://#{server}/services/receivers/simple?sourcetype=#{key}"
130
+ base_url += "&host=#{event['host']}"
131
+ base_url += "&index=#{@index}"
132
+ base_url += "&source=#{event['source']}"
133
+ base_url += "&check-index=false" unless @check_index
134
+ base_url
135
+ end
136
+ end
137
+
138
+ # Module close
139
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+
12
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
13
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
14
+ require 'fluent/test'
15
+ unless ENV.has_key?('VERBOSE')
16
+ nulllogger = Object.new
17
+ nulllogger.instance_eval {|obj|
18
+ def method_missing(method, *args)
19
+ # pass
20
+ end
21
+ }
22
+ $log = nulllogger
23
+ end
24
+
25
+ require 'fluent/plugin/out_splunkapi'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,36 @@
1
+ require 'helper'
2
+
3
+ class SplunkAPIOutputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ protocol rest
10
+ server localhost:8089
11
+ verify false
12
+ auth admin:changeme
13
+ ]
14
+
15
+ def create_driver(conf=CONFIG, tag='test')
16
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::SplunkAPIOutput, tag).configure(conf)
17
+ end
18
+
19
+ def test_configure
20
+ # default
21
+ d = create_driver
22
+ assert_equal 'rest', d.instance.protocol
23
+ assert_equal '{TAG}', d.instance.source
24
+ assert_equal 'fluent', d.instance.sourcetype
25
+ end
26
+
27
+ def test_write
28
+ d = create_driver
29
+
30
+ time = Time.parse("2010-01-02 13:14:15 UTC").to_i
31
+ d.emit({"a"=>1}, time)
32
+ d.emit({"a"=>2}, time)
33
+
34
+ d.run
35
+ end
36
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-splunkapi-ssln
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Kristian Brimble
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-05-21 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fluentd
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-http-persistent
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: fluentd
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: net-http-persistent
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ description: Splunk output plugin (REST API / Storm API) for Fluentd event collector
79
+ email:
80
+ - kbrimble@sportingsolutions,com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - Gemfile
87
+ - LICENSE.txt
88
+ - README.md
89
+ - Rakefile
90
+ - fluent-plugin-splunkapi-ssln.gemspec
91
+ - lib/fluent/plugin/out_splunkapi-ssnl.rb
92
+ - test/helper.rb
93
+ - test/plugin/test_out_splunkapi.rb
94
+ homepage: https://github.com/kbrimble/fluent-plugin-splunkapi
95
+ licenses:
96
+ - Apache License, Version 2.0
97
+ post_install_message:
98
+ rdoc_options: []
99
+ require_paths:
100
+ - lib
101
+ required_ruby_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ! '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ required_rubygems_version: !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubyforge_project: fluent-plugin-splunkapi-ssln
115
+ rubygems_version: 1.8.23
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Splunk output plugin (REST API / Storm API) for Fluentd event collector
119
+ test_files:
120
+ - test/helper.rb
121
+ - test/plugin/test_out_splunkapi.rb