fluent-plugin-dynamodb 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/ChangeLog ADDED
@@ -0,0 +1,8 @@
1
+ Release 0.1.5 - 2012/06/10
2
+
3
+ * First release
4
+
5
+ Release 0.1.0 - 2012/06/09
6
+
7
+ * First commit
8
+
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ # Amazon DynamoDB output plugin for Fluent event collector
2
+
3
+ ##Installation
4
+
5
+ $ fluent-gem install fluent-plugin-dynamodb
6
+
7
+ ##Configuration
8
+
9
+
10
+ ###DynamoDB
11
+
12
+ First of all, you need to create a table in DynamoDB. It's easy to create via Management Console.
13
+
14
+ Specify table name, hash attribute name and throughput as you like. fluent-plugin-dynamodb will load your table schema and write event-stream out to your table.
15
+
16
+ *currently supports only table with a primary key which has a string hash-key. (hash and range key is not supported.)*
17
+
18
+ ### Fluentd
19
+
20
+ <match dynamodb.**>
21
+ type dynamodb
22
+ aws_key_id AWS_ACCESS_KEY
23
+ aws_sec_key AWS_SECRET_ACCESS_KEY
24
+ proxy_uri http://user:password@192.168.0.250:3128/
25
+ dynamo_db_endpoint dynamodb.ap-northeast-1.amazonaws.com
26
+ dynamo_db_table access_log
27
+ </match>
28
+
29
+ * **aws\_key\_id (required)** - AWS access key id.
30
+ * **aws\_sec\_key (required)** - AWS secret key.
31
+ * **proxy_uri (optional)** - your proxy url.
32
+ * **dynamo\_db\_endpoint (required)** - end point of dynamodb. see [Regions and Endpoints](http://docs.amazonwebservices.com/general/latest/gr/rande.html#ddb_region)
33
+ * **dynamo\_db\_table (required)** - table name of dynamodb.
34
+
35
+ ##TODO
36
+
37
+ * auto-create table
38
+ * tag_mapped
39
+ * Multiprocessing
40
+
41
+ ##Copyright
42
+
43
+ <table>
44
+ <tr>
45
+ <td>Copyright</td><td>Copyright (c) 2012- Takashi Matsuno</td>
46
+ </tr>
47
+ <tr>
48
+ <td>License</td><td>Apache License, Version 2.0</td>
49
+ </tr>
50
+ </table>
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rake/testtask'
6
+
7
+ Rake::TestTask.new(:test) do |test|
8
+ test.libs << 'lib' << 'test'
9
+ test.test_files = FileList['test/*.rb']
10
+ test.verbose = true
11
+ end
12
+
13
+ task :default => [:build]
14
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.5
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "fluent-plugin-dynamodb"
6
+ gem.description = "Amazon DynamoDB output plugin for Fluent event collector"
7
+ gem.homepage = "https://github.com/fluent/fluent-plugin-dynamodb"
8
+ gem.summary = gem.description
9
+ gem.version = File.read("VERSION").strip
10
+ gem.authors = ["Takashi Matsuno"]
11
+ gem.email = "g0n5uk3@gmail.com"
12
+ gem.has_rdoc = false
13
+ #gem.platform = Gem::Platform::RUBY
14
+ gem.files = `git ls-files`.split("\n")
15
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ gem.require_paths = ['lib']
18
+
19
+ gem.add_dependency "fluentd", "~> 0.10.0"
20
+ gem.add_dependency "aws-sdk", "~> 1.5.2"
21
+ gem.add_dependency "uuidtools", "~> 2.1.0"
22
+ gem.add_development_dependency "rake", ">= 0.9.2"
23
+ end
@@ -0,0 +1,101 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Fluent
3
+
4
+
5
+ class DynamoDBOutput < Fluent::BufferedOutput
6
+ Fluent::Plugin.register_output('dynamodb', self)
7
+
8
+ BATCHWRITE_ITEM_LIMIT = 25
9
+ BATCHWRITE_CONTENT_SIZE_LIMIT = 1024*1024
10
+
11
+ def initialize
12
+ super
13
+ require 'aws-sdk'
14
+ require 'msgpack'
15
+ require 'time'
16
+ require 'uuidtools'
17
+ end
18
+
19
+ config_param :aws_key_id, :string
20
+ config_param :aws_sec_key, :string
21
+ config_param :proxy_uri, :string, :default => nil
22
+ config_param :dynamo_db_table, :string
23
+ config_param :dynamo_db_endpoint, :string, :default => nil
24
+ config_param :time_format, :string, :default => nil
25
+
26
+ def configure(conf)
27
+ super
28
+
29
+ @timef = TimeFormatter.new(@time_format, @localtime)
30
+ end
31
+
32
+ def start
33
+ super
34
+ options = {
35
+ :access_key_id => @aws_key_id,
36
+ :secret_access_key => @aws_sec_key,
37
+ :dynamo_db_endpoint => @dynamo_db_endpoint,
38
+ }
39
+ options[:proxy_uri] = @proxy_uri if @proxy_uri
40
+
41
+ begin
42
+ restart_session(options)
43
+ valid_table(@dynamo_db_table)
44
+ rescue ConfigError => e
45
+ $log.fatal "ConfigError: Please check your configuration, then restart fluentd. '#{e}'"
46
+ exit!
47
+ rescue Exception => e
48
+ $log.fatal "UnknownError: '#{e}'"
49
+ exit!
50
+ end
51
+ end
52
+
53
+ def restart_session(options)
54
+ config = AWS.config(options)
55
+ @batch = AWS::DynamoDB::BatchWrite.new(config)
56
+ @dynamo_db = AWS::DynamoDB.new(options)
57
+ end
58
+
59
+ def valid_table(table_name)
60
+ table = @dynamo_db.tables[table_name]
61
+ table.load_schema
62
+ raise ConfigError, "Currently composite table is not supported." if table.has_range_key?
63
+ @hash_key_value = table.hash_key.name
64
+ end
65
+
66
+ def format(tag, time, record)
67
+ if !record.key?(@hash_key_value)
68
+ record[@hash_key_value] = UUIDTools::UUID.timestamp_create.to_s
69
+ end
70
+
71
+ [time, record].to_msgpack
72
+ end
73
+
74
+ def write(chunk)
75
+ records = collect_records(chunk)
76
+ item_num = item_size = 0
77
+ records.each {|record|
78
+ item_num += 1
79
+ item_size += record.to_json.length # FIXME: heuristic
80
+ if item_num >= BATCHWRITE_ITEM_LIMIT || item_size >= BATCHWRITE_CONTENT_SIZE_LIMIT
81
+ @batch.process!
82
+ item_num = item_size = 0
83
+ end
84
+ @batch.put(@dynamo_db_table, [record])
85
+ }
86
+ @batch.process!
87
+ end
88
+
89
+ def collect_records(chunk)
90
+ records = []
91
+ chunk.msgpack_each { |time, record|
92
+ record['time'] = @timef.format(time)
93
+ records << record
94
+ }
95
+ records
96
+ end
97
+
98
+ end
99
+
100
+
101
+ end
@@ -0,0 +1,59 @@
1
+ require 'fluent/test'
2
+ require 'fluent/plugin/out_dynamodb'
3
+
4
+ class DynamoDBOutputTest < Test::Unit::TestCase
5
+ def setup
6
+ Fluent::Test.setup
7
+ end
8
+
9
+ CONFIG = %[
10
+ aws_key_id test_key_id
11
+ aws_sec_key test_sec_key
12
+ dynamo_db_table test_table
13
+ dynamo_db_endpoint test.endpoint
14
+ utc
15
+ buffer_type memory
16
+ ]
17
+
18
+ def create_driver(conf = CONFIG)
19
+ Fluent::Test::BufferedOutputTestDriver.new(Fluent::DynamoDBOutput) do
20
+ def write(chunk)
21
+ chunk.read
22
+ end
23
+ end.configure(conf)
24
+ end
25
+
26
+ def test_configure
27
+ d = create_driver
28
+ assert_equal 'test_key_id', d.instance.aws_key_id
29
+ assert_equal 'test_sec_key', d.instance.aws_sec_key
30
+ assert_equal 'test_table', d.instance.dynamo_db_table
31
+ assert_equal 'test.endpoint', d.instance.dynamo_db_endpoint
32
+ end
33
+
34
+ def test_format
35
+ d = create_driver
36
+
37
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
38
+ d.emit({"a"=>1}, time)
39
+ d.emit({"a"=>2}, time)
40
+
41
+ d.expect_format([time, {'a' => 1}].to_msgpack)
42
+ d.expect_format([time, {'a' => 2}].to_msgpack)
43
+
44
+ d.run
45
+ end
46
+
47
+ def test_write
48
+ d = create_driver
49
+
50
+ time = Time.parse("2011-01-02 13:14:15 UTC").to_i
51
+ d.emit({"a"=>1}, time)
52
+ d.emit({"a"=>2}, time)
53
+
54
+ data = d.run
55
+
56
+ assert_equal [time, {'a' => 1}].to_msgpack + [time, {'a' => 2}].to_msgpack, data
57
+ end
58
+
59
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-dynamodb
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.5
6
+ platform: ruby
7
+ authors:
8
+ - Takashi Matsuno
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-06-10 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: fluentd
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 0.10.0
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: aws-sdk
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.5.2
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: uuidtools
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.1.0
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: rake
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: 0.9.2
57
+ type: :development
58
+ version_requirements: *id004
59
+ description: Amazon DynamoDB output plugin for Fluent event collector
60
+ email: g0n5uk3@gmail.com
61
+ executables: []
62
+
63
+ extensions: []
64
+
65
+ extra_rdoc_files: []
66
+
67
+ files:
68
+ - ChangeLog
69
+ - Gemfile
70
+ - README.md
71
+ - Rakefile
72
+ - VERSION
73
+ - fluent-plugin-dynamodb.gemspec
74
+ - lib/fluent/plugin/out_dynamodb.rb
75
+ - test/out_dynamodb.rb
76
+ homepage: https://github.com/fluent/fluent-plugin-dynamodb
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options: []
81
+
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: "0"
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: "0"
96
+ requirements: []
97
+
98
+ rubyforge_project:
99
+ rubygems_version: 1.8.10
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: Amazon DynamoDB output plugin for Fluent event collector
103
+ test_files:
104
+ - test/out_dynamodb.rb