fluent-plugin-kinesis-modified 3.1.3

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