fluent-plugin-jubatus 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 483f2c695c7f2a74eb89c1e6274b7d17234d5dfc
4
- data.tar.gz: 33367a26b845d3c9373da9351819da2a81192c31
3
+ metadata.gz: 6b3fcff4427e5a827c447714310649fc457706d1
4
+ data.tar.gz: ff03960d8a31f7fe5b28cdb747a8f186072cd7df
5
5
  SHA512:
6
- metadata.gz: 01a003c9b9a64c50bdb80909f04daf90832026395075e38af683ccfcda44e53dff4527f82e966a88b29ab8edd7a7baec62d15df62e1e03525b194744287de794
7
- data.tar.gz: af137d2b712e41d8dda0610bb8c262a4a997b6c6128da152ef63dfe3552dd299f435d4ebf9b6c62b9bf2403479f4adc6c2ef46dd64d96254a81eae54b3c0835f
6
+ metadata.gz: ccadad217cf603b02ceb91db22b33c040faa8ebcade2a9411b73cfa5047d74364c6a8fc720c39b4fb65177e5ad210752a7fa943b567f302c8986a15152674191
7
+ data.tar.gz: 1a4cdfb2aaab487b6779ea7e22d6b4478d77e30b3de19667065bca54767f85ab76e8cbd699c071c6b10a39db232bb05d339012aeb4a1f73627daf1f1bec175cb
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Fluent::Plugin::Jubatus
1
+ # Fluent::Plugin::Jubatus, a plugin for [Fluentd](http://fluentd.org)
2
2
 
3
3
  fluentd pluing for jubatus
4
4
 
data/Rakefile CHANGED
@@ -1 +1,6 @@
1
1
  require "bundler/gem_tasks"
2
+
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
@@ -3,7 +3,7 @@ $:.push File.expand_path('../lib', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = "fluent-plugin-jubatus"
6
- gem.version = "0.0.1"
6
+ gem.version = "0.0.2"
7
7
  gem.authors = ["MATSUMOTO Katsuyoshi"]
8
8
  gem.email = ["matsumoto.katsuyoshi+rubygems@gmail.com"]
9
9
  gem.description = %q{Jubatus output plugin for fluentd}
@@ -19,4 +19,6 @@ Gem::Specification.new do |gem|
19
19
  gem.add_dependency 'jubatus'
20
20
  gem.add_development_dependency "simplecov"
21
21
  gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "pry"
23
+ gem.add_development_dependency "rspec"
22
24
  end
@@ -0,0 +1,99 @@
1
+ require 'jubatus/anomaly/client'
2
+ require 'jubatus/anomaly/types'
3
+ require 'jubatus/classifier/client'
4
+ require 'jubatus/classifier/types'
5
+ require 'jubatus/clustering/client'
6
+ require 'jubatus/clustering/types'
7
+ require 'jubatus/recommender/client'
8
+ require 'jubatus/recommender/types'
9
+
10
+ class FluentdJubatus
11
+ def initialize(type, host, port, name='')
12
+ @jubatus = case type
13
+ when /anomaly/i
14
+ Jubatus::Anomaly::Client::Anomaly.new(host, port, name)
15
+ when /classifier/i
16
+ Jubatus::Classifier::Client::Classifier.new(host, port, name)
17
+ when /clustering/i
18
+ Jubatus::Clustering::Client::Clustering.new(host, port, name)
19
+ when /recommender/i
20
+ Jubatus::Recommender::Client::Recommender.new(host, port, name)
21
+ end
22
+ end
23
+
24
+ def set_datum(data, keys)
25
+ datum = {}
26
+ data.each do |k,v|
27
+ datum[k.to_s] = v.to_f if keys[:num].include?(k.to_s)
28
+ datum[k.to_s] = v.to_s if keys[:str].include?(k.to_s)
29
+ end
30
+ Jubatus::Common::Datum.new(datum)
31
+ end
32
+
33
+ def analyze(type, datum, num = 10)
34
+ case type
35
+ when /anomaly/i
36
+ @jubatus.calc_score(datum)
37
+ when /classifier/i
38
+ @jubatus.classify([datum])
39
+ when /clustering/i
40
+ @jubatus.get_nearest_members(datum)
41
+ when /recommender/i
42
+ @jubatus.similar_row_from_datum(datum, num)
43
+ end
44
+ end
45
+
46
+ def close
47
+ @jubatus.get_client.close
48
+ end
49
+
50
+ def learn(type, datum, key = nil)
51
+ # todo
52
+ end
53
+
54
+ def self.fix_result(type, result)
55
+ case type
56
+ when /anomaly/i
57
+ fix_anomaly(result)
58
+ when /classifier/i
59
+ fix_classifier(result)
60
+ when /clustering/i
61
+ fix_clustering(result)
62
+ when /recommender/i
63
+ fix_clustering(result)
64
+ end
65
+ end
66
+
67
+ private
68
+ def self.fix_anomaly(result)
69
+ result
70
+ end
71
+
72
+ def self.fix_classifier(results)
73
+ r = []
74
+ results.each do |result|
75
+ est = {}
76
+ result.each do |res|
77
+ est[res.label] = res.score
78
+ end
79
+ r << est
80
+ end
81
+ r
82
+ end
83
+
84
+ def self.fix_clustering(results)
85
+ r = {}
86
+ results.each do |result|
87
+ r[result.id] = result.score
88
+ end
89
+ r
90
+ end
91
+
92
+ def self.fix_recommender(results)
93
+ result = {}
94
+ results.each do |r|
95
+ result[r.id] = r.score
96
+ end
97
+ result
98
+ end
99
+ end
@@ -12,18 +12,14 @@ class JubatusOutput < Output
12
12
 
13
13
  def initialize
14
14
  super
15
- require 'jubatus/classifier/client'
16
- require 'jubatus/classifier/types'
17
- require 'jubatus/anomaly/client'
18
- require 'jubatus/anomaly/types'
19
- require 'jubatus/recommender/client'
20
- require 'jubatus/recommender/types'
15
+ require 'fluent/plugin/jubatus'
21
16
  end
22
17
 
23
18
  def configure(conf)
24
19
  super
25
- @str = @str_keys.split(/,/).map{|str| str.strip}
26
- @num = @num_keys.split(/,/).map{|num| num.strip}
20
+ str = @str_keys.split(/,/).map{|key| key.strip }
21
+ num = @num_keys.split(/,/).map{|key| key.strip }
22
+ @keys = {str: str, num: num}
27
23
  end
28
24
 
29
25
  def start
@@ -36,7 +32,7 @@ class JubatusOutput < Output
36
32
 
37
33
  def emit(tag, es, chain)
38
34
  es.each do |time, record|
39
- result = result_format(jubatus_run(record))
35
+ result = result_format(@client_api, jubatus_run(record))
40
36
  Engine.emit(@tag, time, result)
41
37
  end
42
38
 
@@ -45,91 +41,30 @@ class JubatusOutput < Output
45
41
 
46
42
  private
47
43
  def jubatus_run(data)
48
- datum = set_datum(data)
49
- if @learn_analyze =~ /^analyze$/i
50
- analyze(datum)
51
- elsif @learn_analyze =~ /^train$/i
52
- update(datum)
53
- end
54
- end
55
-
56
- def analyze(datum)
57
- case
58
- when @client_api =~ /^classif(y|ier)$/i
59
- classify(datum)
60
- when @client_api =~ /^anomaly$/i
61
- anomaly(datum)
62
- when @client_api =~ /^recommender/i
63
- recommend(datum)
64
- end
65
- rescue => e
66
- e
67
- end
68
-
69
- def update(datum)
70
- jubatus = Jubatus::Classifier::Client::Classifier.new(@host, @port.to_i)
71
- jubatus.train(@name, [datum])
72
- jubatus.get_client.close
73
- rescue => e
74
- e
75
- end
76
-
77
- def set_datum(data)
78
- str = []
79
- num = []
80
- data.each do |key, value|
81
- str << [key, value.to_s] if @str.include?(key)
82
- num << [key, value.to_f] if @num.include?(key)
83
- end
84
- case
85
- when @client_api =~ /^classif(y|ier)$/i
86
- Jubatus::Classifier::Datum.new(str, num)
87
- when @client_api =~ /^anomaly$/i
88
- Jubatus::Anomaly::Datum.new(str, num)
89
- end
90
- end
91
-
92
- def result_format(data)
93
- case
94
- when @client_api =~ /^classifier$/i
95
- result_classify(data)
96
- when @client_api =~ /^anomaly$/i
97
- result_anomaly(data)
98
- end
99
- end
100
-
101
- def classify(datum)
102
- jubatus = Jubatus::Classifier::Client::Classifier.new(@host, @port.to_i)
103
- result = jubatus.classify(@name, [datum])
104
- jubatus.get_client.close()
105
- result
106
- rescue => e
107
- e
108
- end
109
-
110
- def anomaly(datum)
111
- jubatus = Jubatus::Anomaly::Client::Anomaly.new(@host, @port.to_i)
112
- result = jubatus.add(@name, datum)
113
- jubatus.get_client.close()
114
- result
115
- rescue => e
116
- e
117
- end
118
-
119
- def result_classify(data)
120
- result = {}
121
- data.map do |datum|
122
- datum.map do |est|
123
- result[est[0]] = est[1]
44
+ count = 0
45
+ jubatus = FluentdJubatus.new(@client_api, @host, @port, @name)
46
+ begin
47
+ datum = jubatus.set_datum(data, @keys)
48
+ case @learn_analyze
49
+ when /^analyze$/i
50
+ jubatus.analyze(@client_api, datum)
51
+ when /^learn$/i
52
+ # todo
53
+ # jubatus.learn(@client_api, datum)
124
54
  end
55
+ rescue MessagePack::RPC::ConnectionTimeoutError => e
56
+ jubatus.close
57
+ count += 1
58
+ raise e if count > 10
59
+ sleep 0.1
60
+ retry
61
+ rescue => e
62
+ e
125
63
  end
126
- result
127
64
  end
128
65
 
129
- def result_anomaly(data)
130
- value = data[1]
131
- value = data[1].to_s if data[1].to_s == "Infinity"
132
- { id: data[0], value: value }
66
+ def result_format(type, result)
67
+ FluentdJubatus.fix_result(type, result)
133
68
  end
134
69
  end
135
70
  end
@@ -0,0 +1,117 @@
1
+ require File.expand_path(__dir__ + '/spec_helper')
2
+
3
+ describe FluentdJubatus do
4
+ let(:fluent_conf) { {host: '127.0.0.1', port: 9199, name: ''} }
5
+ let(:data) { {a: 'a', b: '1', c: '1.0', d: '-1.0', e: 'f', f: '1,', g: 'str'} }
6
+ let(:keys) { {str:['a','e'], num:['b','c','d']} }
7
+ let(:label) { 'fluentd' }
8
+ let(:jubatus) {
9
+ described_class.new(type, fluent_conf[:host], fluent_conf[:port], fluent_conf[:name])
10
+ }
11
+ let(:datum) { jubatus.set_datum(data, keys) }
12
+ let(:raw_jubatus) { jubatus.instance_variable_get(:@jubatus) }
13
+ let(:result) { described_class.fix_result(type, jubatus.analyze(type, datum)) }
14
+ let(:log) { File.expand_path(__dir__) }
15
+ # This test run only in ubuntu or debian using deb package
16
+ let(:ubuntu) { "/opt/jubatus/share/jubatus/example/config/#{type}" }
17
+
18
+ def startup(path, jubatus_type: type, config_path: path, jubatus_log: log, jubatus_port: fluent_conf[:port])
19
+ @pid = spawn("juba#{jubatus_type} -f #{config_path} -l #{jubatus_log} -p #{jubatus_port}")
20
+ sleep 0.1
21
+ end
22
+
23
+ def stop_jubatus
24
+ Process.kill(9, @pid)
25
+ Process.wait(@pid)
26
+ Dir.glob("./spec/juba#{type}.*").each do |f|
27
+ File.delete(File.expand_path(f))
28
+ end
29
+ end
30
+
31
+ context 'anomaly' do
32
+ let(:type) { 'anomaly' }
33
+
34
+ before do
35
+ startup(ubuntu+'/lof.json')
36
+ raw_jubatus.update(label, datum)
37
+ end
38
+
39
+ after do
40
+ stop_jubatus
41
+ end
42
+
43
+ it 'analyze' do
44
+ expect(jubatus.analyze(type, datum)).to eq(1.to_f)
45
+ end
46
+
47
+ it 'fix results' do
48
+ expect(result).to eq(1.to_f)
49
+ end
50
+ end
51
+
52
+ context 'classifier' do
53
+ let(:type) { 'classifier' }
54
+
55
+ before do
56
+ startup(ubuntu+'/arow.json')
57
+ raw_jubatus.train([[label,datum]])
58
+ end
59
+
60
+ after do
61
+ stop_jubatus
62
+ end
63
+
64
+ it 'analyze' do
65
+ expect(jubatus.analyze(type, datum).first.first.label).to eq(label)
66
+ end
67
+
68
+ it 'fix results' do
69
+ expect(result.size).to eq(1)
70
+ end
71
+ end
72
+
73
+ context 'clustering' do
74
+ let(:type) { 'clustering' }
75
+
76
+ before do
77
+ startup(ubuntu+'/kmeans.json')
78
+ 1000.times do
79
+ raw_jubatus.push([datum])
80
+ end
81
+ end
82
+
83
+ after do
84
+ stop_jubatus
85
+ end
86
+
87
+ it 'analyze' do
88
+ expect(jubatus.analyze(type, datum)).to be_true
89
+ end
90
+
91
+ it 'fix results' do
92
+ pending('which do you need results in nearest center point, or nearest cluster members?')
93
+ expect(result.size).to eq(1)
94
+ end
95
+ end
96
+
97
+ context 'recommender' do
98
+ let(:type) { 'recommender' }
99
+
100
+ before do
101
+ startup(ubuntu+'/inverted_index.json')
102
+ raw_jubatus.update_row(label,datum)
103
+ end
104
+
105
+ after do
106
+ stop_jubatus
107
+ end
108
+
109
+ it 'analyze' do
110
+ expect(jubatus.analyze(type, datum).first.score).to eq(1)
111
+ end
112
+
113
+ it 'fix results' do
114
+ expect(result.size).to eq(1)
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,53 @@
1
+ require File.expand_path(__dir__ + '/spec_helper')
2
+
3
+ describe Fluent::JubatusOutput do
4
+ let(:fluentd){ Fluent::Test::TestDriver.new(described_class) }
5
+ let(:config){
6
+ %[
7
+ type jubatus
8
+ client_api classifier
9
+ host 127.0.0.1
10
+ port 9199
11
+ str_keys first, second, third
12
+ num_keys ichi, ni, san
13
+ learn_analyze analyze
14
+ ]
15
+ }
16
+
17
+ context 'set config params' do
18
+ let(:conf){ fluentd.configure(config).instance }
19
+ it 'string keys' do
20
+ expect(conf.instance_variable_get(:@keys)[:str]).to eq(['first','second','third'])
21
+ end
22
+
23
+ it 'number keys' do
24
+ expect(conf.instance_variable_get(:@keys)[:num]).to eq(['ichi','ni','san'])
25
+ end
26
+
27
+
28
+ it 'client api' do
29
+ expect(conf.client_api).to eq('classifier')
30
+ end
31
+
32
+ it 'host' do
33
+ expect(conf.host).to eq('127.0.0.1')
34
+ end
35
+
36
+ it 'port' do
37
+ expect(conf.port).to eq('9199')
38
+ end
39
+
40
+ it 'learn or analyze' do
41
+ expect(conf.learn_analyze).to eq('analyze')
42
+ end
43
+ end
44
+
45
+ context 'fluentd' do
46
+ let(:classifier){ fluend.configure(config) }
47
+ let(:data){ {first: '10', second: 10, third: "abcd", ichi: 1, ni: "-2", san: '3.0'} }
48
+ it 'emit' do
49
+
50
+ end
51
+ end
52
+ end
53
+
@@ -0,0 +1,10 @@
1
+ require 'simplecov'
2
+
3
+ SimpleCov.start do
4
+ add_filter 'spec'
5
+ end
6
+
7
+ $:.unshift File.expand_path(File.join(__dir__, '..', 'lib'))
8
+ require 'fluent/test'
9
+ require 'fluent/plugin/out_jubatus'
10
+ require 'fluent/plugin/jubatus'
metadata CHANGED
@@ -1,69 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-jubatus
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - MATSUMOTO Katsuyoshi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-08 00:00:00.000000000 Z
11
+ date: 2014-04-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fluentd
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
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
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: jubatus
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '>='
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: simplecov
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '>='
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '>='
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - '>='
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - '>='
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
67
95
  - !ruby/object:Gem::Version
68
96
  version: '0'
69
97
  description: Jubatus output plugin for fluentd
@@ -73,13 +101,17 @@ executables: []
73
101
  extensions: []
74
102
  extra_rdoc_files: []
75
103
  files:
76
- - .gitignore
104
+ - ".gitignore"
77
105
  - Gemfile
78
106
  - LICENSE.txt
79
107
  - README.md
80
108
  - Rakefile
81
109
  - fluent-plugin-jubatus.gemspec
110
+ - lib/fluent/plugin/jubatus.rb
82
111
  - lib/fluent/plugin/out_jubatus.rb
112
+ - spec/jubatus_spec.rb
113
+ - spec/out_jubatus_spec.rb
114
+ - spec/spec_helper.rb
83
115
  homepage: https://github.com/katsyoshi/fluent-plugin-jubatus
84
116
  licenses: []
85
117
  metadata: {}
@@ -89,18 +121,21 @@ require_paths:
89
121
  - lib
90
122
  required_ruby_version: !ruby/object:Gem::Requirement
91
123
  requirements:
92
- - - '>='
124
+ - - ">="
93
125
  - !ruby/object:Gem::Version
94
126
  version: '0'
95
127
  required_rubygems_version: !ruby/object:Gem::Requirement
96
128
  requirements:
97
- - - '>='
129
+ - - ">="
98
130
  - !ruby/object:Gem::Version
99
131
  version: '0'
100
132
  requirements: []
101
133
  rubyforge_project:
102
- rubygems_version: 2.0.3
134
+ rubygems_version: 2.2.2
103
135
  signing_key:
104
136
  specification_version: 4
105
137
  summary: Jubatus output plugin for fluentd
106
- test_files: []
138
+ test_files:
139
+ - spec/jubatus_spec.rb
140
+ - spec/out_jubatus_spec.rb
141
+ - spec/spec_helper.rb