fluent-plugin-dynamodb-streams 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1fb8047ed140d8f219d2ef602911c1c74cb1f894
4
+ data.tar.gz: cb6f8f23baf265dee02865a9607e6bc159524ef1
5
+ SHA512:
6
+ metadata.gz: 7944a9e15f65e021c653ac4c9c9d6029ba1b7a7309aa307c932896535d6a5956712e61942441863929647cc7864704c1274ceb6c60dfaf7c3f6e370a9686d07c
7
+ data.tar.gz: baa75db2e7d1bc2b130f79e81da2a359cb1b7072d5437026c75255fb38dcdba82d3771580aa3f7c313fbe95b89f6340c8a5968bfeb7e30c9307319541b826f63
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ - 2.1
5
+ - 2.0.0
6
+ - 1.9.3
7
+ before_script:
8
+ - bundle exec dynamodb-local -inMemory &
9
+ - sleep 5
10
+ script:
11
+ - bundle exec rake test
12
+ - bundle exec rake build
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :test do
6
+ gem "codeclimate-test-reporter", require: nil
7
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Takumi Sakamoto
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,99 @@
1
+ # fluent-plugin-dynamodb-streams
2
+
3
+ [![Build Status](https://travis-ci.org/takus/fluent-plugin-dynamodb-streams.svg?branch=master)](https://travis-ci.org/takus/fluent-plugin-dynamodb-streams)
4
+ [![Code Climate](https://codeclimate.com/github/takus/fluent-plugin-dynamodb-streams/badges/gpa.svg)](https://codeclimate.com/github/takus/fluent-plugin-dynamodb-streams)
5
+ [![Test Coverage](https://codeclimate.com/github/takus/fluent-plugin-dynamodb-streams/badges/coverage.svg)](https://codeclimate.com/github/takus/fluent-plugin-dynamodb-streams/coverage)
6
+
7
+ Fluentd input plugin for [AWS DynamoDB Streams](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html).
8
+
9
+ ## Preparation
10
+
11
+ Create IAM user with a policy like the following.
12
+
13
+ ```
14
+ {
15
+ "Version": "2012-10-17",
16
+ "Statement": [
17
+ {
18
+ "Effect": "Allow",
19
+ "Action": [
20
+ "dynamodb:GetRecords",
21
+ "dynamodb:GetShardIterator",
22
+ "dynamodb:DescribeStream",
23
+ "dynamodb:ListStreams"
24
+ ],
25
+ "Resource": "*"
26
+ }
27
+ ]
28
+ }
29
+ ```
30
+
31
+ Or define `aws_key_id` and `aws_sec_key` in your config file.
32
+
33
+ ## Installation
34
+
35
+ Add this line to your application's Gemfile:
36
+
37
+ ```ruby
38
+ gem 'fluent-plugin-dynamodb-streams'
39
+ ```
40
+
41
+ And then execute:
42
+
43
+ $ bundle
44
+
45
+ Or install it yourself as:
46
+
47
+ $ gem install fluent-plugin-dynamodb-streams
48
+
49
+ ## Configuration
50
+
51
+ ```apache
52
+ <source>
53
+ type dynamodb_streams
54
+ #aws_key_id AWS_ACCESS_KEY_ID
55
+ #aws_sec_key AWS_SECRET_ACCESS_KEY
56
+ #aws_region AWS_DEFAULT_REGION
57
+ stream_arn arn:aws:dynamodb:ap-northeast-1:000000000000:table/table_name/stream/2015-01-01T00:00:00.000
58
+ pos_file /var/lib/fluent/dynamodb_streams_table_name
59
+ fetch_interval 1
60
+ fetch_size 1
61
+ </source>
62
+ ```
63
+
64
+ - `tag`: Fluentd tag.
65
+ - `stream_arn`: DynamoDB Streams ARN.
66
+ - `pos_file`: File to store last sequence number.
67
+ - `fetch_interval`: The interval to fetch records in seconds. Default is 1 sec.
68
+ - `fetch_size`: The maximum number of records fetches in each iteration. Default is 1.
69
+
70
+ ## Output
71
+
72
+ ```javascript
73
+ {
74
+ "aws_region": "ap-northeast-1",
75
+ "event_source": "aws:dynamodb",
76
+ "event_version": "1.0",
77
+ "event_id": "dfbdf4fe-6f2b-4b34-9b17-4b8caae561fa",
78
+ "event_name": "INSERT",
79
+ "dynamodb": {
80
+ "stream_view_type": "NEW_AND_OLD_IMAGES",
81
+ "sequence_number": "000000000000000000001",
82
+ "size_bytes": 14,
83
+ "keys": {
84
+ "key": "value2"
85
+ },
86
+ "old_image": {
87
+ "key": "value1"
88
+ },
89
+ "new_image": {
90
+ "key": "value2"
91
+ }
92
+ }
93
+ }
94
+ ```
95
+
96
+ ## TODO
97
+
98
+ - store sequence number to DynamoDB
99
+ - fetch records from each shards concurrently
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'rake/testtask'
4
+
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'test'
7
+ test.test_files = FileList['test/plugin/*.rb']
8
+ end
9
+
@@ -0,0 +1,22 @@
1
+ <source>
2
+ type dynamodb_streams
3
+ tag stream
4
+ aws_region ddblocal
5
+ stream_arn "#{ENV['STREAM_ARN']}"
6
+ </source>
7
+
8
+ # Only pass MODIFY event
9
+ <filter stream>
10
+ type grep
11
+ regexp1 event_name MODIFY
12
+ </filter>
13
+
14
+ # Only keep new_image
15
+ <filter stream>
16
+ type jq
17
+ jq '.dynamodb|{new_image:.new_image}'
18
+ </filter>
19
+
20
+ <match stream>
21
+ type stdout
22
+ </match>
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "fluent-plugin-dynamodb-streams"
7
+ spec.version = "0.0.1"
8
+ spec.authors = ["Takumi Sakamoto"]
9
+ spec.email = ["takumi.saka@gmail.com"]
10
+ spec.summary = %q{Amazon DynamoDB Streams input plugin for Fluentd}
11
+ spec.description = %q{Amazon DynamoDB Streams input plugin for Fluentd}
12
+ spec.homepage = "https://github.com/takus/fluent-plugin-dynamodb-streams"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "fluentd", [">= 0.10.58", "< 2"]
21
+ spec.add_dependency "aws-sdk", '~> 2'
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "test-unit", ">= 3.1.0"
26
+ spec.add_development_dependency "dynamodb-local"
27
+ end
@@ -0,0 +1,192 @@
1
+ module Fluent
2
+ class DynamoDBStreamsInput < Input
3
+ Fluent::Plugin.register_input('dynamodb_streams', self)
4
+
5
+ # Define `router` method of v0.12 to support v0.10 or earlier
6
+ unless method_defined?(:router)
7
+ define_method("router") { Fluent::Engine }
8
+ end
9
+
10
+ def initialize
11
+ super
12
+ require 'aws-sdk'
13
+ require 'bigdecimal'
14
+ end
15
+
16
+ config_param :tag, :string
17
+ config_param :aws_key_id, :string, :default => nil, :secret => true
18
+ config_param :aws_sec_key, :string, :default => nil, :secret => true
19
+ config_param :aws_region, :string, :default => "ap-northeast-1"
20
+ config_param :stream_arn, :string
21
+ config_param :fetch_interval, :time, :default => 1
22
+ config_param :fetch_size, :integer, :default => 1
23
+ config_param :pos_file, :string, :default => nil
24
+
25
+ def configure(conf)
26
+ super
27
+
28
+ if @aws_region == "ddblocal"
29
+ @aws_region = "ap-northeast-1" # dummy settings
30
+ @stream_endpoint = "http://localhost:8000"
31
+ else
32
+ @stream_endpoint = "https://streams.dynamodb.#{@aws_region}.amazonaws.com"
33
+ end
34
+
35
+ unless @pos_file
36
+ log.warn "dynamodb-streams: 'pos_file PATH' parameter is not set to a 'dynamodb-streams' source."
37
+ log.warn "dynamodb-streams: this parameter is highly recommended to save the position to resume."
38
+ end
39
+ end
40
+
41
+ def start
42
+ super
43
+
44
+ unless @pos_file
45
+ @pos_memory = {}
46
+ end
47
+
48
+ options = {}
49
+ options[:region] = @aws_region if @aws_region
50
+ options[:credentials] = Aws::Credentials.new(@aws_key_id, @aws_sec_key) if @aws_key_id && @aws_sec_key
51
+ options[:endpoint] = @stream_endpoint
52
+ @client = Aws::DynamoDBStreams::Client.new(options)
53
+
54
+ @running = true
55
+ @thread = Thread.new(&method(:run))
56
+ end
57
+
58
+ def shutdown
59
+ @running = false
60
+ @thread.join
61
+ end
62
+
63
+ def run
64
+ while @running
65
+ sleep @fetch_interval
66
+
67
+ @client.describe_stream({
68
+ stream_arn: @stream_arn
69
+ }).stream_description.shards.each do |s|
70
+
71
+ if s.sequence_number_range.ending_sequence_number
72
+ remove_sequence(s.shard_id)
73
+ next
74
+ end
75
+
76
+ if load_sequence(s.shard_id)
77
+ iterator = @client.get_shard_iterator({
78
+ stream_arn: @stream_arn,
79
+ shard_id: s.shard_id,
80
+ shard_iterator_type: "AFTER_SEQUENCE_NUMBER",
81
+ sequence_number: load_sequence(s.shard_id),
82
+ }).shard_iterator
83
+ else
84
+ iterator = @client.get_shard_iterator({
85
+ stream_arn: @stream_arn,
86
+ shard_id: s.shard_id,
87
+ shard_iterator_type: "TRIM_HORIZON",
88
+ }).shard_iterator
89
+ end
90
+
91
+ resp = @client.get_records({
92
+ shard_iterator: iterator,
93
+ limit: @fetch_size,
94
+ })
95
+
96
+ resp.records.each do |r|
97
+ begin
98
+ emit(r)
99
+ rescue => e
100
+ log.error "dynamodb-streams: error has occoured.", error: e.message, error_class: e.class
101
+ end
102
+ save_sequence(s.shard_id, r.dynamodb.sequence_number)
103
+ end
104
+ end
105
+ end
106
+ end
107
+
108
+ def load_sequence(shard_id)
109
+ if @pos_file
110
+ return nil unless File.exist?("#{@pos_file}.#{shard_id}")
111
+ File.read("#{@pos_file}.#{shard_id}").chomp
112
+ else
113
+ return nil unless @pos_memory[shard_id]
114
+ @pos_memory[shard_id]
115
+ end
116
+ end
117
+
118
+ def save_sequence(shard_id, sequence)
119
+ if @pos_file
120
+ open("#{@pos_file}.#{shard_id}", 'w') do |f|
121
+ f.write sequence
122
+ end
123
+ else
124
+ @pos_memory[shard_id] = sequence
125
+ end
126
+ sequence
127
+ end
128
+
129
+ def remove_sequence(shard_id)
130
+ if @pos_file
131
+ return unless File.exist?("#{@pos_file}.#{shard_id}")
132
+ File.unlink("#{@pos_file}.#{shard_id}")
133
+ else
134
+ @pos_memory[shard_id] = nil
135
+ end
136
+ end
137
+
138
+ def emit(r)
139
+ record = {
140
+ "aws_region" => r.aws_region,
141
+ "event_source" => r.event_source,
142
+ "event_version" => r.event_version,
143
+ "event_id" => r.event_id,
144
+ "event_name" => r.event_name,
145
+ "dynamodb" => {
146
+ "stream_view_type" => r.dynamodb.stream_view_type,
147
+ "sequence_number" => r.dynamodb.sequence_number,
148
+ "size_bytes" => r.dynamodb.size_bytes,
149
+ }
150
+ }
151
+ record["dynamodb"]["keys"] = dynamodb_to_hash(r.dynamodb.keys) if r.dynamodb.keys
152
+ record["dynamodb"]["old_image"] = dynamodb_to_hash(r.dynamodb.old_image) if r.dynamodb.old_image
153
+ record["dynamodb"]["new_image"] = dynamodb_to_hash(r.dynamodb.new_image) if r.dynamodb.new_image
154
+ router.emit(@tag, Time.now.to_i, record)
155
+ end
156
+
157
+ def dynamodb_to_hash(hash)
158
+ hash.each do |k, v|
159
+ # delete binary attributes
160
+ if v.b || v.bs
161
+ hash.delete(k)
162
+ else
163
+ hash[k] = format_attribute_value(v)
164
+ end
165
+ end
166
+ return hash
167
+ end
168
+
169
+ def format_attribute_value(v)
170
+ if v.m
171
+ return dynamodb_to_hash(v.m)
172
+ elsif v.l
173
+ return v.l.map {|i| format_attribute_value(i) }
174
+ elsif v.ns
175
+ return v.ns.map {|i| BigDecimal.new(i).to_i }
176
+ elsif v.ss
177
+ return v.ss
178
+ elsif v.null
179
+ return null
180
+ elsif v.bool
181
+ return v.bool
182
+ elsif v.n
183
+ return BigDecimal.new(v.n).to_i
184
+ elsif v.s
185
+ return v.s
186
+ else
187
+ log.warn "dynamodb-streams: unknown attribute value."
188
+ end
189
+ end
190
+
191
+ end
192
+ end
@@ -0,0 +1,88 @@
1
+ require "test_helper"
2
+
3
+ class DynamoDBStreamsInputTest < Test::Unit::TestCase
4
+ include DynamoDBStreamsTestHelper
5
+
6
+ def setup
7
+ Fluent::Test.setup
8
+ end
9
+
10
+ def test_configure
11
+ d = create_driver(
12
+ %[
13
+ tag streams
14
+ aws_key_id test_key_id
15
+ aws_sec_key test_sec_key
16
+ aws_region ap-northeast-1
17
+ stream_arn arn:aws:dynamodb:ap-northeast-1:123456789012:table/fluent-plugin-dynamodb-streams/stream/2015-09-01T00:00:00.000
18
+ pos_file /tmp/fluent-plugin-dynamodb-streams.pos
19
+ fetch_interval 5
20
+ fetch_size 100
21
+ ]
22
+ )
23
+
24
+ assert_equal 'test_key_id', d.instance.aws_key_id
25
+ assert_equal 'test_sec_key', d.instance.aws_sec_key
26
+ assert_equal 'ap-northeast-1', d.instance.aws_region
27
+ assert_equal 'arn:aws:dynamodb:ap-northeast-1:123456789012:table/fluent-plugin-dynamodb-streams/stream/2015-09-01T00:00:00.000', d.instance.stream_arn
28
+ assert_equal '/tmp/fluent-plugin-dynamodb-streams.pos', d.instance.pos_file
29
+ assert_equal 5.0, d.instance.fetch_interval
30
+ assert_equal 100, d.instance.fetch_size
31
+ end
32
+
33
+ def test_emit
34
+ delete_table
35
+ create_table
36
+
37
+ time_ms = (Time.now.to_f * 1000).floor
38
+
39
+ d = create_driver(
40
+ %[
41
+ tag test
42
+ aws_key_id dummy
43
+ aws_sec_key dummy
44
+ aws_region ddblocal
45
+ stream_arn #{@stream_arn}
46
+ ]
47
+ )
48
+
49
+ d.run do
50
+ sleep 1
51
+ put_records([
52
+ {key:"k1", timestamp:time_ms, bool:true, hash:{k:"v"}, l:[{k:"v"}], ns:[1,2,3], ss:["1","2","3"]},
53
+ {key:"k2", timestamp:time_ms},
54
+ ])
55
+ sleep 1
56
+ end
57
+
58
+ emits = d.emits
59
+
60
+ assert_equal(2, emits.size)
61
+
62
+ assert_equal("test", emits[0][0])
63
+ assert_equal(
64
+ {"key" => "k1", "timestamp" => time_ms, "bool" => true, "hash" => {"k" => "v"}, "l" => [{"k" => "v"}], "ns" => [1,2,3], "ss" => ["1","2","3"]},
65
+ emits[0][2]["dynamodb"]["new_image"],
66
+ )
67
+
68
+ assert_equal("test", emits[1][0])
69
+ assert_equal({"key" => "k2", "timestamp" => time_ms}, emits[1][2]["dynamodb"]["new_image"])
70
+
71
+ assert_equal("ddblocal", emits[0][2]["aws_region"])
72
+ assert_true(emits[0][2]["event_id"].size > 0)
73
+ assert_equal("aws:dynamodb", emits[0][2]["event_source"])
74
+ assert_true(emits[0][2]["event_version"].size > 0)
75
+ assert_equal("INSERT", emits[0][2]["event_name"])
76
+ assert_true(emits[0][2]["dynamodb"]["sequence_number"].size > 0)
77
+ assert_equal("NEW_AND_OLD_IMAGES", emits[0][2]["dynamodb"]["stream_view_type"])
78
+ assert_equal(78, emits[0][2]["dynamodb"]["size_bytes"])
79
+
80
+ delete_table
81
+ end
82
+
83
+ private
84
+ def create_driver(conf = CONFIG)
85
+ Fluent::Test::InputTestDriver.new(Fluent::DynamoDBStreamsInput).configure(conf)
86
+ end
87
+
88
+ end
@@ -0,0 +1,66 @@
1
+ require "codeclimate-test-reporter"
2
+ CodeClimate::TestReporter.start
3
+
4
+ require 'fluent/test'
5
+ require 'fluent/plugin/in_dynamodb_streams'
6
+ require 'aws-sdk'
7
+
8
+ module DynamoDBStreamsTestHelper
9
+
10
+ TEST_TABLE_NAME = "in_dynamodb_streams"
11
+
12
+ private
13
+ def dynamodb
14
+ @ddb ||= Aws::DynamoDB::Client.new(
15
+ region: 'ap-northeast-1',
16
+ access_key_id: 'dummy',
17
+ secret_access_key: 'dummy',
18
+ endpoint: 'http://localhost:8000',
19
+ )
20
+ end
21
+
22
+ def create_table
23
+ @stream_arn = dynamodb.create_table({
24
+ table_name: TEST_TABLE_NAME,
25
+ key_schema: [
26
+ {
27
+ attribute_name: "key",
28
+ key_type: "HASH",
29
+ }
30
+ ],
31
+ attribute_definitions: [
32
+ {
33
+ attribute_name: "key",
34
+ attribute_type: "S",
35
+ }
36
+ ],
37
+ provisioned_throughput: {
38
+ read_capacity_units: 1,
39
+ write_capacity_units: 1,
40
+ },
41
+ stream_specification: {
42
+ stream_enabled: true,
43
+ stream_view_type: "NEW_AND_OLD_IMAGES",
44
+ }
45
+ }).table_description.latest_stream_arn
46
+ end
47
+
48
+ def put_records(records)
49
+ records.each do |r|
50
+ dynamodb.put_item(
51
+ table_name: TEST_TABLE_NAME,
52
+ item: r,
53
+ )
54
+ end
55
+ end
56
+
57
+ def delete_table
58
+ dynamodb.list_tables.table_names.each do |t|
59
+ if t == TEST_TABLE_NAME
60
+ dynamodb.delete_table({
61
+ table_name: TEST_TABLE_NAME,
62
+ })
63
+ end
64
+ end
65
+ end
66
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-dynamodb-streams
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Takumi Sakamoto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-09-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fluentd
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 0.10.58
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.10.58
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: aws-sdk
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2'
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '2'
47
+ - !ruby/object:Gem::Dependency
48
+ name: bundler
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.7'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.7'
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '10.0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '10.0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: test-unit
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: 3.1.0
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: 3.1.0
89
+ - !ruby/object:Gem::Dependency
90
+ name: dynamodb-local
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ description: Amazon DynamoDB Streams input plugin for Fluentd
104
+ email:
105
+ - takumi.saka@gmail.com
106
+ executables: []
107
+ extensions: []
108
+ extra_rdoc_files: []
109
+ files:
110
+ - ".gitignore"
111
+ - ".travis.yml"
112
+ - Gemfile
113
+ - LICENSE.txt
114
+ - README.md
115
+ - Rakefile
116
+ - example/fluentd.conf
117
+ - fluent-plugin-dynamodb-streams.gemspec
118
+ - lib/fluent/plugin/in_dynamodb_streams.rb
119
+ - test/plugin/in_dynamodb_streams.rb
120
+ - test/test_helper.rb
121
+ homepage: https://github.com/takus/fluent-plugin-dynamodb-streams
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.2.2
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Amazon DynamoDB Streams input plugin for Fluentd
145
+ test_files:
146
+ - test/plugin/in_dynamodb_streams.rb
147
+ - test/test_helper.rb