fluent-plugin-pghstore 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,11 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ # For TextMate, emacs, vim
6
+ *.tmproj
7
+ tmtags
8
+ *~
9
+ \#*
10
+ .\#*
11
+ *.swp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-pghstore.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,13 @@
1
+ Copyright (c) 2012- Shirou WAKAYAMA
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.rdoc ADDED
@@ -0,0 +1,76 @@
1
+ = fluent-plugin-pghstore
2
+
3
+ == Component
4
+
5
+ === PgHStoreOutput
6
+
7
+ Output to PostgreSQL hstore database.
8
+
9
+ Output table should have tag, time and record column.:
10
+
11
+ CREATE TABLE #{tablename} (
12
+ tag TEXT,
13
+ time TIMESTAMP WITH TIME ZONE,
14
+ record HSTORE
15
+ );
16
+
17
+ == Requirement
18
+
19
+ - PostgreSQL 9.0 or higher
20
+ - hstore changed at PostgreSQL 9.0.
21
+ - postgres-contrib
22
+ - ruby-pg
23
+
24
+ === How to Install hstore
25
+
26
+ hstore is in the contrib.
27
+
28
+ 9.1 or higher:
29
+
30
+ psql <dbname> -c "CREATE EXTENSION hstore;"
31
+
32
+ 9.0:
33
+
34
+ psql <dbname> -f ${PGHOME}/share/contrib/hstore.sql
35
+
36
+ == Configuration
37
+
38
+ Example:
39
+
40
+ <match apache.*>
41
+ type pghstore
42
+ database test
43
+ table test
44
+ table_option CREATE INDEX time_index ON testb (time);
45
+ </match>
46
+
47
+ === Options
48
+
49
+ - Required
50
+ - database
51
+ - database name
52
+ - Optional
53
+ - table
54
+ - tablename. If not set, use +fluentd_store+. If not exists, creates automatically.
55
+ - host
56
+ - port
57
+ - user
58
+ - password
59
+ - table_option
60
+ - Add some SQL. This SQL is called only once when table is created from this plugin.
61
+
62
+ == Limitation
63
+
64
+ - Nested output is not allowd.
65
+ - Since using only one connection, performance may become bad. When you meet this, use connection pooling and write patch!
66
+
67
+
68
+ == Thanks
69
+
70
+ This source code is mainly borrowed from
71
+ {fluent-plugin-datacounter}{https://rubygems.org/gems/fluent-plugin-datacounter}. Thank you for tagomoris.
72
+
73
+ == Copyright
74
+
75
+ Copyright:: Copyright (c) 2012- Shirou WAKAYAMA
76
+ License:: Apache License
data/Rakefile ADDED
@@ -0,0 +1,12 @@
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.test_files = FileList['test/**/test*.rb']
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
12
+
data/example.conf ADDED
@@ -0,0 +1,13 @@
1
+ <source>
2
+ type tail
3
+ path /var/log/apache/access_log
4
+ tag apache.access
5
+ format apache
6
+ </source>
7
+
8
+ <match apache.*>
9
+ type pghstore
10
+ database test
11
+ table test # (option) default is fluentd_store
12
+ table_option CREATE INDEX time_index ON testb (time); # (option)
13
+ </match>
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "fluent-plugin-pghstore"
6
+ s.version = "0.0.1"
7
+ s.authors = ["WAKAYAMA Shirou"]
8
+ s.email = ["shirou.faw@gmail.com"]
9
+ s.homepage = "https://github.com/r_rudi/fluent-plugin-pghstore"
10
+ s.summary = %q{Output to PostgreSQL database which has a hstore extension}
11
+ s.description = %q{Output to PostgreSQL database which has a hstore extension}
12
+
13
+ s.rubyforge_project = "fluent-plugin-pghstore"
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
+ s.require_paths = ["lib"]
19
+
20
+ # specify any dependencies here; for example:
21
+ s.add_development_dependency "rspec"
22
+ # s.add_runtime_dependency "rest-client"
23
+ s.add_development_dependency "fluentd"
24
+ s.add_development_dependency "pg"
25
+ s.add_runtime_dependency "fluentd"
26
+ s.add_runtime_dependency "pg"
27
+ end
@@ -0,0 +1,102 @@
1
+ class Fluent::PgHStoreOutput < Fluent::BufferedOutput
2
+ Fluent::Plugin.register_output('pghstore', self)
3
+
4
+ config_param :database, :string
5
+ config_param :table, :string, :default => 'fluentd_store'
6
+ config_param :host, :string, :default => 'localhost'
7
+ config_param :port, :integer, :default => 5432
8
+ config_param :user, :string, :default => nil
9
+ config_param :password, :string, :default => nil
10
+
11
+ config_param :table_option, :string, :default => nil
12
+
13
+ def initialize
14
+ super
15
+ require 'pg'
16
+ end
17
+
18
+ def start
19
+ super
20
+
21
+ @conn = get_connection(@database, @host, @port, @user, @password)
22
+
23
+ create_table(@table) unless table_exists?(@table)
24
+
25
+ end
26
+
27
+ def shutdown
28
+ super
29
+
30
+ @conn.close
31
+ end
32
+
33
+ def format(tag, time, record)
34
+ [tag, time, record].to_msgpack
35
+ end
36
+
37
+ def write(chunk)
38
+ chunk.msgpack_each {|(tag, time_str, record)|
39
+ sql = generate_sql(tag, time_str, record)
40
+ @conn.exec(sql)
41
+ }
42
+ end
43
+
44
+ private
45
+
46
+ def generate_sql(tag, time, record)
47
+ kv_list = []
48
+ record.each {|(key,value)|
49
+ begin
50
+ v = Integer(value)
51
+ rescue ArgumentError => e
52
+ kv_list.push("#{key} => \"#{value}\"") # might be string
53
+ else
54
+ kv_list.push("#{key} => #{value}")
55
+ end
56
+ }
57
+
58
+ sql =<<"SQL"
59
+ INSERT INTO #{@table} (tag, time, record) VALUES
60
+ ('#{tag}', '#{Time.at(time)}'::TIMESTAMP WITH TIME ZONE, '#{kv_list.join(",")}');
61
+ SQL
62
+ return sql
63
+ end
64
+
65
+ def get_connection(dbname, host, port, user, password)
66
+ if user
67
+ return PG.connect(:dbname => dbname, :host => host, :port => port,
68
+ :user => user, :password => password)
69
+ else
70
+ return PG.connect(:dbname => dbname, :host => host, :port => port)
71
+ end
72
+ end
73
+
74
+ def table_exists?(table)
75
+ sql =<<"SQL"
76
+ SELECT COUNT(*) FROM pg_tables WHERE tablename = '#{table}';
77
+ SQL
78
+ res = @conn.exec(sql)
79
+ if res[0]["count"] == "1"
80
+ return true
81
+ else
82
+ return false
83
+ end
84
+ end
85
+
86
+ def create_table(tablename)
87
+ sql =<<"SQL"
88
+ CREATE TABLE #{tablename} (
89
+ tag TEXT,
90
+ time TIMESTAMP WITH TIME ZONE,
91
+ record HSTORE
92
+ );
93
+ SQL
94
+
95
+ sql += @table_option if @table_option
96
+
97
+ @conn.exec(sql)
98
+
99
+ $log.warn "#{tablename} table is not exists. created."
100
+ end
101
+
102
+ 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_pghstore'
26
+
27
+ class Test::Unit::TestCase
28
+ end
@@ -0,0 +1,44 @@
1
+ require 'helper'
2
+
3
+ class PGHStoreOutputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ database "testdb"
10
+ table "testtable"
11
+ user "testuser"
12
+ password "testpassword"
13
+ ]
14
+
15
+ def create_driver(conf = CONFIG, tag='test.input')
16
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::PgHStoreOutput, tag).configure(conf)
17
+ end
18
+
19
+ def test_configure
20
+ end
21
+
22
+ def test_format
23
+ d = create_driver
24
+
25
+ # time = Time.parse("2011-01-02 13:14:15 UTC").to_i
26
+ # d.emit({"a"=>1}, time)
27
+ # d.emit({"a"=>2}, time)
28
+
29
+ # d.expect_format %[2011-01-02T13:14:15Z\ttest\t{"a":1}\n]
30
+ # d.expect_format %[2011-01-02T13:14:15Z\ttest\t{"a":2}\n]
31
+
32
+ # d.run
33
+ end
34
+
35
+ def test_write
36
+ d = create_driver
37
+
38
+ # time = Time.parse("2011-01-02 13:14:15 UTC").to_i
39
+ # d.emit({"a"=>1}, time)
40
+ # d.emit({"a"=>2}, time)
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,277 @@
1
+ require 'helper'
2
+
3
+ class DataCounterOutputTest < Test::Unit::TestCase
4
+ def setup
5
+ Fluent::Test.setup
6
+ end
7
+
8
+ CONFIG = %[
9
+ unit minute
10
+ aggregate tag
11
+ input_tag_remove_prefix test
12
+ count_key target
13
+ pattern1 status2xx ^2\\d\\d$
14
+ pattern2 status3xx ^3\\d\\d$
15
+ pattern3 status4xx ^4\\d\\d$
16
+ pattern4 status5xx ^5\\d\\d$
17
+ ]
18
+
19
+ def create_driver(conf = CONFIG, tag='test.input')
20
+ Fluent::Test::OutputTestDriver.new(Fluent::DataCounterOutput, tag).configure(conf)
21
+ end
22
+
23
+ def test_configure
24
+ assert_raise(Fluent::ConfigError) {
25
+ d = create_driver('')
26
+ }
27
+ assert_raise(Fluent::ConfigError) {
28
+ d = create_driver %[
29
+ count_key field
30
+ ]
31
+ }
32
+ assert_raise(Fluent::ConfigError) {
33
+ d = create_driver %[
34
+ pattern1 hoge ^1\\d\\d$
35
+ ]
36
+ }
37
+ assert_raise(Fluent::ConfigError) {
38
+ d = create_driver %[
39
+ count_key field
40
+ pattern2 hoge ^1\\d\\d$
41
+ ]
42
+ }
43
+ assert_raise(Fluent::ConfigError) {
44
+ d = create_driver %[
45
+ count_key field
46
+ pattern1 hoge ^1\\d\\d$
47
+ pattern4 pos ^4\\d\\d$
48
+ ]
49
+ }
50
+ assert_raise(Fluent::ConfigError) {
51
+ d = create_driver %[
52
+ count_key field
53
+ pattern1 hoge ^1\\d\\d$
54
+ pattern2 hoge ^4\\d\\d$
55
+ ]
56
+ }
57
+ d = create_driver %[
58
+ count_key field
59
+ pattern1 ok ^2\\d\\d$
60
+ ]
61
+ assert_equal 60, d.instance.tick
62
+ assert_equal :tag, d.instance.aggregate
63
+ assert_equal 'datacount', d.instance.tag
64
+ assert_nil d.instance.input_tag_remove_prefix
65
+ assert_equal 'field', d.instance.count_key
66
+ assert_equal 'ok ^2\d\d$', d.instance.pattern1
67
+
68
+ d1 = create_driver %[
69
+ unit minute
70
+ count_key field
71
+ pattern1 ok ^2\\d\\d$
72
+ ]
73
+ d2 = create_driver %[
74
+ count_interval 60s
75
+ count_key field
76
+ pattern1 ok ^2\\d\\d$
77
+ ]
78
+ assert_equal d1.instance.tick, d2.instance.tick
79
+
80
+ d = create_driver %[
81
+ count_interval 5m
82
+ count_key field
83
+ pattern1 ok ^2\\d\\d$
84
+ ]
85
+ assert_equal 300, d.instance.tick
86
+
87
+ d = create_driver %[
88
+ count_interval 2h
89
+ count_key field
90
+ pattern1 ok ^2\\d\\d$
91
+ ]
92
+ assert_equal 7200, d.instance.tick
93
+
94
+ d = create_driver %[
95
+ count_interval 30s
96
+ count_key field
97
+ pattern1 ok ^2\\d\\d$
98
+ ]
99
+ assert_equal 30, d.instance.tick
100
+ end
101
+
102
+ def test_count_initialized
103
+ d = create_driver %[
104
+ aggregate all
105
+ count_key field
106
+ pattern1 hoge 1\d\d
107
+ pattern2 moge 2\d\d
108
+ ]
109
+ assert_equal [0,0,0], d.instance.counts['all']
110
+ end
111
+
112
+ def test_countups
113
+ d = create_driver
114
+ assert_nil d.instance.counts['test.input']
115
+
116
+ d.instance.countups('test.input', [0, 0, 0, 0, 0])
117
+ assert_equal [0,0,0,0,0], d.instance.counts['test.input']
118
+ d.instance.countups('test.input', [1, 1, 1, 0, 0])
119
+ assert_equal [1,1,1,0,0], d.instance.counts['test.input']
120
+ d.instance.countups('test.input', [0, 5, 1, 0, 0])
121
+ assert_equal [1,6,2,0,0], d.instance.counts['test.input']
122
+ end
123
+
124
+ def test_stripped_tag
125
+ d = create_driver
126
+ assert_equal 'input', d.instance.stripped_tag('test.input')
127
+ assert_equal 'test.input', d.instance.stripped_tag('test.test.input')
128
+ assert_equal 'input', d.instance.stripped_tag('input')
129
+ end
130
+
131
+ def test_generate_output
132
+ d = create_driver
133
+ r1 = d.instance.generate_output({'test.input' => [60,240,120,180,0], 'test.input2' => [0,600,0,0,0]}, 60)
134
+ assert_equal 60, r1['input_unmatched_count']
135
+ assert_equal 1.0, r1['input_unmatched_rate']
136
+ assert_equal 10.0, r1['input_unmatched_percentage']
137
+ assert_equal 240, r1['input_status2xx_count']
138
+ assert_equal 4.0, r1['input_status2xx_rate']
139
+ assert_equal 40.0, r1['input_status2xx_percentage']
140
+ assert_equal 120, r1['input_status3xx_count']
141
+ assert_equal 2.0, r1['input_status3xx_rate']
142
+ assert_equal 20.0, r1['input_status3xx_percentage']
143
+ assert_equal 180, r1['input_status4xx_count']
144
+ assert_equal 3.0, r1['input_status4xx_rate']
145
+ assert_equal 30.0, r1['input_status4xx_percentage']
146
+ assert_equal 0, r1['input_status5xx_count']
147
+ assert_equal 0.0, r1['input_status5xx_rate']
148
+ assert_equal 0.0, r1['input_status5xx_percentage']
149
+
150
+ assert_equal 0, r1['input2_unmatched_count']
151
+ assert_equal 0.0, r1['input2_unmatched_rate']
152
+ assert_equal 0.0, r1['input2_unmatched_percentage']
153
+ assert_equal 600, r1['input2_status2xx_count']
154
+ assert_equal 10.0, r1['input2_status2xx_rate']
155
+ assert_equal 100.0, r1['input2_status2xx_percentage']
156
+ assert_equal 0, r1['input2_status3xx_count']
157
+ assert_equal 0.0, r1['input2_status3xx_rate']
158
+ assert_equal 0.0, r1['input2_status3xx_percentage']
159
+ assert_equal 0, r1['input2_status4xx_count']
160
+ assert_equal 0.0, r1['input2_status4xx_rate']
161
+ assert_equal 0.0, r1['input2_status4xx_percentage']
162
+ assert_equal 0, r1['input2_status5xx_count']
163
+ assert_equal 0.0, r1['input2_status5xx_rate']
164
+ assert_equal 0.0, r1['input2_status5xx_percentage']
165
+
166
+ d = create_driver %[
167
+ aggregate all
168
+ count_key field
169
+ pattern1 hoge xxx\d\d
170
+ ]
171
+ r2 = d.instance.generate_output({'all' => [60,240]}, 60)
172
+ assert_equal 60, r2['unmatched_count']
173
+ assert_equal 1.0, r2['unmatched_rate']
174
+ assert_equal 20.0, r2['unmatched_percentage']
175
+ assert_equal 240, r2['hoge_count']
176
+ assert_equal 4.0, r2['hoge_rate']
177
+ assert_equal 80.0, r2['hoge_percentage']
178
+ end
179
+
180
+ def test_pattern_num
181
+ assert_equal 20, Fluent::DataCounterOutput::PATTERN_MAX_NUM
182
+
183
+ conf = %[
184
+ aggregate all
185
+ count_key field
186
+ ]
187
+ (1..20).each do |i|
188
+ conf += "pattern#{i} name#{i} ^#{i}$\n"
189
+ end
190
+ d = create_driver(conf, 'test.max')
191
+ d.run do
192
+ (1..20).each do |j|
193
+ d.emit({'field' => j})
194
+ end
195
+ end
196
+ r = d.instance.flush(60)
197
+ assert_equal 1, r['name1_count']
198
+ assert_equal 1, r['name2_count']
199
+ assert_equal 1, r['name3_count']
200
+ assert_equal 1, r['name4_count']
201
+ assert_equal 1, r['name5_count']
202
+ assert_equal 1, r['name6_count']
203
+ assert_equal 1, r['name7_count']
204
+ assert_equal 1, r['name8_count']
205
+ assert_equal 1, r['name9_count']
206
+ assert_equal 1, r['name10_count']
207
+ assert_equal 1, r['name11_count']
208
+ assert_equal 1, r['name12_count']
209
+ assert_equal 1, r['name13_count']
210
+ assert_equal 1, r['name14_count']
211
+ assert_equal 1, r['name15_count']
212
+ assert_equal 1, r['name16_count']
213
+ assert_equal 1, r['name17_count']
214
+ assert_equal 1, r['name18_count']
215
+ assert_equal 1, r['name19_count']
216
+ assert_equal 1, r['name20_count']
217
+ end
218
+
219
+ def test_emit
220
+ d1 = create_driver(CONFIG, 'test.tag1')
221
+ d1.run do
222
+ 60.times do
223
+ d1.emit({'target' => '200'})
224
+ d1.emit({'target' => '100'})
225
+ d1.emit({'target' => '200'})
226
+ d1.emit({'target' => '400'})
227
+ end
228
+ end
229
+ r1 = d1.instance.flush(60)
230
+ assert_equal 120, r1['tag1_status2xx_count']
231
+ assert_equal 2.0, r1['tag1_status2xx_rate']
232
+ assert_equal 50.0, r1['tag1_status2xx_percentage']
233
+
234
+ assert_equal 60, r1['tag1_status4xx_count']
235
+ assert_equal 1.0, r1['tag1_status4xx_rate']
236
+ assert_equal 25.0, r1['tag1_status4xx_percentage']
237
+
238
+ assert_equal 60, r1['tag1_unmatched_count']
239
+ assert_equal 1.0, r1['tag1_unmatched_rate']
240
+ assert_equal 25.0, r1['tag1_unmatched_percentage']
241
+
242
+ assert_equal 0, r1['tag1_status3xx_count']
243
+ assert_equal 0.0, r1['tag1_status3xx_rate']
244
+ assert_equal 0.0, r1['tag1_status3xx_percentage']
245
+ assert_equal 0, r1['tag1_status5xx_count']
246
+ assert_equal 0.0, r1['tag1_status5xx_rate']
247
+ assert_equal 0.0, r1['tag1_status5xx_percentage']
248
+
249
+ d2 = create_driver(%[
250
+ aggregate all
251
+ count_key target
252
+ pattern1 ok 2\\d\\d
253
+ pattern2 redirect 3\\d\\d
254
+ ], 'test.tag2')
255
+ d2.run do
256
+ 60.times do
257
+ d2.emit({'target' => '200'})
258
+ d2.emit({'target' => '300 200'})
259
+ end
260
+ end
261
+ d2.instance.flush_emit(120)
262
+ emits = d2.emits
263
+ assert_equal 1, emits.length
264
+ data = emits[0]
265
+ assert_equal 'datacount', data[0] # tag
266
+ assert_equal 120, data[2]['ok_count']
267
+ assert_equal 1.0, data[2]['ok_rate']
268
+ assert_equal 100.0, data[2]['ok_percentage']
269
+ assert_equal 0, data[2]['redirect_count']
270
+ assert_equal 0.0, data[2]['redirect_rate']
271
+ assert_equal 0.0, data[2]['redirect_percentage']
272
+ assert_equal 0, data[2]['unmatched_count']
273
+ assert_equal 0.0, data[2]['unmatched_rate']
274
+ assert_equal 0.0, data[2]['unmatched_percentage']
275
+ end
276
+
277
+ end
metadata ADDED
@@ -0,0 +1,136 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-pghstore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - WAKAYAMA Shirou
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-03-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
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: fluentd
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: pg
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
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: fluentd
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
+ - !ruby/object:Gem::Dependency
79
+ name: pg
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Output to PostgreSQL database which has a hstore extension
95
+ email:
96
+ - shirou.faw@gmail.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - Gemfile
103
+ - LICENSE.txt
104
+ - README.rdoc
105
+ - Rakefile
106
+ - example.conf
107
+ - fluent-plugin-pghstore.gemspec
108
+ - lib/fluent/plugin/out_pghstore.rb
109
+ - test/helper.rb
110
+ - test/plugin/test_out_pghstore.rb
111
+ - test/plugin/test_out_pghstore.rb.bak
112
+ homepage: https://github.com/r_rudi/fluent-plugin-pghstore
113
+ licenses: []
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements: []
131
+ rubyforge_project: fluent-plugin-pghstore
132
+ rubygems_version: 1.8.21
133
+ signing_key:
134
+ specification_version: 3
135
+ summary: Output to PostgreSQL database which has a hstore extension
136
+ test_files: []