fluent-plugin-riak2 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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: []