fluent-plugin-kinesis-modified 3.1.3

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/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ require "bundler/gem_tasks"
16
+
17
+ require 'rake/testtask'
18
+
19
+ task default: [:test]
20
+ Rake::TestTask.new do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.test_files = FileList['test/**/test_*.rb']
23
+ test.options = '-v'
24
+ end
25
+
26
+ load 'benchmark/task.rake'
@@ -0,0 +1,106 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ require_relative '../test/helper'
16
+ require 'fluent/plugin/out_kinesis_streams'
17
+ require 'fluent/plugin/out_kinesis_streams_aggregated'
18
+ require 'fluent/plugin/out_kinesis_firehose'
19
+ require 'benchmark'
20
+ require 'net/empty_port'
21
+
22
+ namespace :benchmark do
23
+ task :local do
24
+ KinesisBenchmark.new.run
25
+ end
26
+ task :remote do
27
+ KinesisBenchmark.new(false).run
28
+ end
29
+ end
30
+
31
+ class KinesisBenchmark
32
+ def initialize(local = true)
33
+ @local = local
34
+ Fluent::Test.setup
35
+ end
36
+
37
+ def run
38
+ setup
39
+ benchmark(ENV['SIZE'] || 100, ENV['COUNT'] || 10000)
40
+ teardown
41
+ end
42
+
43
+ def setup
44
+ return if not @local
45
+ @port = Net::EmptyPort.empty_port
46
+ @server_pid = fork do
47
+ Process.setsid
48
+ server = DummyServer.start(port: @port)
49
+ Signal.trap("TERM") do
50
+ server.shutdown
51
+ end
52
+ server.thread.join
53
+ end
54
+ Net::EmptyPort.wait(@port, 3)
55
+ end
56
+
57
+ def teardown
58
+ return if not @local
59
+ Process.kill "TERM", @server_pid
60
+ Process.waitpid @server_pid
61
+ end
62
+
63
+ def default_config
64
+ conf = %[
65
+ log_level error
66
+ region ap-northeast-1
67
+ data_key a
68
+ ]
69
+ if @local
70
+ conf += %[
71
+ endpoint https://localhost:#{@port}
72
+ ssl_verify_peer false
73
+ ]
74
+ end
75
+ conf
76
+ end
77
+
78
+ def create_driver(type, conf = default_config)
79
+ klass = case type
80
+ when :streams
81
+ Fluent::Plugin::KinesisStreamsOutput
82
+ when :streams_aggregated
83
+ Fluent::Plugin::KinesisStreamsAggregatedOutput
84
+ when :firehose
85
+ Fluent::Plugin::KinesisFirehoseOutput
86
+ end
87
+ conf += case type
88
+ when :streams, :streams_aggregated
89
+ "stream_name fluent-plugin-test"
90
+ when :firehose
91
+ "delivery_stream_name fluent-plugin-test"
92
+ end
93
+
94
+ Fluent::Test::Driver::Output.new(klass) do
95
+ end.configure(conf)
96
+ end
97
+
98
+ def benchmark(size, count)
99
+ record = {"a"=>"a"*size}
100
+ Benchmark.bmbm(20) do |x|
101
+ [:streams_aggregated, :streams, :firehose].each do |type|
102
+ x.report(type) { driver_run(create_driver(type), count.times.map{|i|record}) }
103
+ end
104
+ end
105
+ end
106
+ end
@@ -0,0 +1,63 @@
1
+ # coding: utf-8
2
+ #
3
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
6
+ # may not use this file except in compliance with the License. A copy of
7
+ # the License is located at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # or in the "license" file accompanying this file. This file is
12
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
13
+ # ANY KIND, either express or implied. See the License for the specific
14
+ # language governing permissions and limitations under the License.
15
+
16
+ lib = File.expand_path('../lib', __FILE__)
17
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
18
+ require 'fluent_plugin_kinesis/version'
19
+
20
+ Gem::Specification.new do |spec|
21
+ spec.name = "fluent-plugin-kinesis-modified"
22
+ spec.version = FluentPluginKinesis::VERSION
23
+ spec.author = 'iHandy'
24
+ spec.summary = %q{Fluentd output plugin that sends events to Amazon Kinesis. Forked from fluent-plugin-kinesis version 3.1.0}
25
+ spec.homepage = "https://github.com/BlackNight95/aws-fluent-plugin-kinesis/tree/feature_modified_aggregation"
26
+ spec.license = "Apache-2.0"
27
+
28
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+ spec.required_ruby_version = '>= 2.1'
32
+
33
+ spec.add_dependency "fluentd", ">= 0.14.10", "< 2"
34
+
35
+ # This plugin is sometimes used with s3 plugin, so watch out for conflicts
36
+ # https://rubygems.org/gems/fluent-plugin-s3
37
+ # Exclude v1.5 to avoid aws-sdk dependency problem due to this issue
38
+ # https://github.com/aws/aws-sdk-ruby/issues/1872
39
+ # Exclude aws-sdk-kinesis v1.4 to avoid aws-sdk-core dependency problem with td-agent v3.1.1
40
+ # NoMethodError: undefined method `event=' for #<Seahorse::Model::Shapes::ShapeRef:*>
41
+ # https://github.com/aws/aws-sdk-ruby/commit/03d60f9d3d821e645bd2a3efca066f37350ef906#diff-c69f15af8ea3eb9ab152659476e04608R401
42
+ # https://github.com/aws/aws-sdk-ruby/commit/571c2d0e5ff9c24ff72893a08a74790db591fb57#diff-a55155f04aa6559460a0814e264eb0cdR43
43
+ spec.add_dependency "aws-sdk-kinesis", "~> 1", "!= 1.4", "!= 1.5"
44
+ # Exclude aws-sdk-firehose v1.9 to avoid aws-sdk-core dependency problem with td-agent v3.2.1
45
+ # LoadError: cannot load such file -- aws-sdk-core/plugins/endpoint_discovery.rb
46
+ # https://github.com/aws/aws-sdk-ruby/commit/85d8538a62255e58d9e176ee524a9f94354b51a0#diff-d51486091a10ada65b308b7f45966af1R18
47
+ # https://github.com/aws/aws-sdk-ruby/commit/7c9584bc6473100df9aec9333ab491ad4faeeca8#diff-be94f87e58e00329a6c0e03e43d5c292
48
+ spec.add_dependency "aws-sdk-firehose", "~> 1", "!= 1.5", "!= 1.9"
49
+
50
+ spec.add_dependency "google-protobuf", "~> 3"
51
+
52
+ spec.add_development_dependency "bundler", ">= 1.10"
53
+ spec.add_development_dependency "rake", ">= 10.0"
54
+ spec.add_development_dependency "test-unit", ">= 3.0.8"
55
+ spec.add_development_dependency "test-unit-rr", ">= 1.0.3"
56
+ spec.add_development_dependency "pry", ">= 0.10.1"
57
+ spec.add_development_dependency "pry-byebug", ">= 3.3.0"
58
+ spec.add_development_dependency "pry-stack_explorer", ">= 0.4.9.2"
59
+ spec.add_development_dependency "net-empty_port", ">= 0.0.2"
60
+ spec.add_development_dependency "mocha", ">= 1.1.0"
61
+ spec.add_development_dependency "webmock", ">= 1.24.2"
62
+ spec.add_development_dependency "fakefs", ">= 0.8.1"
63
+ end
@@ -0,0 +1,20 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ source 'https://rubygems.org'
16
+
17
+ # Specify your gem's dependencies in fluent-plugin-kinesis.gemspec
18
+ gemspec path: ".."
19
+
20
+ gem "fluentd", "0.14.10"
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ source 'https://rubygems.org'
16
+
17
+ # Specify your gem's dependencies in fluent-plugin-kinesis.gemspec
18
+ gemspec path: ".."
19
+
20
+ # Specify related gems for td-agent v3.1.1
21
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.1.1/config/projects/td-agent3.rb#L22
22
+ gem "fluentd", "1.0.2"
23
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.1.0/plugin_gems.rb#L16-L23
24
+ gem "jmespath", "1.3.1"
25
+ gem "aws-partitions", "1.42.0"
26
+ gem "aws-sigv4", "1.0.2"
27
+ gem "aws-sdk-core", "3.11.0"
28
+ gem "aws-sdk-kms", "1.3.0"
29
+ gem "aws-sdk-sqs", "1.3.0"
30
+ gem "aws-sdk-s3", "1.8.0"
31
+ gem "fluent-plugin-s3", "1.1.0"
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ source 'https://rubygems.org'
16
+
17
+ # Specify your gem's dependencies in fluent-plugin-kinesis.gemspec
18
+ gemspec path: ".."
19
+
20
+ # Specify related gems for td-agent v3.2.0
21
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.2.0/config/projects/td-agent3.rb#L27
22
+ gem "fluentd", "1.2.2"
23
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.2.0/plugin_gems.rb#L16-L23
24
+ gem "jmespath", "1.4.0"
25
+ gem "aws-partitions", "1.87.0"
26
+ gem "aws-sigv4", "1.0.2"
27
+ gem "aws-sdk-core", "3.21.2"
28
+ gem "aws-sdk-kms", "1.5.0"
29
+ gem "aws-sdk-sqs", "1.3.0"
30
+ gem "aws-sdk-s3", "1.13.0"
31
+ gem "fluent-plugin-s3", "1.1.3"
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ source 'https://rubygems.org'
16
+
17
+ # Specify your gem's dependencies in fluent-plugin-kinesis.gemspec
18
+ gemspec path: ".."
19
+
20
+ # Specify related gems for td-agent v3.2.1
21
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.2.1/config/projects/td-agent3.rb#L27
22
+ gem "fluentd", "1.2.6"
23
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.2.1/plugin_gems.rb#L16-L23
24
+ gem "jmespath", "1.4.0"
25
+ gem "aws-partitions", "1.105.0"
26
+ gem "aws-sigv4", "1.0.3"
27
+ gem "aws-sdk-core", "3.30.0"
28
+ gem "aws-sdk-kms", "1.9.0"
29
+ gem "aws-sdk-sqs", "1.7.0"
30
+ gem "aws-sdk-s3", "1.21.0"
31
+ gem "fluent-plugin-s3", "1.1.6"
@@ -0,0 +1,31 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ source 'https://rubygems.org'
16
+
17
+ # Specify your gem's dependencies in fluent-plugin-kinesis.gemspec
18
+ gemspec path: ".."
19
+
20
+ # Specify related gems for td-agent v3.3.0
21
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.3.0/config/projects/td-agent3.rb#L27
22
+ gem "fluentd", "1.3.3"
23
+ # https://github.com/treasure-data/omnibus-td-agent/blob/v3.3.0/plugin_gems.rb#L16-L23
24
+ gem "jmespath", "1.4.0"
25
+ gem "aws-partitions", "1.127.0"
26
+ gem "aws-sigv4", "1.0.3"
27
+ gem "aws-sdk-core", "3.44.2"
28
+ gem "aws-sdk-kms", "1.13.0"
29
+ gem "aws-sdk-sqs", "1.10.0"
30
+ gem "aws-sdk-s3", "1.30.0"
31
+ gem "fluent-plugin-s3", "1.1.7"
@@ -0,0 +1,185 @@
1
+ #
2
+ # Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License"). You
5
+ # may not use this file except in compliance with the License. A copy of
6
+ # the License is located at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # or in the "license" file accompanying this file. This file is
11
+ # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12
+ # ANY KIND, either express or implied. See the License for the specific
13
+ # language governing permissions and limitations under the License.
14
+
15
+ require 'fluent/plugin/output'
16
+ require 'fluent/plugin/kinesis_helper/client'
17
+ require 'fluent/plugin/kinesis_helper/api'
18
+ require 'zlib'
19
+
20
+ module Fluent
21
+ module Plugin
22
+ class KinesisOutput < Fluent::Plugin::Output
23
+ include Fluent::MessagePackFactory::Mixin
24
+ include KinesisHelper::Client
25
+ include KinesisHelper::API
26
+
27
+ class SkipRecordError < ::StandardError
28
+ def initialize(message, record)
29
+ super message
30
+ @record_message = if record.is_a? Array
31
+ record.reverse.map(&:to_s).join(', ')
32
+ else
33
+ record.to_s
34
+ end
35
+ end
36
+
37
+ def to_s
38
+ super + ": " + @record_message
39
+ end
40
+ end
41
+ class KeyNotFoundError < SkipRecordError
42
+ def initialize(key, record)
43
+ super "Key '#{key}' doesn't exist", record
44
+ end
45
+ end
46
+ class ExceedMaxRecordSizeError < SkipRecordError
47
+ def initialize(size, record)
48
+ super "Record size limit exceeded in #{size/1024} KB", record
49
+ end
50
+ end
51
+ class InvalidRecordError < SkipRecordError
52
+ def initialize(record)
53
+ super "Invalid type of record", record
54
+ end
55
+ end
56
+
57
+ config_param :data_key, :string, default: nil
58
+ config_param :log_truncate_max_size, :integer, default: 1024
59
+ config_param :compression, :string, default: nil
60
+
61
+ desc "Formatter calls chomp and removes separator from the end of each record. This option is for compatible format with plugin v2. (default: false)"
62
+ # https://github.com/awslabs/aws-fluent-plugin-kinesis/issues/142
63
+ config_param :chomp_record, :bool, default: false
64
+
65
+ config_section :format do
66
+ config_set_default :@type, 'json'
67
+ end
68
+ config_section :inject do
69
+ config_set_default :time_type, 'string'
70
+ config_set_default :time_format, '%Y-%m-%dT%H:%M:%S.%N%z'
71
+ end
72
+
73
+ config_param :debug, :bool, default: false
74
+ config_param :max_records_per_call, :integer, default: 128
75
+
76
+ helpers :formatter, :inject
77
+
78
+ def configure(conf)
79
+ super
80
+ @data_formatter = data_formatter_create(conf)
81
+ end
82
+
83
+ def multi_workers_ready?
84
+ true
85
+ end
86
+
87
+ private
88
+
89
+ def data_formatter_create(conf)
90
+ formatter = formatter_create
91
+ compressor = compressor_create
92
+ if @data_key.nil?
93
+ if @chomp_record
94
+ ->(tag, time, record) {
95
+ record = inject_values_to_record(tag, time, record)
96
+ # Formatter calls chomp and removes separator from the end of each record.
97
+ # This option is for compatible format with plugin v2.
98
+ # https://github.com/awslabs/aws-fluent-plugin-kinesis/issues/142
99
+ compressor.call(formatter.format(tag, time, record).chomp.b)
100
+ }
101
+ else
102
+ ->(tag, time, record) {
103
+ record = inject_values_to_record(tag, time, record)
104
+ compressor.call(formatter.format(tag, time, record).b)
105
+ }
106
+ end
107
+ else
108
+ ->(tag, time, record) {
109
+ raise InvalidRecordError, record unless record.is_a? Hash
110
+ raise KeyNotFoundError.new(@data_key, record) if record[@data_key].nil?
111
+ compressor.call(record[@data_key].to_s.b)
112
+ }
113
+ end
114
+ end
115
+
116
+ def compressor_create
117
+ case @compression
118
+ when "zlib"
119
+ ->(data) { Zlib::Deflate.deflate(data) }
120
+ else
121
+ ->(data) { data }
122
+ end
123
+ end
124
+
125
+ def format_for_api(&block)
126
+ converted = block.call
127
+ size = size_of_values(converted)
128
+ if size > @max_record_size
129
+ raise ExceedMaxRecordSizeError.new(size, converted)
130
+ end
131
+ converted.to_msgpack
132
+ rescue SkipRecordError => e
133
+ log.error(truncate e)
134
+ ''
135
+ end
136
+
137
+ def write_records_batch(chunk, &block)
138
+ unique_id = chunk.dump_unique_id_hex(chunk.unique_id)
139
+ chunk.open do |io|
140
+ records = msgpack_unpacker(io).to_enum
141
+ split_to_batches(records) do |batch, size|
142
+ log.debug(sprintf "Write chunk %s / %3d records / %4d KB", unique_id, batch.size, size/1024)
143
+ batch_request_with_retry(batch, &block)
144
+ log.debug("Finish writing chunk")
145
+ end
146
+ end
147
+ end
148
+
149
+ def write_records_batch2(chunk, &block)
150
+ unique_id = chunk.dump_unique_id_hex(chunk.unique_id)
151
+ chunk.open do |io|
152
+ records = msgpack_unpacker(io).to_enum
153
+ batches = []
154
+ sizes = []
155
+ split_to_batches(records) do |batch, size|
156
+ batches << batch
157
+ sizes << size
158
+ end
159
+ (0..batches.size).step(@max_records_per_call) do |i|
160
+ batches_slice = batches[i..i+@max_records_per_call-1]
161
+ size = sizes[i..i+@max_records_per_call-1].inject(:+)
162
+ batches_size = batches_slice.map(&:size).inject(:+)
163
+ if not size.nil?
164
+ log.debug(sprintf "Write chunk %s / %3d batches / %3d records / %4d KB", unique_id, batches_slice.size, batches_size, size/1024)
165
+ batch_request_with_retry(batches_slice, &block)
166
+ log.debug("Finish writing chunk")
167
+ end
168
+ end
169
+ end
170
+ end
171
+
172
+ def request_type
173
+ self.class::RequestType
174
+ end
175
+
176
+ def truncate(msg)
177
+ if @log_truncate_max_size == 0 or (msg.to_s.size <= @log_truncate_max_size)
178
+ msg.to_s
179
+ else
180
+ msg.to_s[0...@log_truncate_max_size]
181
+ end
182
+ end
183
+ end
184
+ end
185
+ end