fluent-plugin-amplitude 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 757d43474f5a6517ea2efdd15f43655fd6ca3edd
4
+ data.tar.gz: 7be8f650adad1bd3565391b92cf970fcc0db223f
5
+ SHA512:
6
+ metadata.gz: 1c307bc96c613dca51aed3360b2bde8871e16685dd84bb3c00db8e00960dadadc9bb89075a9f729188ecafc9325fa41a23c031cd769b0ac018489f753044860d
7
+ data.tar.gz: e6f941184f8d4deb9d57d7cf9674fac275d6ff99815e4993ed1776ce265a2c79346b80009e2a6a0fc086db4fd9d448559c80f40edd8d752c842fac49792d44e0
data/.gitignore ADDED
@@ -0,0 +1 @@
1
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Vijay Ramesh <vijay@change.org>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,78 @@
1
+ # fluent-plugin-amplitude
2
+ Output plugin for [Fluentd](http://fluentd.org) to [Amplitude](https://amplitude.com/)
3
+
4
+ This plugin uses the [amplitude-api](https://github.com/toothrot/amplitude-api) gem, which itself talks to Amplitude's [HTTP API](https://amplitude.zendesk.com/hc/en-us/articles/204771828-HTTP-API).
5
+
6
+ ## Installation
7
+ Install with gem or fluent-gem command as:
8
+
9
+ ```bash
10
+ # for fluentd
11
+ $ gem install fluent-plugin-amplitude
12
+
13
+ # for td-agent
14
+ $ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-amplitude
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ #### Example configuration
20
+ ```xml
21
+ <match output.amplitude.*>
22
+ @type amplitude
23
+ api_key XXXXXX
24
+ user_id_key user_id
25
+ device_id_key uuid
26
+ user_properties first_name, last_name
27
+ event_properties current_source
28
+ properties_blacklist user
29
+ events_whitelist petition_view, petition_share
30
+ flush_interval 5s
31
+ retry_limit 2
32
+ remove_tag_prefix output.amplitude.
33
+ <secondary>
34
+ @type file
35
+ path /var/log/fluent/forward-failed
36
+ </secondary>
37
+ </match>
38
+ ```
39
+
40
+ #### api_key
41
+ AmplitudeOutput needs your Amplitude `api_key` ([see Amplitude for more information](https://amplitude.zendesk.com/hc/en-us/articles/206728448-Where-can-I-find-my-app-s-API-Key-or-Secret-Key-))
42
+
43
+ #### user_id_key and device_id_key
44
+ You must set at least one of `user_id_key` and `device_id_key`. They will be used to pull out the `user_id` and `device_id` values from the record to send to the Amplitude API.
45
+
46
+ #### user_properties and event_properties
47
+ You can optionally specify lists of `user_properties` and `event_properties` to pull from the record.
48
+
49
+ If `user_properties` are specified, only those properties will be included as `user_properties` in the Amplitude API call. Otherwise no `user_properties` will be sent.
50
+
51
+ If `event_properties` are specified, only those properties will be included as `event_properties` in the Amplitude API call. Otherwise the entire record (minus the key/value for `user_id_key` and `device_id_key`, and minus any `user_properties`) will be sent as `event_properties` to Amplitude.
52
+
53
+ #### event type
54
+ The event_type is the tag. To modify this, fluent-plugin-amplitude includes the `HandleTagNameMixin` mixin which allows the following options:
55
+
56
+ ```xml
57
+ remove_tag_prefix <tag_prefix_to_remove_including_the_dot>
58
+ remove_tag_suffix <tag_suffix_to_remove_including_the_dot>
59
+ add_tag_prefix <tag_prefix_to_add_including_the_dot>
60
+ add_tag_suffix <tag_suffix_to_add_including_the_dot>
61
+ ```
62
+
63
+ #### properties_blacklist
64
+ Any properties included in the blacklist will be scrubbed from the record.
65
+
66
+ #### events_whitelist
67
+ If your `<match>` is using a wildcard, you can specify specific events to whitelist. If the `events_whitelist` is empty all events will be sent to Amplitude. Note the event name here is the `event_type` (so should not include, e.g., any prefixes that were removed via `remove_tag_prefix`)
68
+
69
+ #### Error handling
70
+ Any error will result in the message retrying. In the case of an incorrectly configured API key, this can result in the messages infinitely retrying. You should set the normal [buffered output plugin options](http://docs.fluentd.org/articles/buffer-plugin-overview) to prevent this (and to preserve data in the case of misconfigured records failing to be submitted to Amplitude).
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork it ( http://github.com/change/fluent-plugin-amplitude/fork )
75
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
76
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
77
+ 4. Push to the branch (`git push origin my-new-feature`)
78
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rubocop/rake_task'
3
+
4
+ RuboCop::RakeTask.new
5
+
6
+ begin
7
+ require 'rspec/core/rake_task'
8
+ RSpec::Core::RakeTask.new(:spec)
9
+ rescue LoadError
10
+ puts 'Unable to load rspec. Have you run `bundle install`?'
11
+ end
12
+
13
+ task(:default).clear
14
+ task default: ['rubocop:auto_correct', :spec]
@@ -0,0 +1,28 @@
1
+ # -*- encoding: 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-amplitude'
7
+ spec.version = '0.0.1'
8
+ spec.authors = ['Vijay Ramesh']
9
+ spec.email = ['vijay@change.org']
10
+ spec.summary = 'Fluentd plugin to output event data to Amplitude'
11
+ spec.description = 'Fluentd plugin to output event data to Amplitude'
12
+ spec.homepage = 'https://github.com/change/fluent-plugin-amplitude'
13
+
14
+ spec.files = `git ls-files -z`.split("\x0")
15
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
16
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.require_paths = ['lib']
18
+
19
+ spec.add_runtime_dependency 'fluentd', '>= 0.10.55'
20
+ spec.add_runtime_dependency 'amplitude-api', '~> 0.0.9'
21
+ spec.add_runtime_dependency 'msgpack', '~> 1.0', '>= 1.0.2'
22
+
23
+ spec.add_development_dependency 'rake', '~> 11.3'
24
+ spec.add_development_dependency 'rspec', '~> 3.5'
25
+ spec.add_development_dependency 'test-unit', '~> 3.2', '>= 3.2.1'
26
+ spec.add_development_dependency 'rspec-mocks', '~> 3.5'
27
+ spec.add_development_dependency 'rubocop', '~> 0.44.1'
28
+ end
@@ -0,0 +1,130 @@
1
+ module Fluent
2
+ # Fluent::AmplitudeOutput plugin
3
+ class AmplitudeOutput < Fluent::BufferedOutput
4
+ Fluent::Plugin.register_output('amplitude', self)
5
+
6
+ include Fluent::HandleTagNameMixin
7
+
8
+ config_param :api_key, :string, secret: true
9
+ config_param :device_id_key, :string
10
+ config_param :user_id_key, :string
11
+ config_param :user_properties, :array, default: nil
12
+ config_param :event_properties, :array, default: nil
13
+ config_param :properties_blacklist, :array, default: nil
14
+ config_param :events_whitelist, :array, default: nil
15
+ class AmplitudeError < StandardError
16
+ end
17
+
18
+ def initialize
19
+ super
20
+ require 'amplitude-api'
21
+ end
22
+
23
+ def configure(conf)
24
+ super
25
+ raise Fluent::ConfigError, "'api_key' must be specified." if @api_key.nil?
26
+
27
+ invalid = @device_id_key.nil? && @user_id_key.nil?
28
+ raise Fluent::ConfigError,
29
+ "'device_id_key' or 'user_id_key' must be specified." if invalid
30
+ end
31
+
32
+ def start
33
+ super
34
+ AmplitudeAPI.api_key = @api_key
35
+ end
36
+
37
+ def format(tag, time, record)
38
+ return if @events_whitelist && !@events_whitelist.include?(tag)
39
+
40
+ amplitude_hash = { event_type: tag }
41
+
42
+ filter_properties_blacklist!(record)
43
+ extract_user_and_device_or_fail!(amplitude_hash, record)
44
+ extract_user_properties!(amplitude_hash, record)
45
+ extract_event_properties!(amplitude_hash, record)
46
+
47
+ [tag, time, amplitude_hash].to_msgpack
48
+ end
49
+
50
+ def write(chunk)
51
+ records = []
52
+ chunk.msgpack_each do |_tag, _time, record|
53
+ records << AmplitudeAPI::Event.new(simple_symbolize_keys(record))
54
+ end
55
+
56
+ send_to_amplitude(records)
57
+ end
58
+
59
+ private
60
+
61
+ def filter_properties_blacklist!(record)
62
+ return unless @properties_blacklist
63
+ record.reject! { |k, _| @properties_blacklist.include?(k) }
64
+ end
65
+
66
+ def extract_user_and_device_or_fail!(amplitude_hash, record)
67
+ if @user_id_key && record[@user_id_key]
68
+ amplitude_hash[:user_id] = record.delete(@user_id_key)
69
+ end
70
+
71
+ if @device_id_key && record[@device_id_key]
72
+ amplitude_hash[:device_id] = record.delete(@device_id_key)
73
+ end
74
+
75
+ verify_user_and_device_or_fail(amplitude_hash)
76
+ end
77
+
78
+ def verify_user_and_device_or_fail(amplitude_hash)
79
+ return if amplitude_hash[:user_id] || amplitude_hash[:device_id]
80
+ raise AmplitudeError, 'Error: either user_id or device_id must be set'
81
+ end
82
+
83
+ def extract_user_properties!(amplitude_hash, record)
84
+ # if user_properties are specified, pull them off of the record
85
+ return unless @user_properties
86
+ amplitude_hash[:user_properties] = {}.tap do |user_properties|
87
+ @user_properties.each do |prop|
88
+ next unless record[prop]
89
+ user_properties[prop.to_sym] = record.delete(prop)
90
+ end
91
+ end
92
+ end
93
+
94
+ def extract_event_properties!(amplitude_hash, record)
95
+ # if event_properties are specified, pull them off of the record
96
+ # otherwise, use the remaining record (minus any user_properties)
97
+ amplitude_hash[:event_properties] = begin
98
+ if @event_properties
99
+ record.select do |k, _v|
100
+ @event_properties.include?(k)
101
+ end
102
+ else
103
+ record
104
+ end
105
+ end
106
+ end
107
+
108
+ def send_to_amplitude(records)
109
+ log.info("sending #{records.length} to amplitude")
110
+ begin
111
+ res = AmplitudeAPI.track(records)
112
+ unless res.response_code == 200
113
+ raise "Got #{res.response_code} #{res.body} from AmplitudeAPI"
114
+ end
115
+ rescue StandardError => e
116
+ raise AmplitudeError, "Error: #{e.message}"
117
+ end
118
+ end
119
+
120
+ def simple_symbolize_keys(hsh)
121
+ Hash[hsh.map do |k, v|
122
+ begin
123
+ [k.to_sym, v]
124
+ rescue
125
+ [k, v]
126
+ end
127
+ end]
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,191 @@
1
+ require 'spec_helper'
2
+ require 'amplitude-api'
3
+ describe Fluent::AmplitudeOutput do
4
+ let(:amplitude_api) { double(:amplitude_api) }
5
+ let(:now) { Time.now.to_i }
6
+ let(:tag) { 'after_sign' }
7
+ let(:amplitude) do
8
+ Fluent::Test::BufferedOutputTestDriver.new(
9
+ Fluent::AmplitudeOutput.new
10
+ ).configure(conf)
11
+ end
12
+ let(:conf) do
13
+ %(
14
+ api_key XXXXXX
15
+ user_id_key user_id
16
+ device_id_key uuid
17
+ user_properties first_name, last_name
18
+ event_properties current_source
19
+ )
20
+ end
21
+
22
+ before do
23
+ Fluent::Test.setup
24
+ expect(AmplitudeAPI).to receive(:api_key=).with('XXXXXX')
25
+ allow(AmplitudeAPI).to receive(:track).with(kind_of(Array)).and_return(
26
+ double(:response, response_code: 200)
27
+ )
28
+ end
29
+
30
+ describe '#format' do
31
+ before do
32
+ amplitude.tag = tag
33
+ amplitude.emit(event, now)
34
+ end
35
+
36
+ context 'everything is set' do
37
+ let(:event) do
38
+ {
39
+ 'user_id' => 42,
40
+ 'uuid' => 'e6153b00-85d8-11e6-b1bc-43192d1e493f',
41
+ 'first_name' => 'Bobby',
42
+ 'last_name' => 'Weir',
43
+ 'state' => 'CA',
44
+ 'current_source' => 'fb_share',
45
+ 'recruiter_id' => 710
46
+ }
47
+ end
48
+
49
+ let(:formatted_event) do
50
+ {
51
+ event_type: tag,
52
+ user_id: 42,
53
+ device_id: 'e6153b00-85d8-11e6-b1bc-43192d1e493f',
54
+ user_properties: {
55
+ first_name: 'Bobby',
56
+ last_name: 'Weir'
57
+ },
58
+ event_properties: {
59
+ current_source: 'fb_share'
60
+ }
61
+ }
62
+ end
63
+
64
+ it 'produces the expected output' do
65
+ amplitude.expect_format [tag, now, formatted_event].to_msgpack
66
+ amplitude.run
67
+ end
68
+ end
69
+
70
+ context 'the input only contains the user_id_key' do
71
+ let(:event) do
72
+ {
73
+ 'user_id' => 42,
74
+ 'first_name' => 'Bobby',
75
+ 'last_name' => 'Weir',
76
+ 'state' => 'CA',
77
+ 'current_source' => 'fb_share',
78
+ 'recruiter_id' => 710
79
+ }
80
+ end
81
+ let(:formatted_event) do
82
+ {
83
+ event_type: tag,
84
+ user_id: 42,
85
+ user_properties: {
86
+ first_name: 'Bobby',
87
+ last_name: 'Weir'
88
+ },
89
+ event_properties: {
90
+ current_source: 'fb_share'
91
+ }
92
+ }
93
+ end
94
+ it 'produces the expected output without device_id' do
95
+ amplitude.expect_format [tag, now, formatted_event].to_msgpack
96
+ amplitude.run
97
+ end
98
+ end
99
+
100
+ context 'the input only contains the device_id field' do
101
+ let(:event) do
102
+ {
103
+ 'uuid' => 'e6153b00-85d8-11e6-b1bc-43192d1e493f',
104
+ 'first_name' => 'Bobby',
105
+ 'last_name' => 'Weir',
106
+ 'state' => 'CA',
107
+ 'current_source' => 'fb_share',
108
+ 'recruiter_id' => 710
109
+ }
110
+ end
111
+ let(:formatted_event) do
112
+ {
113
+ event_type: tag,
114
+ device_id: 'e6153b00-85d8-11e6-b1bc-43192d1e493f',
115
+ user_properties: {
116
+ first_name: 'Bobby',
117
+ last_name: 'Weir'
118
+ },
119
+ event_properties: {
120
+ current_source: 'fb_share'
121
+ }
122
+ }
123
+ end
124
+ it 'produces the expected output without user_id' do
125
+ amplitude.expect_format [tag, now, formatted_event].to_msgpack
126
+ amplitude.run
127
+ end
128
+ end
129
+
130
+ context 'the input only contains neither user_id nor device_id field' do
131
+ let(:event) do
132
+ {
133
+ 'first_name' => 'Bobby',
134
+ 'last_name' => 'Weir',
135
+ 'state' => 'CA',
136
+ 'current_source' => 'fb_share',
137
+ 'recruiter_id' => 710
138
+ }
139
+ end
140
+ it 'raises a Fluent::AmplitudeOutput::AmplitudeError' do
141
+ expect { amplitude.run }.to raise_error(
142
+ Fluent::AmplitudeOutput::AmplitudeError
143
+ )
144
+ end
145
+ end
146
+
147
+ context 'properties_blacklist is specified' do
148
+ let(:conf) do
149
+ %(
150
+ api_key XXXXXX
151
+ user_id_key user_id
152
+ device_id_key uuid
153
+ user_properties first_name, last_name
154
+ properties_blacklist foo, state
155
+ )
156
+ end
157
+
158
+ let(:event) do
159
+ {
160
+ 'user_id' => 42,
161
+ 'uuid' => 'e6153b00-85d8-11e6-b1bc-43192d1e493f',
162
+ 'first_name' => 'Bobby',
163
+ 'last_name' => 'Weir',
164
+ 'state' => 'CA',
165
+ 'current_source' => 'fb_share',
166
+ 'recruiter_id' => 710,
167
+ 'foo' => 'bar'
168
+ }
169
+ end
170
+ let(:formatted_event) do
171
+ {
172
+ event_type: tag,
173
+ user_id: 42,
174
+ device_id: 'e6153b00-85d8-11e6-b1bc-43192d1e493f',
175
+ user_properties: {
176
+ first_name: 'Bobby',
177
+ last_name: 'Weir'
178
+ },
179
+ event_properties: {
180
+ current_source: 'fb_share',
181
+ recruiter_id: 710
182
+ }
183
+ }
184
+ end
185
+ it 'produces the expected output without blacklisted properties' do
186
+ amplitude.expect_format [tag, now, formatted_event].to_msgpack
187
+ amplitude.run
188
+ end
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,13 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+ Bundler.setup(:default, :test)
5
+ Bundler.require(:default, :test)
6
+
7
+ require 'fluent/test'
8
+ require 'rspec'
9
+
10
+ Test::Unit::AutoRunner.need_auto_run = false if defined?(Test::Unit::AutoRunner)
11
+
12
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
13
+ require 'fluent/plugin/out_amplitude'
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fluent-plugin-amplitude
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vijay Ramesh
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-10-28 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.55
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 0.10.55
27
+ - !ruby/object:Gem::Dependency
28
+ name: amplitude-api
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.0.9
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.0.9
41
+ - !ruby/object:Gem::Dependency
42
+ name: msgpack
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 1.0.2
51
+ type: :runtime
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: '1.0'
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 1.0.2
61
+ - !ruby/object:Gem::Dependency
62
+ name: rake
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '11.3'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '11.3'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '3.5'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '3.5'
89
+ - !ruby/object:Gem::Dependency
90
+ name: test-unit
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3.2'
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: 3.2.1
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '3.2'
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: 3.2.1
109
+ - !ruby/object:Gem::Dependency
110
+ name: rspec-mocks
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '3.5'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '3.5'
123
+ - !ruby/object:Gem::Dependency
124
+ name: rubocop
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: 0.44.1
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: 0.44.1
137
+ description: Fluentd plugin to output event data to Amplitude
138
+ email:
139
+ - vijay@change.org
140
+ executables: []
141
+ extensions: []
142
+ extra_rdoc_files: []
143
+ files:
144
+ - ".gitignore"
145
+ - Gemfile
146
+ - LICENSE
147
+ - README.md
148
+ - Rakefile
149
+ - fluent-plugin-amplitude.gemspec
150
+ - lib/fluent/plugin/out_amplitude.rb
151
+ - spec/out_amplitude_spec.rb
152
+ - spec/spec_helper.rb
153
+ homepage: https://github.com/change/fluent-plugin-amplitude
154
+ licenses: []
155
+ metadata: {}
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ required_rubygems_version: !ruby/object:Gem::Requirement
166
+ requirements:
167
+ - - ">="
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ requirements: []
171
+ rubyforge_project:
172
+ rubygems_version: 2.4.5.1
173
+ signing_key:
174
+ specification_version: 4
175
+ summary: Fluentd plugin to output event data to Amplitude
176
+ test_files:
177
+ - spec/out_amplitude_spec.rb
178
+ - spec/spec_helper.rb