fluent-plugin-lambda-ext 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 75cd7e8051e0f475a5bbf5bfd65450c237be81a3
4
+ data.tar.gz: cc49999010ac7eb18ae3c8b1098642731952c026
5
+ SHA512:
6
+ metadata.gz: 238d775d29c01c17e3fdec90971614e97bf1fb51ec572405ce2bbf22d21dcc44875a5a42762d01cabbd4399a1123f4a4ff71f35200e6bc130bb6e57f9b3378ab
7
+ data.tar.gz: 2b80355e6f29805661fd33bae987d5b6900d786972113a0b1d9f7e5b7c9e991c7d897e3b437b68403e49ed60fd3ba6f6e4604a008fbb8e5cc7fc316a84330d66
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ fluent.cnf
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --require spec_helper
2
+ --colour
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1
4
+ - 2.2
5
+ - 2.3.4
6
+ - 2.4.1
7
+ before_install:
8
+ - gem update bundler
9
+ script:
10
+ - bundle install
11
+ - bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in fluent-plugin-dd.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Genki Sugawara
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,49 @@
1
+ # fluent-plugin-lambda-ext
2
+
3
+ Output plugin for [AWS Lambda](http://aws.amazon.com/lambda/).
4
+
5
+ [![GitHub version](https://badge.fury.io/gh/VAveryanov8%2Ffluent-plugin-lambda-ext.svg)](https://badge.fury.io/gh/VAveryanov8%2Ffluent-plugin-lambda-ext)
6
+ [![Build Status](https://travis-ci.org/VAveryanov8/fluent-plugin-lambda-ext.svg?branch=master)](https://travis-ci.org/VAveryanov8/fluent-plugin-lambda-ext)
7
+
8
+ **This is a fork of [fluent-plugin-lambda](https://github.com/winebarrel/fluent-plugin-lambda)**
9
+
10
+ ## Installation
11
+
12
+ $ gem install fluent-plugin-lambda-ext(not exists yet)
13
+
14
+ ## Configuration
15
+
16
+ ```
17
+ <match lambda.**>
18
+ type lambda
19
+ #profile ...
20
+ #credentials_path ...
21
+ #aws_key_id ...
22
+ #aws_sec_key ...
23
+ region us-east-1
24
+ #endpoint ...
25
+
26
+ #qualifier staging
27
+ function_name my_func
28
+ # Set 'group_events' true for making batch requests
29
+ #group_events true
30
+ # Pass the function name in the key of record if the function name is not set
31
+
32
+ # include_time_key false
33
+ # include_tag_key false
34
+ </match>
35
+ ```
36
+
37
+ ## Usage
38
+
39
+ When the function name is set:
40
+
41
+ ```sh
42
+ echo '{"key":"value"}' | fluent-cat lambda.foo
43
+ ```
44
+
45
+ When the function name is not set:
46
+
47
+ ```sh
48
+ echo '{"function_name":"my_func", "key":"value"}' | fluent-cat lambda.bar
49
+ ```
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task :default => :spec
@@ -0,0 +1,22 @@
1
+ # coding: utf-8
2
+ Gem::Specification.new do |spec|
3
+ spec.name = 'fluent-plugin-lambda-ext'
4
+ spec.version = '0.3.0'
5
+ spec.authors = ['Genki Sugawara']
6
+ spec.email = ['sugawara@cookpad.com']
7
+ spec.description = %q{Output plugin for AWS Lambda. Fork of github.com/winebarrel/fluent-plugin-lambda}
8
+ spec.summary = %q{Output plugin for AWS Lambda.}
9
+ spec.homepage = 'https://github.com/VAveryanov8/fluent-plugin-lambda-ext'
10
+ spec.license = 'MIT'
11
+
12
+ spec.files = `git ls-files -z`.split("\x0")
13
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
+ spec.require_paths = ['lib']
15
+
16
+ spec.add_dependency 'fluentd'
17
+ spec.add_dependency 'aws-sdk-core', '~> 2.1'
18
+ spec.add_development_dependency 'bundler'
19
+ spec.add_development_dependency 'rake'
20
+ spec.add_development_dependency 'rspec', '>= 3.0.0'
21
+ spec.add_development_dependency 'test-unit', '>= 3.2.0'
22
+ end
@@ -0,0 +1,10 @@
1
+ <source>
2
+ @type forward
3
+ @id forward_input
4
+ </source>
5
+
6
+ <match lambda.**>
7
+ type lambda
8
+
9
+ function_name test
10
+ </match>
@@ -0,0 +1,131 @@
1
+ require 'json'
2
+ require 'aws-sdk-core'
3
+ require 'fluent/plugin/output'
4
+
5
+ class Fluent::Plugin::LambdaOutput < Fluent::Plugin::Output
6
+ Fluent::Plugin.register_output('lambda', self)
7
+
8
+ helpers :compat_parameters, :inject
9
+
10
+ DEFAULT_BUFFER_TYPE = "memory"
11
+
12
+ config_param :profile, :string, :default => nil
13
+ config_param :credentials_path, :string, :default => nil
14
+ config_param :aws_key_id, :string, :default => nil
15
+ config_param :aws_sec_key, :string, :default => nil
16
+ config_param :region, :string, :default => nil
17
+ config_param :endpoint, :string, :default => nil
18
+ config_param :function_name, :string, :default => nil
19
+ config_param :qualifier, :string, :default => nil
20
+ config_param :group_events, :bool, :default => false
21
+
22
+ config_set_default :include_time_key, false
23
+ config_set_default :include_tag_key, false
24
+
25
+ config_section :buffer do
26
+ config_set_default :@type, DEFAULT_BUFFER_TYPE
27
+ end
28
+
29
+ def initialize
30
+ super
31
+ end
32
+
33
+ def configure(conf)
34
+ compat_parameters_convert(conf, :buffer, :inject)
35
+ super
36
+
37
+ aws_opts = {}
38
+
39
+ if @profile
40
+ credentials_opts = {:profile_name => @profile}
41
+ credentials_opts[:path] = @credentials_path if @credentials_path
42
+ credentials = Aws::SharedCredentials.new(credentials_opts)
43
+ aws_opts[:credentials] = credentials
44
+ end
45
+
46
+ if @group_events
47
+ raise Fluent::ConfigError, "could not group events without 'function_name'" if @function_name.nil?
48
+ end
49
+
50
+ aws_opts[:access_key_id] = @aws_key_id if @aws_key_id
51
+ aws_opts[:secret_access_key] = @aws_sec_key if @aws_sec_key
52
+ aws_opts[:region] = @region if @region
53
+ aws_opts[:endpoint] = @endpoint if @endpoint
54
+
55
+ configure_aws(aws_opts)
56
+ end
57
+
58
+ def start
59
+ super
60
+
61
+ @client = create_client
62
+ end
63
+
64
+ def formatted_to_msgpack_binary
65
+ true
66
+ end
67
+
68
+ def format(tag, time, record)
69
+ [tag, time, record].to_msgpack
70
+ end
71
+
72
+ def write(chunk)
73
+ chunk = chunk.to_enum(:msgpack_each)
74
+ if @group_events
75
+ write_batch(chunk)
76
+ else
77
+ write_by_one(chunk)
78
+ end
79
+ end
80
+
81
+ private
82
+
83
+ def configure_aws(options)
84
+ Aws.config.update(options)
85
+ end
86
+
87
+ def create_client
88
+ Aws::Lambda::Client.new
89
+ end
90
+
91
+ def write_batch(chunk)
92
+ func_name = @function_name
93
+ chunk.group_by {|tag, time, record|
94
+ tag
95
+ }.each{|key, group|
96
+ events = []
97
+ group.each do |time, tag, record|
98
+ events << record
99
+ end
100
+ @client.invoke({
101
+ :function_name => func_name,
102
+ :payload => JSON.dump(events),
103
+ :invocation_type => 'Event',
104
+ })
105
+ }
106
+ end
107
+
108
+ def write_by_one(chunk)
109
+ chunk.select {|tag, time, record|
110
+ if @function_name or record['function_name']
111
+ true
112
+ else
113
+ log.warn("`function_name` key does not exist: #{[tag, time, record].inspect}")
114
+ false
115
+ end
116
+ }.each {|tag, time, record|
117
+ record = inject_values_to_record(tag, time, record)
118
+ func_name = @function_name || record['function_name']
119
+
120
+ payload = {
121
+ :function_name => func_name,
122
+ :payload => JSON.dump(record),
123
+ :invocation_type => 'Event',
124
+ }
125
+ payload[:qualifier] = @qualifier unless @qualifier.nil?
126
+
127
+ @client.invoke(payload)
128
+ }
129
+ end
130
+
131
+ end
@@ -0,0 +1,110 @@
1
+ describe Fluent::Plugin::LambdaOutput do
2
+ include Fluent::Test::Helpers
3
+
4
+ let(:time) {
5
+ event_time('2014-09-01 01:23:45 UTC')
6
+ }
7
+
8
+ context 'when events is sent' do
9
+ it 'should be call invoke' do
10
+ run_driver(function_name: 'my_func') do |d, client|
11
+ expect(client).to receive(:invoke).with(
12
+ function_name: 'my_func',
13
+ payload: JSON.dump('key1' => 'foo', 'key2' => 100),
14
+ invocation_type: 'Event',
15
+ )
16
+
17
+ expect(client).to receive(:invoke).with(
18
+ function_name: 'my_func',
19
+ payload: JSON.dump('key1' => 'bar', 'key2' => 200),
20
+ invocation_type: 'Event',
21
+ )
22
+
23
+ d.feed(time, {'key1' => 'foo', 'key2' => 100})
24
+ d.feed(time, {'key1' => 'bar', 'key2' => 200})
25
+ end
26
+ end
27
+ end
28
+
29
+ context 'when events is sent with function_name' do
30
+ it 'should be call invoke' do
31
+ run_driver do |d, client|
32
+ expect(client).to receive(:invoke).with(
33
+ function_name: 'my_func1',
34
+ payload: JSON.dump('function_name' => 'my_func1', 'key1' => 'foo' , 'key2' => 100),
35
+ invocation_type: 'Event',
36
+ )
37
+
38
+ expect(client).to receive(:invoke).with(
39
+ function_name: 'my_func2',
40
+ payload: JSON.dump('function_name' => 'my_func2', 'key1' => 'bar' , 'key2' => 200),
41
+ invocation_type: 'Event',
42
+ )
43
+
44
+ d.feed(time, {'function_name' => 'my_func1', 'key1' => 'foo', 'key2' => 100})
45
+ d.feed(time, {'function_name' => 'my_func2', 'key1' => 'bar', 'key2' => 200})
46
+ end
47
+ end
48
+ end
49
+
50
+ context 'when events is sent without function_name' do
51
+ it 'should be warned' do
52
+ run_driver do |d, client|
53
+ expect(client).to_not receive(:invoke)
54
+
55
+ d.feed(time, {'key1' => 'foo', 'key2' => 100})
56
+ d.feed(time, {'key1' => 'bar', 'key2' => 200})
57
+
58
+ expect(d.instance.log).to receive(:warn).
59
+ with('`function_name` key does not exist: ["test.default", 1409534625, {"key1"=>"foo", "key2"=>100}]')
60
+ expect(d.instance.log).to receive(:warn).
61
+ with('`function_name` key does not exist: ["test.default", 1409534625, {"key1"=>"bar", "key2"=>200}]')
62
+ end
63
+ end
64
+ end
65
+
66
+ context 'when a qualifier is provided' do
67
+ it 'invokes that alias' do
68
+ run_driver(qualifier: 'staging') do |d, client|
69
+ expect(client).to receive(:invoke).with(
70
+ function_name: 'my_func1',
71
+ payload: JSON.dump('function_name' => 'my_func1', 'key1' => 'foo' , 'key2' => 100),
72
+ invocation_type: 'Event',
73
+ qualifier: 'staging'
74
+ )
75
+
76
+ expect(client).to receive(:invoke).with(
77
+ function_name: 'my_func2',
78
+ payload: JSON.dump('function_name' => 'my_func2', 'key1' => 'bar' , 'key2' => 200),
79
+ invocation_type: 'Event',
80
+ qualifier: 'staging'
81
+ )
82
+
83
+ d.feed(time, {'function_name' => 'my_func1', 'key1' => 'foo', 'key2' => 100})
84
+ d.feed(time, {'function_name' => 'my_func2', 'key1' => 'bar', 'key2' => 200})
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'when bulk write is turned on' do
90
+ it 'should call invoke with array of events' do
91
+ run_driver(group_events: true, function_name: 'my_func') do |d, client|
92
+
93
+ expect(client).to receive(:invoke).with(
94
+ function_name: 'my_func',
95
+ payload: JSON.dump([{'key' => 1}, {'key' => 2}, {'key' => 3}]),
96
+ invocation_type: 'Event'
97
+ )
98
+
99
+ d.feed(time, {'key' => 1})
100
+ d.feed(time, {'key' => 2})
101
+ d.feed(time, {'key' => 3})
102
+ end
103
+ end
104
+ end
105
+ it 'should throw error when @group_events is on, but function_name is missed' do
106
+ expect {
107
+ run_driver(group_events: true)
108
+ }.to raise_error(Fluent::ConfigError)
109
+ end
110
+ end
@@ -0,0 +1,40 @@
1
+ require 'fluent/test'
2
+ require 'fluent/test/driver/output'
3
+ require 'fluent/test/helpers'
4
+ require 'fluent/plugin/out_lambda'
5
+ require 'aws-sdk-core'
6
+ require 'time'
7
+
8
+ # Disable Test::Unit
9
+ module Test::Unit::RunCount; def run(*); end; end
10
+ # prevent Test::Unit's AutoRunner from executing during RSpec's rake task
11
+ Test::Unit.run = true if defined?(Test::Unit) && Test::Unit.respond_to?(:run=)
12
+
13
+ RSpec.configure do |config|
14
+ config.before(:all) do
15
+ Fluent::Test.setup
16
+ end
17
+ end
18
+
19
+ def run_driver(options = {})
20
+ tag = options.delete(:tag) || 'test.default'
21
+
22
+ additional_options = options.map {|key, value|
23
+ "#{key} #{value}"
24
+ }.join("\n")
25
+
26
+ fluentd_conf = <<-EOS
27
+ type lambda
28
+ aws_key_id AKIAIOSFODNN7EXAMPLE
29
+ aws_sec_key wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
30
+ region us-west-1
31
+ #{additional_options}
32
+ EOS
33
+
34
+ driver = Fluent::Test::Driver::Output.new(Fluent::Plugin::LambdaOutput).configure(fluentd_conf)
35
+
36
+ driver.run(default_tag: tag) do
37
+ client = driver.instance.instance_variable_get(:@client)
38
+ yield(driver, client)
39
+ end
40
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-lambda-ext
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Genki Sugawara
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2018-03-18 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'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: aws-sdk-core
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: 3.0.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.0.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: test-unit
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.2.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 3.2.0
97
+ description: Output plugin for AWS Lambda. Fork of github.com/winebarrel/fluent-plugin-lambda
98
+ email:
99
+ - sugawara@cookpad.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - fluent-plugin-lambda.gemspec
112
+ - fluent.conf
113
+ - lib/fluent/plugin/out_lambda.rb
114
+ - spec/out_lambda_spec.rb
115
+ - spec/spec_helper.rb
116
+ homepage: https://github.com/VAveryanov8/fluent-plugin-lambda-ext
117
+ licenses:
118
+ - MIT
119
+ metadata: {}
120
+ post_install_message:
121
+ rdoc_options: []
122
+ require_paths:
123
+ - lib
124
+ required_ruby_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ required_rubygems_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements: []
135
+ rubyforge_project:
136
+ rubygems_version: 2.6.14.1
137
+ signing_key:
138
+ specification_version: 4
139
+ summary: Output plugin for AWS Lambda.
140
+ test_files:
141
+ - spec/out_lambda_spec.rb
142
+ - spec/spec_helper.rb