fluent-plugin-mixpanel 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 +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +13 -0
- data/README.md +58 -0
- data/Rakefile +11 -0
- data/fluent-plugin-mixpanel.gemspec +25 -0
- data/lib/fluent/plugin/out_mixpanel.rb +76 -0
- data/test/helper.rb +28 -0
- data/test/plugin/test_out_mixpanel.rb +93 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d8d9a539d77b2b4338ad6de2f4389095fd034816
|
4
|
+
data.tar.gz: 62760bebcef57a117db6191fd5610d99a079ca7e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9383f6371b857b50d34892e334193b308124378497f70f9baaf4c21af058acc89a34e6ecf3222fa3f4800e6435ea8360caaa8fe2aa2fd69f9d0a45b2d264324c
|
7
|
+
data.tar.gz: f4c3f7cc40d6879ef48dd827a655a50d8caa583ba2a69578632f5db62ce9638ac17349941354423e82566feec5a8d1144fa4f23801aaed009790bc49b02eedd5
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
Copyright (c) 2014- Kazuyuki Honda
|
2
|
+
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
you may not use this file except in compliance with the License.
|
5
|
+
You may obtain a copy of the License at
|
6
|
+
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
See the License for the specific language governing permissions and
|
13
|
+
limitations under the License.
|
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# fluent-plugin-mixpanel
|
2
|
+
|
3
|
+
[](https://travis-ci.org/hakobera/fluent-plugin-mixpanel)
|
4
|
+
|
5
|
+
## Component
|
6
|
+
|
7
|
+
### MixpanelOutput
|
8
|
+
|
9
|
+
[Fluentd](http://fluentd.org) plugin to send event track data to [mixpanel](https://mixpanel.com).
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
Install with gem or fluent-gem command as:
|
14
|
+
|
15
|
+
```
|
16
|
+
# for fluentd
|
17
|
+
$ gem install fluent-plugin-mixpanel
|
18
|
+
|
19
|
+
# for td-agent
|
20
|
+
$ sudo /usr/lib64/fluent/ruby/bin/fluent-gem install fluent-plugin-mixpanel
|
21
|
+
```
|
22
|
+
|
23
|
+
## Configuration
|
24
|
+
|
25
|
+
### MixpanelOutput
|
26
|
+
|
27
|
+
MixpanelOutput needs mixpanel's `project_token`, that can get from your mixpanel project settings.
|
28
|
+
You should also specify property key name by `distinct_id_key` and `event_key`.
|
29
|
+
|
30
|
+
```xml
|
31
|
+
<match output.mixpanel.*>
|
32
|
+
type mixpanel
|
33
|
+
project_token YOUR_PROJECT_TOKEN
|
34
|
+
distinct_id_key user_id
|
35
|
+
event_key event_name
|
36
|
+
</match>
|
37
|
+
```
|
38
|
+
|
39
|
+
If record like this:
|
40
|
+
|
41
|
+
```rb
|
42
|
+
{ user_id: "123", event_name: "event1", key1: "value1", key2: "value2" }
|
43
|
+
```
|
44
|
+
|
45
|
+
above settings send to the following data to mixpanel, using [mixpanel-ruby](https://github.com/mixpanel/mixpanel-ruby) gem.
|
46
|
+
|
47
|
+
```rb
|
48
|
+
tracker = Mixpanel::Tracker.new(YOUR_PROJECT_TOKEN)
|
49
|
+
tracker.track("123", "event1", { key1: "value1", key2: "value2" })
|
50
|
+
```
|
51
|
+
|
52
|
+
## Contributing
|
53
|
+
|
54
|
+
1. Fork it ( http://github.com/hakobera/fluent-plugin-mixpanel/fork )
|
55
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
56
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
57
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
58
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
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-mixpanel"
|
7
|
+
spec.version = "0.0.1"
|
8
|
+
spec.authors = ["Kazuyuki Honda"]
|
9
|
+
spec.email = ["hakobera@gmail.com"]
|
10
|
+
spec.summary = %q{Fluentd plugin to send event track data to mixpanel}
|
11
|
+
spec.description = %q{Fluentd plugin to send event track data to mixpanel}
|
12
|
+
spec.homepage = "https://github.com/hakobera/fluent-plugin-mixpanel"
|
13
|
+
spec.license = "Apache License, Version 2.0"
|
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_runtime_dependency "fluentd"
|
21
|
+
spec.add_runtime_dependency "mixpanel-ruby"
|
22
|
+
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
spec.add_development_dependency "webmock"
|
25
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
class Fluent::MixpanelOutput < Fluent::BufferedOutput
|
2
|
+
Fluent::Plugin.register_output('mixpanel', self)
|
3
|
+
|
4
|
+
config_param :project_token, :string
|
5
|
+
config_param :distinct_id_key, :string
|
6
|
+
config_param :event_key, :string
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super
|
10
|
+
require 'mixpanel-ruby'
|
11
|
+
end
|
12
|
+
|
13
|
+
def configure(conf)
|
14
|
+
super
|
15
|
+
@project_tokey = conf['project_token']
|
16
|
+
@distinct_id_key = conf['distinct_id_key']
|
17
|
+
@event_key = conf['event_key']
|
18
|
+
|
19
|
+
if @project_token.empty?
|
20
|
+
raise Fluent::ConfigError, "'project_token' must be specifed."
|
21
|
+
end
|
22
|
+
|
23
|
+
if @distinct_id_key.empty?
|
24
|
+
raise Fluent::ConfigError, "'distinct_id_key' must be specifed."
|
25
|
+
end
|
26
|
+
|
27
|
+
if @event_key.empty?
|
28
|
+
raise Fluent::ConfigError, "'event_key' must be specifed."
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def start
|
33
|
+
super
|
34
|
+
@tracker = Mixpanel::Tracker.new(@project_token)
|
35
|
+
end
|
36
|
+
|
37
|
+
def shutdown
|
38
|
+
super
|
39
|
+
end
|
40
|
+
|
41
|
+
def format(tag, time, record)
|
42
|
+
[tag, time, record].to_msgpack
|
43
|
+
end
|
44
|
+
|
45
|
+
def write(chunk)
|
46
|
+
records = []
|
47
|
+
chunk.msgpack_each do |tag, time, record|
|
48
|
+
data = {}
|
49
|
+
|
50
|
+
if record[@distinct_id_key]
|
51
|
+
data['distinct_id'] = record[@distinct_id_key]
|
52
|
+
record.delete(@distinct_id_key)
|
53
|
+
else
|
54
|
+
log.warn('no distinct_id')
|
55
|
+
return
|
56
|
+
end
|
57
|
+
|
58
|
+
if record[@event_key]
|
59
|
+
data['event'] = record[@event_key]
|
60
|
+
record.delete(@event_key)
|
61
|
+
else
|
62
|
+
log.warn('no event')
|
63
|
+
return
|
64
|
+
end
|
65
|
+
|
66
|
+
record.merge!(time: time.to_i)
|
67
|
+
data['properties'] = record
|
68
|
+
|
69
|
+
records << data
|
70
|
+
end
|
71
|
+
|
72
|
+
records.each do |record|
|
73
|
+
@tracker.track(record['distinct_id'], record['event'], record['properties'])
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
13
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
14
|
+
require 'fluent/test'
|
15
|
+
unless ENV.has_key?('VERBOSE')
|
16
|
+
nulllogger = Object.new
|
17
|
+
nulllogger.instance_eval {|obj|
|
18
|
+
def method_missing(method, *args)
|
19
|
+
# pass
|
20
|
+
end
|
21
|
+
}
|
22
|
+
$log = nulllogger
|
23
|
+
end
|
24
|
+
|
25
|
+
require 'fluent/plugin/out_mixpanel'
|
26
|
+
|
27
|
+
class Test::Unit::TestCase
|
28
|
+
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'helper'
|
2
|
+
require 'uri'
|
3
|
+
require 'webmock/test_unit'
|
4
|
+
|
5
|
+
WebMock.disable_net_connect!
|
6
|
+
|
7
|
+
class MixpanelOutputTest < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
Fluent::Test.setup
|
11
|
+
@out = []
|
12
|
+
end
|
13
|
+
|
14
|
+
CONFIG = %[
|
15
|
+
project_token test_token
|
16
|
+
distinct_id_key user_id
|
17
|
+
event_key event
|
18
|
+
]
|
19
|
+
|
20
|
+
def create_driver(conf = CONFIG)
|
21
|
+
Fluent::Test::BufferedOutputTestDriver.new(Fluent::MixpanelOutput).configure(conf)
|
22
|
+
end
|
23
|
+
|
24
|
+
def stub_mixpanel(url="https://api.mixpanel.com/track")
|
25
|
+
stub_request(:post, url).with do |req|
|
26
|
+
body = URI.decode_www_form(req.body)
|
27
|
+
@out << JSON.load(Base64.decode64(body.assoc('data').last))
|
28
|
+
end.to_return(status: 200, body: JSON.generate({ status: 1 }))
|
29
|
+
end
|
30
|
+
|
31
|
+
def stub_mixpanel_unavailable(url="https://api.mixpanel.com/track")
|
32
|
+
stub_request(:post, url).to_return(status: 503, body: "Service Unavailable")
|
33
|
+
end
|
34
|
+
|
35
|
+
def sample_record
|
36
|
+
{ user_id: "123", event: "event1", key1: "value1", key2: "value2" }
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_configure
|
40
|
+
d = create_driver
|
41
|
+
|
42
|
+
assert_equal 'test_token', d.instance.project_token
|
43
|
+
assert_equal 'user_id', d.instance.distinct_id_key
|
44
|
+
assert_equal 'event', d.instance.event_key
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_write
|
48
|
+
stub_mixpanel
|
49
|
+
d = create_driver
|
50
|
+
time = Time.new('2014-01-01T01:23:45+00:00')
|
51
|
+
d.emit(sample_record, time)
|
52
|
+
d.run
|
53
|
+
|
54
|
+
assert_equal "123", @out[0]['properties']['distinct_id']
|
55
|
+
assert_equal "event1", @out[0]['event']
|
56
|
+
assert_equal time.to_i, @out[0]['properties']['time']
|
57
|
+
assert_equal "value1", @out[0]['properties']['key1']
|
58
|
+
assert_equal "value2", @out[0]['properties']['key2']
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_write_multi_request
|
62
|
+
stub_mixpanel
|
63
|
+
d = create_driver
|
64
|
+
time1 = Time.new('2014-01-01T01:23:45+00:00')
|
65
|
+
time2 = Time.new('2014-01-02T01:23:45+00:00')
|
66
|
+
|
67
|
+
d.emit(sample_record, time1)
|
68
|
+
d.emit(sample_record.merge(key3: "value3"), time2)
|
69
|
+
d.run
|
70
|
+
|
71
|
+
assert_equal "123", @out[0]['properties']['distinct_id']
|
72
|
+
assert_equal "event1", @out[0]['event']
|
73
|
+
assert_equal time1.to_i, @out[0]['properties']['time']
|
74
|
+
assert_equal "value1", @out[0]['properties']['key1']
|
75
|
+
assert_equal "value2", @out[0]['properties']['key2']
|
76
|
+
|
77
|
+
assert_equal "123", @out[1]['properties']['distinct_id']
|
78
|
+
assert_equal "event1", @out[1]['event']
|
79
|
+
assert_equal time2.to_i, @out[1]['properties']['time']
|
80
|
+
assert_equal "value1", @out[1]['properties']['key1']
|
81
|
+
assert_equal "value2", @out[1]['properties']['key2']
|
82
|
+
assert_equal "value2", @out[1]['properties']['key2']
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_request_error
|
86
|
+
stub_mixpanel_unavailable
|
87
|
+
d = create_driver
|
88
|
+
d.emit(sample_record)
|
89
|
+
assert_raise(Mixpanel::ConnectionError) {
|
90
|
+
d.run
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fluent-plugin-mixpanel
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kazuyuki Honda
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-11 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: mixpanel-ruby
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
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: webmock
|
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
|
+
description: Fluentd plugin to send event track data to mixpanel
|
70
|
+
email:
|
71
|
+
- hakobera@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".travis.yml"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- fluent-plugin-mixpanel.gemspec
|
83
|
+
- lib/fluent/plugin/out_mixpanel.rb
|
84
|
+
- test/helper.rb
|
85
|
+
- test/plugin/test_out_mixpanel.rb
|
86
|
+
homepage: https://github.com/hakobera/fluent-plugin-mixpanel
|
87
|
+
licenses:
|
88
|
+
- Apache License, Version 2.0
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.2.0
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: Fluentd plugin to send event track data to mixpanel
|
110
|
+
test_files:
|
111
|
+
- test/helper.rb
|
112
|
+
- test/plugin/test_out_mixpanel.rb
|