logstash-filter-mixpanel 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzNhMGYxMmM5OTBkZjFlMjQxZDc0NjE4ZjRmMzk1NWI0ZjQ4N2U2ZA==
4
+ ZDU0ODI4YTRjYjk1YzRiNDk5YTdkZTNhMWRmM2U4MjMyNzNmMmMxNA==
5
5
  data.tar.gz: !binary |-
6
- YTRlMzhmOTc3MzhlZjYwZWZkZWJiMTdlY2Q1Mzk3YWJiOWNhMWMyMg==
6
+ Y2E2ZDE0OGNjOGQ0MGQwNDBjNDhlZGRkYjEzMDc5ODcyNmQ1MTA5ZQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzIyMDhkODU3YWJkMjdlNGY5Yzc4ZGUyMDI4NzRjMWVjZDVmYjhkY2Q5M2Fi
10
- NTIxY2RmMTkyYTMzYmNiMzdiYzRjZTNjNTFkYTI2ZWJlN2E4YjNkNzIyZDU0
11
- ZTljYTNkZGMzMTE1NTE5ZWY2MzkyYjExOWI4ZmRlZTRiOTI5MDA=
9
+ NmFjMmI3MTdkMjAxOWVkY2RlNzBmOWJiMTc0MDU0OWQzZGFmODZiZWRhYjE1
10
+ ZThlMTI1NGNlMjU0NTIxMmQ3NDE4Njk4OWFjODNlZmNjNmNlZGFiMTdlNGNh
11
+ YTg0ZTIxNjU5NGNkNmExNmJhODVlZmMzYjFmYzY1YzUzZWYzMmE=
12
12
  data.tar.gz: !binary |-
13
- MWU1NDBjYmUyOGRjNTk3MGFiZjY2MWM2YTc0MDAxNzI2YmQzM2U5YjViMTQz
14
- ZGUwYTQ4ZmMzNTJhZjRlOTI1ODBhMTkzMWFhNDQxOWE4MGJiM2Q0MjU1MmJl
15
- ZWU4YWVjYmJhYWE4MzIxOGNhYWMzMjY3M2M2YWJhNDczZTIyYzY=
13
+ ODViNGM2ZDU0NjhlYmQ0NGYwYjkyZjVkM2UxODkyMmEyYzUwNGQ2ZmI1MDQ4
14
+ MTgwOTMzYjY5NDRmNzdkOGVhZjk3NWNiYTE1ZWUxMTJkNjJlOTFkODI4N2Mw
15
+ YTY2OTE4NDQ5ZmI0ZjJkZmMwZDg2YjUxODNiN2JiZGJiZGYwZjY=
@@ -24,9 +24,11 @@ class LogStash::Filters::Mixpanel < LogStash::Filters::Base
24
24
  config :api_key, :validate => :string, :required => true
25
25
  config :api_secret, :validate => :string, :required => true
26
26
  config :where, :validate => :array, :required => true
27
+ config :use_or, :validate => :boolean, :default => false
27
28
  config :source, :validate => :string, :default => 'message'
28
29
  config :target, :validate => :string, :default => 'mixpanel'
29
30
  config :tag_on_failure, :validate => :array, :default => ['_mixpanelfilterfailure']
31
+ config :tag_on_multiresults, :validate => :array, :default => ['_mixpanelfiltermultiresults']
30
32
 
31
33
 
32
34
  public
@@ -40,7 +42,7 @@ class LogStash::Filters::Mixpanel < LogStash::Filters::Base
40
42
  public
41
43
  def filter(event)
42
44
 
43
- result = fetch_data
45
+ result = fetch_data event
44
46
  if !result.nil?
45
47
  event[@target] = result
46
48
 
@@ -55,12 +57,18 @@ class LogStash::Filters::Mixpanel < LogStash::Filters::Base
55
57
  end # def filter
56
58
 
57
59
  private
58
- def fetch_data
60
+ def fetch_data(event)
59
61
  options = {}
60
62
  options['where'] = prepare_where @where if @where
61
63
 
62
64
  response = @mp.request('engage', options)
63
- if response['results'].size >= 1
65
+ if response['results'].size == 1
66
+ single_res = response['results'][0]
67
+ elsif response['results'].size > 1
68
+ @tag_on_multiresults.each do |tag|
69
+ event['tags'] ||= []
70
+ event['tags'] << tag unless event['tags'].include?(tag)
71
+ end
64
72
  single_res = response['results'][0]
65
73
  else
66
74
  return nil
@@ -72,18 +80,22 @@ class LogStash::Filters::Mixpanel < LogStash::Filters::Base
72
80
  end
73
81
 
74
82
  private
75
- def prepare_where wheredata
83
+ def prepare_where(wheredata)
76
84
  special_properties = %w(email first_name last_name last_seen created)
77
85
  res_array = []
78
86
  wheredata.each { |constraint|
79
87
  constraint.each { |key, value|
80
88
  # prepend key with dollar sigh if key is in special_properties
81
- # TODO: add test for special properties without dollar sign
82
89
  key = "$#{key}" if special_properties.include? key
83
90
 
84
91
  res_array.push "properties[\"#{key}\"] == \"#{value}\""
85
92
  }
86
93
  }
87
- res_array.join ' and '
94
+ if @use_or
95
+ result = res_array.join ' or '
96
+ else
97
+ result = res_array.join ' and '
98
+ end
99
+ result
88
100
  end
89
- end # class LogStash::Filters::Example
101
+ end # class LogStash::Filters::Mixpanel
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-filter-mixpanel'
3
- s.version = '0.1.3'
3
+ s.version = '0.1.4'
4
4
  s.version = "#{s.version}.pre.#{ENV['TRAVIS_BUILD_NUMBER']}" if ENV['TRAVIS'] and ENV['TRAVIS_BRANCH'] != 'master'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "This filter checks mixpanel for additional people data and adds it to the event data"
@@ -1,5 +1,6 @@
1
1
  require File.absolute_path(File.join(File.dirname(__FILE__), '../../spec/spec_helper'))
2
2
  require File.absolute_path(File.join(File.dirname(__FILE__), '../../lib/logstash/filters/mixpanel'))
3
+ require 'rspec'
3
4
  require 'mixpanel_client'
4
5
  require 'mixpanel-ruby'
5
6
  require 'ffaker'
@@ -7,39 +8,6 @@ require 'base64'
7
8
 
8
9
 
9
10
  describe LogStash::Filters::Mixpanel do
10
- before(:all) do
11
- @mp = Mixpanel::Tracker.new(ENV['MP_PROJECT_TOKEN'])
12
-
13
- @user_1_id = FFaker::Guid.guid
14
- @user_1_ip = FFaker::Internet.ip_v4_address
15
- @user_1_email = FFaker::Internet.safe_email
16
- @user_1_first_name = FFaker::NameDE.first_name
17
- @user_1_last_name = FFaker::NameDE.last_name
18
- @user_1_data = {
19
- :$first_name => @user_1_first_name,
20
- :$last_name => @user_1_last_name,
21
- :$email => @user_1_email,
22
- 'Device ID' => @user_1_id
23
- }
24
- @mp.people.set(@user_1_id, @user_1_data, ip=@user_1_ip)
25
- @mp.track(@user_1_id, 'user 1 created')
26
-
27
- @user_2_id = FFaker::Guid.guid
28
- @user_2_ip = FFaker::Internet.ip_v4_address
29
- @user_2_email = FFaker::Internet.safe_email
30
- @user_2_first_name = @user_1_first_name
31
- @user_2_last_name = @user_1_last_name
32
- @user_2_data = {
33
- :$first_name => @user_2_first_name,
34
- :$last_name => @user_2_last_name,
35
- :$email => @user_2_email,
36
- 'Device ID' => @user_2_id
37
- }
38
- @mp.people.set(@user_2_id, @user_2_data, ip=@user_2_ip)
39
- @mp.track(@user_2_id, 'user 2 created')
40
-
41
-
42
- end
43
11
 
44
12
  context 'raise error' do
45
13
  context 'on wrong api key config' do
@@ -106,95 +74,244 @@ describe LogStash::Filters::Mixpanel do
106
74
 
107
75
  context 'fetch created user' do
108
76
  context 'by device id' do
77
+ before {
78
+ @id = FFaker::Guid.guid
79
+ @expected_result = {
80
+ 'page' => 0,
81
+ 'page_size' => 1000,
82
+ 'results' => [{ '$distinc_id' => 123124,
83
+ '$properties' => { '$created' => '2008-12-12T11:20:47',
84
+ '$email' => 'example@mixpanel.com',
85
+ '$first_name' => 'Example',
86
+ '$last_name' => 'Name',
87
+ 'Device ID' => @id,
88
+ '$last_seen' => '2008-06-09T23:08:40' }
89
+ }]
90
+ }
91
+ Mixpanel::Client.any_instance.stub(:request).and_return(@expected_result)
92
+ }
93
+
109
94
  let(:config) do <<-CONFIG
110
95
  filter {
111
96
  mixpanel {
112
97
  api_key => '#{ENV['MP_PROJECT_KEY']}'
113
98
  api_secret => '#{ENV['MP_PROJECT_SECRET']}'
114
- where => [{'Device ID' => '#{@user_1_id}'}]
99
+ where => [{'Device ID' => '#{@id}'}]
115
100
  }
116
101
  }
117
102
  CONFIG
118
103
  end
119
104
 
120
- sample("message" => "123") do
105
+ sample('message' => '123') do
121
106
  expect(subject).to include('mixpanel')
122
107
  expect(subject['mixpanel']).to include('Device ID')
123
108
  expect(subject['mixpanel']).to include('$distinct_id')
124
109
  expect(subject['mixpanel']).to include('$email')
125
110
  expect(subject['mixpanel']).to include('$last_name')
126
111
  expect(subject['mixpanel']).to include('Device ID')
112
+ expect(subject['mixpanel']['Device ID']).to eq(@id)
113
+ expect(subject['mixpanel']).to eq(@expected_result['results'][0]['$properties'])
127
114
  insist { subject['tags'] }.nil?
128
115
  end
129
116
  end
130
117
 
131
- context 'by email' do
132
- let(:config) do <<-CONFIG
133
- filter {
134
- mixpanel {
135
- api_key => '#{ENV['MP_PROJECT_KEY']}'
136
- api_secret => '#{ENV['MP_PROJECT_SECRET']}'
137
- where => [{'email' => '#{@user_1_email}'}]
118
+ # TODO: Create Unit test for "by email if it has no dollar char"
119
+ # context 'by email if it has no dollar char' do
120
+ # before {
121
+ # @id = FFaker::Guid.guid
122
+ # @expected_result = {
123
+ # 'page' => 0,
124
+ # 'page_size' => 1000,
125
+ # 'results' => [{ '$distinc_id' => 123124,
126
+ # '$properties' => { '$created' => '2008-12-12T11:20:47',
127
+ # '$email' => 'example@mixpanel.com',
128
+ # '$first_name' => 'Example',
129
+ # '$last_name' => 'Name',
130
+ # 'Device ID' => @id,
131
+ # '$last_seen' => '2008-06-09T23:08:40' }
132
+ # }]
133
+ # }
134
+ # Mixpanel::Client.any_instance.stub(:request).and_return(@expected_result)
135
+ # }
136
+ #
137
+ # let(:config) do <<-CONFIG
138
+ # filter {
139
+ # mixpanel {
140
+ # api_key => '#{ENV['MP_PROJECT_KEY']}'
141
+ # api_secret => '#{ENV['MP_PROJECT_SECRET']}'
142
+ # where => [{'email' => '#{@id}'}]
143
+ # }
144
+ # }
145
+ # CONFIG
146
+ # end
147
+ #
148
+ # sample('message' => '123') do
149
+ # expect(subject).to include("mixpanel")
150
+ # expect(subject['mixpanel']).to include('Device ID')
151
+ # expect(subject['mixpanel']).to include('$distinct_id')
152
+ # expect(subject['mixpanel']).to include('$email')
153
+ # expect(subject['mixpanel']).to include('$last_name')
154
+ # expect(subject['mixpanel']).to include('Device ID')
155
+ # insist { subject['tags'] }.nil?
156
+ # end
157
+ # end
158
+ #
159
+ # TODO: Create Unit test for "by email if it has dollar char"
160
+ # context 'by email if it has dollar char' do
161
+ # let(:config) do <<-CONFIG
162
+ # filter {
163
+ # mixpanel {
164
+ # api_key => '#{ENV['MP_PROJECT_KEY']}'
165
+ # api_secret => '#{ENV['MP_PROJECT_SECRET']}'
166
+ # where => [{'$email' => '#{@user_1_email}'}]
167
+ # }
168
+ # }
169
+ # CONFIG
170
+ # end
171
+ #
172
+ # sample('message' => '123') do
173
+ # expect(subject).to include("mixpanel")
174
+ # expect(subject['mixpanel']).to include('Device ID')
175
+ # expect(subject['mixpanel']).to include('$distinct_id')
176
+ # expect(subject['mixpanel']).to include('$email')
177
+ # expect(subject['mixpanel']).to include('$last_name')
178
+ # expect(subject['mixpanel']).to include('Device ID')
179
+ # insist { subject['tags'] }.nil?
180
+ # end
181
+ # end
182
+ end
183
+
184
+ context 'test on multiple returns' do
185
+ context 'with and constraint' do
186
+ before {
187
+ @first_name = FFaker::NameDE.first_name
188
+ @expected_result = {
189
+ 'page' => 0,
190
+ 'page_size' => 1000,
191
+ 'results' => [{ '$distinc_id' => 123124,
192
+ '$properties' => { '$created' => '2008-12-12T11:20:47',
193
+ '$email' => 'example1@mixpanel.com',
194
+ '$first_name' => @first_name,
195
+ '$last_name' => 'Name1',
196
+ 'Device ID' => '123',
197
+ '$last_seen' => '2008-06-09T23:08:40' }
198
+ }, { '$distinc_id' => 1231244,
199
+ '$properties' => { '$created' => '2008-12-12T11:20:47',
200
+ '$email' => 'example2@mixpanel.com',
201
+ '$first_name' => @first_name,
202
+ '$last_name' => 'Name2',
203
+ 'Device ID' => '1234',
204
+ '$last_seen' => '2008-06-09T23:08:40' }
205
+ }]
138
206
  }
207
+ Mixpanel::Client.any_instance.stub(:request).and_return(@expected_result)
139
208
  }
140
- CONFIG
209
+
210
+ let(:config) do <<-CONFIG
211
+ filter {
212
+ mixpanel {
213
+ api_key => '#{ENV['MP_PROJECT_KEY']}'
214
+ api_secret => '#{ENV['MP_PROJECT_SECRET']}'
215
+ where => [{'first_name' => '#{@first_name}'}]
216
+ }
217
+ }
218
+ CONFIG
141
219
  end
142
220
 
143
- sample("message" => "123") do
144
- expect(subject).to include('mixpanel')
221
+ sample('message' => '123') do
222
+ expect(subject).to include("mixpanel")
145
223
  expect(subject['mixpanel']).to include('Device ID')
146
224
  expect(subject['mixpanel']).to include('$distinct_id')
147
225
  expect(subject['mixpanel']).to include('$email')
226
+ expect(subject['mixpanel']).to include('$first_name')
148
227
  expect(subject['mixpanel']).to include('$last_name')
149
228
  expect(subject['mixpanel']).to include('Device ID')
150
- insist { subject['tags'] }.nil?
229
+ expect(subject).to include('tags')
230
+
231
+ expect(subject['tags']).to include('_mixpanelfiltermultiresults')
232
+ expect(subject['mixpanel']).to eq(@expected_result['results'][0]['$properties'])
233
+ # expect(subject['mixpanel']['$first_name']).to eq(@first_name)
234
+ # expect(subject['mixpanel']['$last_name']).to eq('Name1')
151
235
  end
152
236
  end
153
- end
154
237
 
155
- context 'test on multiple returns' do
156
- let(:config) do <<-CONFIG
157
- filter {
158
- mixpanel {
159
- api_key => '#{ENV['MP_PROJECT_KEY']}'
160
- api_secret => '#{ENV['MP_PROJECT_SECRET']}'
161
- where => [{'first_name' => '#{@user_1_first_name}'}]
238
+ context 'with or constraint' do
239
+ before {
240
+ @email1 = FFaker::Internet.safe_email
241
+ @email2 = FFaker::Internet.safe_email
242
+ @expected_result = {
243
+ 'page' => 0,
244
+ 'page_size' => 1000,
245
+ 'results' => [{ '$distinc_id' => 123124,
246
+ '$properties' => { '$created' => '2008-12-12T11:20:47',
247
+ '$email' => 'example1@mixpanel.com',
248
+ '$first_name' => 'Firstname1',
249
+ '$last_name' => 'Name1',
250
+ 'Device ID' => '123',
251
+ '$last_seen' => '2008-06-09T23:08:40' }
252
+ }, { '$distinc_id' => 1231244,
253
+ '$properties' => { '$created' => '2008-12-12T11:20:47',
254
+ '$email' => 'example1@mixpanel.com',
255
+ '$first_name' => 'Firstname2',
256
+ '$last_name' => 'Name2',
257
+ 'Device ID' => '1234',
258
+ '$last_seen' => '2008-06-09T23:08:40' }
259
+ }]
162
260
  }
261
+ Mixpanel::Client.any_instance.stub(:request).and_return(@expected_result)
163
262
  }
164
- CONFIG
165
- end
166
263
 
167
- sample("message" => "123") do
168
- expect(subject).to include('mixpanel')
169
- expect(subject['mixpanel']).to include('Device ID')
170
- expect(subject['mixpanel']).to include('$distinct_id')
171
- expect(subject['mixpanel']).to include('$email')
172
- expect(subject['mixpanel']).to include('$last_name')
173
- expect(subject['mixpanel']).to include('Device ID')
174
- insist { subject['tags'] }.nil?
264
+ let(:config) do <<-CONFIG
265
+ filter {
266
+ mixpanel {
267
+ api_key => '#{ENV['MP_PROJECT_KEY']}'
268
+ api_secret => '#{ENV['MP_PROJECT_SECRET']}'
269
+ where => [{'email' => '#{@email1}'}, {'email' => '#{@email2}'}]
270
+ use_or => true
271
+ }
272
+ }
273
+ CONFIG
274
+ end
275
+
276
+ sample('message' => '123') do
277
+ expect(subject).to include('mixpanel')
278
+ expect(subject['mixpanel']).to include('Device ID')
279
+ expect(subject['mixpanel']).to include('$distinct_id')
280
+ expect(subject['mixpanel']).to include('$email')
281
+ expect(subject['mixpanel']).to include('$last_name')
282
+ expect(subject['mixpanel']).to include('Device ID')
283
+
284
+ expect(subject).to include('tags')
285
+ expect(subject['tags']).to include('_mixpanelfiltermultiresults')
286
+ expect(subject['mixpanel']).to eq(@expected_result['results'][0]['$properties'])
287
+ end
175
288
  end
176
289
  end
177
290
 
178
291
  context 'test on no returns' do
292
+ before {
293
+ @expected_result = {
294
+ 'page' => 0,
295
+ 'page_size' => 1000,
296
+ 'results' => []
297
+ }
298
+ Mixpanel::Client.any_instance.stub(:request).and_return(@expected_result)
299
+ }
300
+
179
301
  let(:config) do <<-CONFIG
180
302
  filter {
181
303
  mixpanel {
182
304
  api_key => '#{ENV['MP_PROJECT_KEY']}'
183
305
  api_secret => '#{ENV['MP_PROJECT_SECRET']}'
184
- where => [{'first_name' => 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'}]
306
+ where => [{'$first_name' => 'thisfirstnameshouldneverbeseen123'}]
185
307
  }
186
308
  }
187
309
  CONFIG
188
310
  end
189
311
 
190
- sample("message" => "123") do
191
- insist { subject["tags"] }.include?('_mixpanelfilterfailure')
312
+ sample('message' => '123') do
313
+ insist { subject['tags'] }.include?('_mixpanelfilterfailure')
192
314
  reject { subject }.include?('mixpanel')
193
315
  end
194
316
  end
195
-
196
- after(:all) do
197
- @mp.people.delete_user(@user_1_id)
198
- @mp.people.delete_user(@user_2_id)
199
- end
200
317
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-filter-mixpanel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Torsten Feld