fluent-plugin-riak2 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03e66f7515f40f6b25b945a90dd5e8fd0e3e2bf6
4
+ data.tar.gz: 3c32370f5c55cd950c8c439e8919f8fffed7e98d
5
+ SHA512:
6
+ metadata.gz: d050d1bf3fe03dfc50ba78cffce9df5862d5190de55e6f5727274a485d6d880ab948b791e1363101d8b828322ed07bd3707ef52aa9296890c00fc2bd4f3c43b8
7
+ data.tar.gz: e33348d42363c08598e4450c32201284351e526458cd817a0b0828ff33c73777e385c1d918c6961a0cddeade29c05a2c5be5f8a100d29e8fc2f04ace964e1f35
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ coverage
6
+ InstalledFiles
7
+ lib/bundler/man
8
+ pkg
9
+ rdoc
10
+ spec/reports
11
+ test/tmp
12
+ test/version_tmp
13
+ tmp
14
+ *~
15
+ Gemfile.lock
16
+ # YARD artifacts
17
+ .yardoc
18
+ _yardoc
19
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem "simplecov", :require => false
6
+ gem "uuidtools", :require => ">= 2.1.3"
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ Copyright 2014 Kota UENISHI, Collective Health, Inc.
2
+
3
+ Licensed under the Apache License, Version 2.0 (the "License");
4
+ you may not use this file except in compliance with the License.
5
+ You may obtain a copy of the License at
6
+
7
+ http://www.apache.org/licenses/LICENSE-2.0
8
+
9
+ Unless required by applicable law or agreed to in writing, software
10
+ distributed under the License is distributed on an "AS IS" BASIS,
11
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ See the License for the specific language governing permissions and
13
+ limitations under the License.
data/README.md ADDED
@@ -0,0 +1,74 @@
1
+ [fluent-plugin-riak2](https://github.com/collectivehealth/fluent-plugin-riak2g), a plugin for [Fluentd](http://fluentd.org)
2
+ ==================
3
+
4
+
5
+ `fluent-plugin-riak2` is a fluentd output plugin designed to stuff log messages into a riak cluster.
6
+
7
+ This version is based on the work of [Kota UENISHI's fluent-plugin-riak](https://github.com/kuenishi/fluent-plugin-riak). We are very thankful for his effort and his decision to release the work under the Apache 2 license.
8
+
9
+ `fluent-plugin-riak2` is designed to be used with Riak 2.x clusters and it's yokozuna/solr based search engine. Support for secondary indicies is limited and should be considered deprecated.
10
+
11
+ Riak ( http://github.com/basho/riak ) is an open-source distributed KVS focused on availability.
12
+
13
+ Current status is still proof-of-concept: index setting and its configuration are to be decided. Also performance optimization is required. Another idea is in_tail_riak by using riak post-commit.
14
+
15
+ installation
16
+ ------------
17
+
18
+ ```bash
19
+ $ sudo gem install fluent-plugin-riak2
20
+ ```
21
+
22
+ Notice: you need Riak configured using eleveldb as backend.
23
+
24
+
25
+ fluent.conf example
26
+ -------------------
27
+
28
+ ```
29
+ <match riak2.**>
30
+ type riak2
31
+
32
+ buffer_type memory
33
+ flush_interval 10s
34
+ retry_limit 5
35
+ retry_wait 1s
36
+ buffer_chunk_limit 256m
37
+ buffer_queue_limit 8096
38
+
39
+ # pb port
40
+ nodes 127.0.0.1:8087
41
+ #for cluster, define multiple machines
42
+ #nodes 192.168.100.128:10018 129.168.100.128:10028
43
+ </match>
44
+
45
+ ```
46
+
47
+ - key format -> 2013-02-<uuid>
48
+ - value format -> [records] in JSON
49
+ - index:
50
+
51
+ - year_int -> year
52
+ - month_bin -> <year>-<month>
53
+ - tag_bin -> tags
54
+
55
+ easy querying log
56
+ -----------------
57
+
58
+ ```bash
59
+ $ curl -X PUT http://localhost:8098/buckets/static/keys/browser.html -H 'Content-type: text/html' -d @browser.html
60
+ $ open http://localhost:8098/buckets/static/keys/browser.html
61
+ ```
62
+
63
+ License
64
+ =======
65
+
66
+ Apache 2.0
67
+
68
+ Copyright Kota UENISHI, Collective Health, Inc.
69
+
70
+ Kota UENISHI's original message:
71
+
72
+ Many Thanks to fluent-plugin-mongo
73
+
74
+ Collective Health, Inc. would like to thank Kota UENISHI for his effort and his decision to release the work under the Apache 2 license.
data/Rakefile ADDED
@@ -0,0 +1,17 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new(:test) do |test|
7
+ test.libs << 'lib' << 'test'
8
+ test.test_files = FileList['test/plugin/*.rb']
9
+ test.verbose = true
10
+ end
11
+
12
+ task :coverage do |t|
13
+ ENV['SIMPLE_COV'] = '1'
14
+ Rake::Task["test"].invoke
15
+ end
16
+
17
+ task :default => [:build]
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.4
data/browser.html ADDED
@@ -0,0 +1,178 @@
1
+ <html>
2
+ <head>
3
+ <title>Riak mapreducer</title>
4
+ <style type="text/css">
5
+ body {
6
+ background: #678; text-align: center; width: 100%; font-family: 'Titillium', Monospace;
7
+ }
8
+ body div {
9
+ width: 80%; background: #ddd;
10
+ padding: 20px; text-align: left; margin: 0px auto;
11
+ }
12
+ h2 {
13
+ padding: 0px;
14
+ margin: 0px auto;
15
+ }
16
+ a {
17
+ text-shadow: 1px 1px #888888;
18
+ text-decoration:underline;
19
+ }
20
+ </style>
21
+ <script lang="JavaScript">
22
+ function get_map(){ return document.getElementById("map").value; }
23
+ function get_reduce(){ return document.getElementById("reduce").value; }
24
+ function get_bucketname(){ return document.getElementById("bucket").value; }
25
+ function exec_query(m, r){
26
+ var q = { inputs : get_bucketname(),
27
+ query : [
28
+ { map: { language: "javascript", source: m}},
29
+ { reduce: { language: "javascript", source: r}}
30
+ ]};
31
+ var xmlhttp = new XMLHttpRequest();
32
+ xmlhttp.open("POST", "/mapred", false);
33
+ xmlhttp.setRequestHeader("Content-Type", "application/json");
34
+ xmlhttp.send(JSON.stringify(q, null, ""));
35
+ var result = xmlhttp.responseText;
36
+
37
+ var resultBox = document.getElementById("result");
38
+ resultBox.innerText = result;
39
+ }
40
+ </script>
41
+ </head>
42
+
43
+ <body>
44
+ <div id="content">
45
+ <div style="text-align:right">
46
+ <script lang="JavaScript">
47
+ </script>
48
+ bucket name:<input type="text" id="bucket" value="fluentlog"/>
49
+ </div>
50
+
51
+ <h2>Run mapreduce on fluentd log</h2>
52
+ <table style="border: 1px solid black;">
53
+ <tr>
54
+ <th>map</th> <th>reduce</th>
55
+ </tr>
56
+ <tr>
57
+ <td>
58
+ <textarea name="map" id="map" rows="16" cols="50">
59
+ function(v){
60
+ var data = v.values[0].data;
61
+ var c = JSON.parse(data);
62
+ return [c.count];
63
+ }
64
+ </textarea>
65
+ </td><td>
66
+ <textarea name="reduce" id="reduce" rows="16" cols="50" >
67
+ function(v){
68
+ var sum = 0;
69
+ for( var i=0; i < v.length; ++i){
70
+ sum += v[i];
71
+ }
72
+ return [sum];
73
+ }
74
+ </textarea>
75
+ </td>
76
+ </tr>
77
+ <tr>
78
+ <th colspan="2"> <a onClick="exec_query(get_map(), get_reduce());">query</a> </th>
79
+ </tr>
80
+ <tr>
81
+ <td width="200px" colspan="2">
82
+ <div id="result" style="font: bold;"></div>
83
+ </td>
84
+ </tr>
85
+ <tr><td colspan="3">
86
+ <script lang="JavaScript">
87
+ function grep(){
88
+
89
+ }
90
+ </script>
91
+ <script lang="JavaScript" type="text/javascript">
92
+ function count_rank(){
93
+ var m = "function(v){
94
+ var data = v.values[0].data;
95
+ var c = JSON.parse(data);
96
+ var tags = {};
97
+ for(var i=0; i<c.length; ++i){
98
+ count = tags[c[i].tag];
99
+ if(count == null){ tags[c[i].tag] = 1; }
100
+ else{ tags[c[i].tag] = count+1; }
101
+ }
102
+ return [tags];
103
+ }";
104
+ var r = "function(v){
105
+ var tags = {};
106
+ for(var i=0; i<v.length; ++i){
107
+ for (var prop in v[i]) {
108
+ count = tags[prop];
109
+ if(count == null){ tags[prop] = v[i][prop]; }
110
+ else{ tags[prop] = count+v[i][prop]; }
111
+ }
112
+ }
113
+ return [tags];
114
+ }";
115
+ exec_query(m, r);
116
+ }
117
+ </script>
118
+
119
+ <!-- <a onClick="grep();">grep</a> <input type="text" id="grep" value="debug"/> -->
120
+ <a onClick="count_rank();">count&amp;rank</a> <input type="text" id="count_rank" value="tag"/>
121
+ </td></tr>
122
+ </table>
123
+
124
+ <hr/>
125
+ <h2>Riak object viewer</h2>
126
+ <script lang="JavaScript">
127
+ function get(){
128
+ var key = document.getElementById("key").value;
129
+ var xmlhttp = new XMLHttpRequest();
130
+ xmlhttp.open("GET", "/buckets/"+ get_bucketname() +"/keys/"+key, false);
131
+ xmlhttp.send();
132
+ var result = xmlhttp.responseText;
133
+ console.log(result);
134
+ document.getElementById("object").innerText = result;
135
+ }
136
+ </script>
137
+ <a onClick="get();" >get</a> <input type="text" id="key" />
138
+ <div id="object"></div>
139
+
140
+
141
+ <h2>Riak keylister</h2>
142
+ <script lang="JavaScript">
143
+ function listkeys(){
144
+ var xmlhttp = new XMLHttpRequest();
145
+ xmlhttp.open("GET", "/buckets/"+ get_bucketname() +"/keys?keys=true", false);
146
+ xmlhttp.send();
147
+ var result = JSON.parse(xmlhttp.responseText);
148
+ console.log(result);
149
+
150
+ document.getElementById("keylist").innerText = result.keys.sort().join("\n");
151
+ }
152
+ </script>
153
+ <a onClick="listkeys();" >listkeys</a>
154
+ <div id="keylist"></div>
155
+ <hr/>
156
+ (C)@kuenishi distributed under Apache 2 license
157
+ </div>
158
+ <!--
159
+ <h2>Riak object putter</h2>
160
+ <script lang="JavaScript">
161
+ function put(){
162
+ var key = document.getElementById("key2").value;
163
+ var value = document.getElementById("value").value;
164
+ var xmlhttp = new XMLHttpRequest();
165
+ xmlhttp.open("PUT", "/buckets/fluentlog/keys/"+key, false);
166
+ xmlhttp.setRequestHeader("Content-Type", "application/json");
167
+ xmlhttp.send(value);
168
+ var result = xmlhttp.responseText;
169
+ console.log(result);
170
+ document.getElementById("object2").innerText = result;
171
+ }
172
+ </script>
173
+ <a onClick="put();" >put</a> <input type="text" id="key2" /> <input type="text" id="value" />
174
+ <div id="object2"></div>
175
+ -->
176
+
177
+ </body>
178
+ </html>
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-riak2"
6
+ gem.description = "Riak 2.x plugin for Fluent event collector"
7
+ gem.homepage = "https://github.com/collectivehealth/fluent-plugin-riak2"
8
+ gem.summary = gem.description
9
+ gem.version = File.read("VERSION").strip
10
+ gem.license = 'Apache-2.0'
11
+ gem.authors = ["Kota UENISHI", "Matt Nunogawa"]
12
+ gem.email = "matt@collectivehealth.com"
13
+ gem.has_rdoc = false
14
+ #gem.platform = Gem::Platform::RUBY
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency "fluentd", "~> 0.10"
21
+ gem.add_dependency "riak-client", "~> 2.1.0"
22
+ gem.add_dependency "uuidtools", ">= 2.1.3"
23
+ gem.add_development_dependency "rake", ">= 0.9.2"
24
+ gem.add_development_dependency "simplecov", ">= 0.5.4"
25
+ gem.add_development_dependency "rr", ">= 1.0.0"
26
+ end
@@ -0,0 +1,80 @@
1
+ module Fluent
2
+
3
+ class Riak2Output < BufferedOutput
4
+
5
+ Fluent::Plugin.register_output('riak2', self)
6
+ include SetTimeKeyMixin
7
+ config_set_default :include_tag_key, true
8
+ include SetTagKeyMixin
9
+ config_set_default :include_time_key, true
10
+
11
+ config_param :bucket_name, :string, :default => "fluentlog"
12
+ config_param :nodes, :string, :default => "localhost:8087"
13
+
14
+ def initialize
15
+ super
16
+ require 'riak'
17
+ require 'msgpack'
18
+ require 'uuidtools'
19
+ end
20
+
21
+ def configure(conf)
22
+ super
23
+
24
+ @nodes = @nodes.split(',').map{ |s|
25
+ ip,port = s.split(':')
26
+ {:host => ip, :pb_port => port.to_i}
27
+ }
28
+ $log.info "riak nodes=#{@nodes}"
29
+ end
30
+
31
+ def start
32
+ $log.debug " => #{@buffer.chunk_limit} #{@buffer.queue_limit} "
33
+ @conn = Riak::Client.new(:nodes => @nodes)
34
+ @bucket = @conn.bucket(@bucket_name)
35
+ @buf = {}
36
+
37
+ super
38
+ end
39
+
40
+ def format(tag, time, record)
41
+ [time, tag, record].to_msgpack
42
+ end
43
+
44
+ def write(chunk)
45
+ $log.debug " <<<<<===========\n"
46
+
47
+ records = []
48
+ tags = []
49
+ chunk.msgpack_each { |time, tag, record|
50
+ record[@tag_key] = tag
51
+ tags << tag
52
+ records << record
53
+ $log.debug record
54
+ }
55
+ put_now(records, tags)
56
+ end
57
+
58
+ private
59
+
60
+ # TODO: add index for some analysis
61
+ def put_now(records, tags)
62
+ if not records.empty? then
63
+ today = Date.today
64
+ key = "#{today.to_s}-#{UUIDTools::UUID.timestamp_create.to_s}"
65
+ robj = Riak::RObject.new(@bucket, key)
66
+ robj.raw_data = records.to_json
67
+ robj.indexes['year_int'] << today.year
68
+ robj.indexes['month_bin'] << "#{today.year}-#{"%02d" % today.month}"
69
+ tags.each do |tag|
70
+ robj.indexes['tag_bin'] << tag
71
+ end
72
+ robj.content_type = 'application/json'
73
+ robj.store
74
+ robj
75
+ end
76
+ end
77
+
78
+ end
79
+
80
+ end
data/listkeys.rb ADDED
@@ -0,0 +1,36 @@
1
+ require 'riak'
2
+
3
+ nodes = [{ :host => "127.0.0.1",
4
+ :pb_port => 8087 }]
5
+
6
+
7
+ c = Riak::Client.new( :nodes => nodes, :protocol => "pbc" )
8
+ #c.list_buckets
9
+ b = c.bucket("fluentlog")
10
+
11
+ def put(bucket)
12
+ o = Riak::RObject.new(bucket, "hoge")
13
+ o.content_type = "text/plain"
14
+ o.raw_data = "hogehoge"
15
+ o.store
16
+ end
17
+
18
+ def get(bucket)
19
+ o = bucket.get("hoge")
20
+ p o.content_type
21
+ p o.raw_data
22
+ end
23
+
24
+ def keys(bucket)
25
+ bucket.keys { |ks|
26
+ ks.each { |k|
27
+ o = bucket.get(k)
28
+ print "#{o.bucket.name}/#{o.key} (#{o.content_type})\n"
29
+ print " => #{o.raw_data}\n"
30
+ }
31
+ }
32
+ end
33
+
34
+ #put b
35
+ #get b
36
+ keys b
data/setup_index.sh ADDED
@@ -0,0 +1,11 @@
1
+ #!/bin/sh
2
+
3
+ HOST=$1
4
+
5
+ echo setting up fluentlog_index at $HOST
6
+ curl -X PUT http://${HOST}/yz/index/fluentlog_index
7
+ echo "setting fluentlog_index to fluentlog bucket"
8
+ curl -X PUT http://${HOST}/buckets/fluentlog/props -H 'Content-type:application/json' -d '{"props":{"yz_index":"fluentlog_index"}}'
9
+
10
+ curl http://${HOST}/yz/index?index=true
11
+ curl http://${HOST}/buckets/fluentlog/props
metadata ADDED
@@ -0,0 +1,139 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-riak2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.4
5
+ platform: ruby
6
+ authors:
7
+ - Kota UENISHI
8
+ - Matt Nunogawa
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-12-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: fluentd
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ~>
19
+ - !ruby/object:Gem::Version
20
+ version: '0.10'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ version: '0.10'
28
+ - !ruby/object:Gem::Dependency
29
+ name: riak-client
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 2.1.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ~>
40
+ - !ruby/object:Gem::Version
41
+ version: 2.1.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: uuidtools
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - '>='
47
+ - !ruby/object:Gem::Version
48
+ version: 2.1.3
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - '>='
54
+ - !ruby/object:Gem::Version
55
+ version: 2.1.3
56
+ - !ruby/object:Gem::Dependency
57
+ name: rake
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - '>='
61
+ - !ruby/object:Gem::Version
62
+ version: 0.9.2
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - '>='
68
+ - !ruby/object:Gem::Version
69
+ version: 0.9.2
70
+ - !ruby/object:Gem::Dependency
71
+ name: simplecov
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 0.5.4
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - '>='
82
+ - !ruby/object:Gem::Version
83
+ version: 0.5.4
84
+ - !ruby/object:Gem::Dependency
85
+ name: rr
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - '>='
89
+ - !ruby/object:Gem::Version
90
+ version: 1.0.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - '>='
96
+ - !ruby/object:Gem::Version
97
+ version: 1.0.0
98
+ description: Riak 2.x plugin for Fluent event collector
99
+ email: matt@collectivehealth.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - Gemfile
106
+ - LICENSE
107
+ - README.md
108
+ - Rakefile
109
+ - VERSION
110
+ - browser.html
111
+ - fluent-plugin-riak2.gemspec
112
+ - lib/fluent/plugin/out_riak2.rb
113
+ - listkeys.rb
114
+ - setup_index.sh
115
+ homepage: https://github.com/collectivehealth/fluent-plugin-riak2
116
+ licenses:
117
+ - Apache-2.0
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.0.14
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: Riak 2.x plugin for Fluent event collector
139
+ test_files: []