fluent-plugin-out-solr 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc782b093daee34447a02fd38a5329ea324b5451
4
+ data.tar.gz: f9d6ed5c4ee8e56adf8bbda753cbf099a02d9eda
5
+ SHA512:
6
+ metadata.gz: 1c6087383a13c05b88f30e4d14553e17852cce81bd3181b958a3329354d59328fd253527a4281b54d9d3506c74725aa88e44498af7aa5fe87e5059a21c8fd765
7
+ data.tar.gz: 0a5ef15f05a429891962cd8661b3507ccab8c911638b1d2eec38e80da1b21bd8435099dedc16c20c37b7193fdd5e46485ea780710081e5ac7802133addc38a0f
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,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'coveralls', require: false
data/LICENSE.txt ADDED
@@ -0,0 +1,23 @@
1
+ Copyright (c) 2012 Uken Games
2
+ Copyright (c) HARUYAMA Seigo
3
+
4
+ MIT License
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining
7
+ a copy of this software and associated documentation files (the
8
+ "Software"), to deal in the Software without restriction, including
9
+ without limitation the rights to use, copy, modify, merge, publish,
10
+ distribute, sublicense, and/or sell copies of the Software, and to
11
+ permit persons to whom the Software is furnished to do so, subject to
12
+ the following conditions:
13
+
14
+ The above copyright notice and this permission notice shall be
15
+ included in all copies or substantial portions of the Software.
16
+
17
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
21
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
22
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,75 @@
1
+ # fluent-plugin-out-solr
2
+
3
+ Yet another Solr output plugin for fluentd based on [uken/fluent-plugin-elasticsearch](https://github.com/uken/fluent-plugin-elasticsearch).
4
+
5
+ Notice: no relationship with [btigit/fluent-plugin-solr](https://github.com/btigit/fluent-plugin-solr).
6
+
7
+ ## Installation
8
+
9
+ $ gem install fluent-plugin-out-solr
10
+
11
+ ## Usage
12
+
13
+ ### fluent.conf snippet
14
+
15
+ ```
16
+ <source>
17
+ type tail
18
+ format apache
19
+ path /tmp/access.log
20
+ tag apache.access
21
+ </source>
22
+
23
+ <match apache.*>
24
+ type solr
25
+ host localhost
26
+ port 8983
27
+ core collection1
28
+ include_tag_key true
29
+ tag_key tag
30
+ flush_interval 3s
31
+ </match>
32
+ ```
33
+
34
+ ### solrconfig.xml snippet
35
+
36
+ See: [UniqueKey - Solr Wiki](https://wiki.apache.org/solr/UniqueKey)
37
+
38
+ ```xml
39
+ <requestHandler name="/update" class="solr.UpdateRequestHandler">
40
+ <lst name="defaults">
41
+ <str name="update.chain">uuid</str>
42
+ </lst>
43
+ </requestHandler>
44
+
45
+ <updateRequestProcessorChain name="uuid">
46
+ <processor class="solr.UUIDUpdateProcessorFactory">
47
+ <str name="fieldName">id</str>
48
+ </processor>
49
+ <processor class="solr.RunUpdateProcessorFactory" />
50
+ </updateRequestProcessorChain>
51
+ ```
52
+
53
+ ### schema.xml snippet
54
+
55
+ ```xml
56
+ <field name="id" type="uuid" indexed="true" stored="true" required="true"/>
57
+
58
+ <field name="host" type="string" indexed="true" stored="true"/>
59
+ <field name="user" type="string" indexed="true" stored="true"/>
60
+ <field name="method" type="string" indexed="true" stored="true"/>
61
+ <field name="path" type="string" indexed="true" stored="true"/>
62
+ <field name="code" type="string" indexed="true" stored="true"/>
63
+ <field name="size" type="string" indexed="true" stored="true"/>
64
+ <field name="referer" type="string" indexed="true" stored="true"/>
65
+ <field name="agent" type="text_ws" indexed="true" stored="true"/>
66
+ <field name="tag" type="string" indexed="true" stored="true"/>
67
+ ```
68
+
69
+ ## Contributing
70
+
71
+ 1. Fork it
72
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
73
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
74
+ 4. Push to the branch (`git push origin my-new-feature`)
75
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+
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
11
+
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'fluent-plugin-out-solr'
6
+ s.version = '0.0.1'
7
+ s.authors = ['diogo', 'pitr', 'haruyama']
8
+ s.email = ['team@uken.com', 'haruyama@unixuser.org']
9
+ s.description = %q{Solr output plugin for Fluent event collector}
10
+ s.summary = s.description
11
+ s.homepage = 'https://github.com/haruyama/fluent-plugin-out-solr'
12
+ s.license = 'MIT'
13
+
14
+ s.files = `git ls-files`.split($/)
15
+ s.executables = s.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
16
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
17
+ s.require_paths = ['lib']
18
+
19
+ s.add_runtime_dependency 'fluentd'
20
+
21
+ s.add_development_dependency 'rake'
22
+ s.add_development_dependency 'webmock'
23
+ end
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ # Solr output plugin for Fluent
6
+ class Fluent::SolrOutput < Fluent::BufferedOutput
7
+ Fluent::Plugin.register_output('solr', self)
8
+
9
+ config_param :host, :string, default: 'localhost'
10
+ config_param :port, :integer, default: 8983
11
+ config_param :core, :string, default: 'collection1'
12
+
13
+ include Fluent::SetTagKeyMixin
14
+ config_set_default :include_tag_key, false
15
+
16
+ def initialize
17
+ super
18
+ end
19
+
20
+ def configure(conf)
21
+ super
22
+ end
23
+
24
+ def start
25
+ super
26
+ end
27
+
28
+ def format(tag, time, record)
29
+ [tag, time, record].to_msgpack
30
+ end
31
+
32
+ def shutdown
33
+ super
34
+ end
35
+
36
+ def write(chunk)
37
+ bulk_message = []
38
+
39
+ chunk.msgpack_each do |tag, time, record|
40
+ record.merge!(@tag_key => tag) if @include_tag_key
41
+
42
+ bulk_message << record
43
+ end
44
+
45
+ http = Net::HTTP.new(@host, @port.to_i)
46
+ request = Net::HTTP::Post.new('/solr/' + URI.escape(@core) + '/update', 'content-type' => 'application/json; charset=utf-8')
47
+ request.body = Yajl::Encoder.encode(bulk_message)
48
+ http.request(request).value
49
+ end
50
+ end
data/test/helper.rb ADDED
@@ -0,0 +1 @@
1
+ require 'minitest/pride'
@@ -0,0 +1,25 @@
1
+ LineLength:
2
+ Enabled: false
3
+
4
+ MethodLength:
5
+ Enabled: true
6
+ CountComments: false # count full line comments?
7
+ Max: 50
8
+
9
+ FavorSprintf:
10
+ Enabled: false
11
+
12
+ MultilineBlocks:
13
+ Enabled: false
14
+
15
+ AvoidPerlBackrefs:
16
+ Enabled: false
17
+
18
+ PercentLiterals:
19
+ Enabled: false
20
+
21
+ BraceAfterPercent:
22
+ Enabled: false
23
+
24
+ ClassLength:
25
+ Enabled: false
@@ -0,0 +1,116 @@
1
+ require 'test/unit'
2
+
3
+ require 'fluent/test'
4
+ require 'fluent/plugin/out_solr'
5
+
6
+ require 'webmock/test_unit'
7
+ require 'date'
8
+
9
+ require 'helper'
10
+
11
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
12
+ $LOAD_PATH.push File.dirname(__FILE__)
13
+
14
+ WebMock.disable_net_connect!
15
+
16
+ # Solr output test
17
+ class SolrOutput < Test::Unit::TestCase
18
+ attr_accessor :index_cmds, :content_type
19
+
20
+ def setup
21
+ Fluent::Test.setup
22
+ @driver = nil
23
+ end
24
+
25
+ def driver(tag = 'test', conf = '')
26
+ @driver ||= Fluent::Test::BufferedOutputTestDriver.new(Fluent::SolrOutput, tag).configure(conf)
27
+ end
28
+
29
+ def sample_record
30
+ { 'age' => 26, 'request_id' => '42' }
31
+ end
32
+
33
+ def stub_solr(url = 'http://localhost:8983/solr/collection1/update')
34
+ stub_request(:post, url).with do |req|
35
+ @content_type = req.headers['Content-Type']
36
+ @index_cmds = JSON.parse(req.body)
37
+ end
38
+ end
39
+
40
+ def stub_solr_unavailable(url = 'http://localhost:8983/solr/collection1/update')
41
+ stub_request(:post, url).to_return(status: [503, 'Service Unavailable'])
42
+ end
43
+
44
+ def test_writes_to_default_index
45
+ stub_solr
46
+ driver.emit(sample_record)
47
+ driver.run
48
+ assert_equal(26, @index_cmds[0]['age'])
49
+ assert_equal('42', @index_cmds[0]['request_id'])
50
+ end
51
+
52
+ def test_wrties_with_proper_content_type
53
+ stub_solr
54
+ driver.emit(sample_record)
55
+ driver.run
56
+ assert_equal('application/json; charset=utf-8', @content_type)
57
+ end
58
+
59
+ def test_writes_to_speficied_core
60
+ driver.configure("core mycore\n")
61
+ solr_request = stub_solr('http://localhost:8983/solr/mycore/update')
62
+ driver.emit(sample_record)
63
+ driver.run
64
+ assert_requested(solr_request)
65
+ end
66
+
67
+ def test_writes_to_speficied_host
68
+ driver.configure("host 192.168.33.50\n")
69
+ solr_request = stub_solr('http://192.168.33.50:8983/solr/collection1/update')
70
+ driver.emit(sample_record)
71
+ driver.run
72
+ assert_requested(solr_request)
73
+ end
74
+
75
+ def test_writes_to_speficied_port
76
+ driver.configure("port 9201\n")
77
+ solr_request = stub_solr('http://localhost:9201/solr/collection1/update')
78
+ driver.emit(sample_record)
79
+ driver.run
80
+ assert_requested(solr_request)
81
+ end
82
+
83
+ def test_makebulk
84
+ stub_solr
85
+ driver.emit(sample_record)
86
+ driver.emit(sample_record.merge('age' => 27))
87
+ driver.run
88
+ assert_equal(2, index_cmds.count)
89
+ assert_equal(26, @index_cmds[0]['age'])
90
+ assert_equal(27, @index_cmds[1]['age'])
91
+ end
92
+
93
+ def test_doesnt_add_tag_key_by_default
94
+ stub_solr
95
+ driver.emit(sample_record)
96
+ driver.run
97
+ assert_nil(index_cmds[0]['tag'])
98
+ end
99
+
100
+ def test_adds_tag_key_when_configured
101
+ driver('mytag').configure("include_tag_key true\n")
102
+ stub_solr
103
+ driver.emit(sample_record)
104
+ driver.run
105
+ assert(index_cmds[0].key?('tag'))
106
+ assert_equal(index_cmds[0]['tag'], 'mytag')
107
+ end
108
+
109
+ def test_request_error
110
+ stub_solr_unavailable
111
+ driver.emit(sample_record)
112
+ assert_raise(Net::HTTPFatalError) do
113
+ driver.run
114
+ end
115
+ end
116
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-out-solr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - diogo
8
+ - pitr
9
+ - haruyama
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-12-20 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fluentd
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - '>='
27
+ - !ruby/object:Gem::Version
28
+ version: '0'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - '>='
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ - !ruby/object:Gem::Dependency
44
+ name: webmock
45
+ requirement: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - '>='
48
+ - !ruby/object:Gem::Version
49
+ version: '0'
50
+ type: :development
51
+ prerelease: false
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ description: Solr output plugin for Fluent event collector
58
+ email:
59
+ - team@uken.com
60
+ - haruyama@unixuser.org
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - fluent-plugin-out-solr.gemspec
71
+ - lib/fluent/plugin/out_solr.rb
72
+ - test/helper.rb
73
+ - test/plugin/.rubocop.yml
74
+ - test/plugin/test_out_solr.rb
75
+ homepage: https://github.com/haruyama/fluent-plugin-out-solr
76
+ licenses:
77
+ - MIT
78
+ metadata: {}
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - '>='
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubyforge_project:
95
+ rubygems_version: 2.1.11
96
+ signing_key:
97
+ specification_version: 4
98
+ summary: Solr output plugin for Fluent event collector
99
+ test_files:
100
+ - test/helper.rb
101
+ - test/plugin/.rubocop.yml
102
+ - test/plugin/test_out_solr.rb