moesif_rack 1.3.8 → 1.4.2
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 +4 -4
- data/README.md +177 -126
- data/lib/moesif_rack/app_config.rb +4 -0
- data/lib/moesif_rack/moesif_middleware.rb +90 -26
- data/moesif_capture_outgoing/httplog/http_log.rb +56 -4
- data/test/moesif_rack_test.rb +3 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d8635baa7838edc611616b3fcd19d30c6a8c9034f985b1a48df744eae3fc252
|
4
|
+
data.tar.gz: bf138ca57419057dafdc088f076e3b632a623cd5d268012e6e67a9ce60372ea9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25e43ffa1f612ed39c3ddcee9a55b29ff8f81ed0f9e7d36651d605232aec4ef3ba55cf2e072bd99e72ce46fccc565591872bb58ddd982d65da86a7305f0f4784
|
7
|
+
data.tar.gz: '095a38e7f8dc9e4ba2fbf9ffd40dfd2ac01fcd72b5475915266274a807c53b70054f823109648e73319557efc07c61ddfb95f99a5d4586855b3db1f0fed7573a'
|
data/README.md
CHANGED
@@ -22,7 +22,7 @@ gem install moesif_rack
|
|
22
22
|
and if you have a `Gemfile` in your project, please add this line to
|
23
23
|
|
24
24
|
```
|
25
|
-
gem 'moesif_rack', '~> 1.
|
25
|
+
gem 'moesif_rack', '~> 1.4.2'
|
26
26
|
|
27
27
|
```
|
28
28
|
|
@@ -126,12 +126,10 @@ Optional.
|
|
126
126
|
identify_user is a Proc that takes env, headers, and body as arguments and returns a user_id string. This helps us attribute requests to unique users. Even though Moesif can automatically retrieve the user_id without this, this is highly recommended to ensure accurate attribution.
|
127
127
|
|
128
128
|
```ruby
|
129
|
-
|
130
129
|
moesif_options['identify_user'] = Proc.new { |env, headers, body|
|
131
130
|
|
132
|
-
#
|
133
|
-
|
134
|
-
'my_user_id'
|
131
|
+
# Add your custom code that returns a string for user id
|
132
|
+
'12345'
|
135
133
|
}
|
136
134
|
|
137
135
|
```
|
@@ -145,13 +143,24 @@ identify_company is a Proc that takes env, headers, and body as arguments and re
|
|
145
143
|
|
146
144
|
moesif_options['identify_company'] = Proc.new { |env, headers, body|
|
147
145
|
|
148
|
-
#
|
149
|
-
|
150
|
-
'my_company_id'
|
146
|
+
# Add your custom code that returns a string for company id
|
147
|
+
'67890'
|
151
148
|
}
|
152
149
|
|
153
150
|
```
|
154
151
|
|
152
|
+
#### __`identify_session`__
|
153
|
+
|
154
|
+
Optional. A Proc that takes env, headers, body and returns a string.
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
|
158
|
+
moesif_options['identify_session'] = Proc.new { |env, headers, body|
|
159
|
+
# Add your custom code that returns a string for session/API token
|
160
|
+
'XXXXXXXXX'
|
161
|
+
}
|
162
|
+
```
|
163
|
+
|
155
164
|
#### __`get_metadata`__
|
156
165
|
|
157
166
|
Optional.
|
@@ -162,31 +171,15 @@ metadata to this event.
|
|
162
171
|
```ruby
|
163
172
|
|
164
173
|
moesif_options['get_metadata'] = Proc.new { |env, headers, body|
|
165
|
-
|
166
|
-
#snip
|
174
|
+
# Add your custom code that returns a dictionary
|
167
175
|
value = {
|
168
|
-
'
|
169
|
-
'
|
176
|
+
'datacenter' => 'westus',
|
177
|
+
'deployment_version' => 'v1.2.3'
|
170
178
|
}
|
171
|
-
|
172
179
|
value
|
173
180
|
}
|
174
181
|
```
|
175
182
|
|
176
|
-
#### __`identify_session`__
|
177
|
-
|
178
|
-
Optional. A Proc that takes env, headers, body and returns a string.
|
179
|
-
|
180
|
-
```ruby
|
181
|
-
|
182
|
-
moesif_options['identify_session'] = Proc.new { |env, headers, body|
|
183
|
-
|
184
|
-
#snip
|
185
|
-
|
186
|
-
'the_session_token'
|
187
|
-
}
|
188
|
-
|
189
|
-
```
|
190
183
|
|
191
184
|
#### __`mask_data`__
|
192
185
|
|
@@ -196,9 +189,8 @@ With mask_data, you can make modifications to headers or body of the event befor
|
|
196
189
|
```ruby
|
197
190
|
|
198
191
|
moesif_options['mask_data'] = Proc.new { |event_model|
|
199
|
-
|
200
|
-
|
201
|
-
|
192
|
+
# Add your custom code that returns a event_model after modifying any fields
|
193
|
+
event_model.response.body.password = nil
|
202
194
|
event_model
|
203
195
|
}
|
204
196
|
|
@@ -213,9 +205,7 @@ Optional. A Proc that takes env, headers, body and returns a boolean.
|
|
213
205
|
```ruby
|
214
206
|
|
215
207
|
moesif_options['skip'] = Proc.new { |env, headers, body|
|
216
|
-
|
217
|
-
#snip
|
218
|
-
|
208
|
+
# Add your custom code that returns true to skip logging the API call
|
219
209
|
false
|
220
210
|
}
|
221
211
|
|
@@ -232,7 +222,7 @@ Optional. Boolean. Default false. If true, it will print out debug messages. In
|
|
232
222
|
|
233
223
|
Optional. Boolean. Default true. If false, will not log request and response body to Moesif.
|
234
224
|
|
235
|
-
#### __`
|
225
|
+
#### __`capture_outgoing_requests`__
|
236
226
|
Optional. boolean, Default `false`. Set to `true` to capture all outgoing API calls from your app to third parties like Stripe, Github or to your own dependencies while using [Net::HTTP](https://ruby-doc.org/stdlib-2.6.3/libdoc/net/http/rdoc/Net/HTTP.html) package. The options below is applied to outgoing API calls. When the request is outgoing, for options functions that take request and response as input arguments, the request and response objects passed in are [Request](https://www.rubydoc.info/stdlib/net/Net/HTTPRequest) request and [Response](https://www.rubydoc.info/stdlib/net/Net/HTTPResponse) response objects.
|
237
227
|
|
238
228
|
|
@@ -245,9 +235,8 @@ identify_user_outgoing is a Proc that takes request and response as arguments an
|
|
245
235
|
|
246
236
|
moesif_options['identify_user_outgoing'] = Proc.new { |request, response|
|
247
237
|
|
248
|
-
#
|
249
|
-
|
250
|
-
'the_user_id'
|
238
|
+
# Add your custom code that returns a string for user id
|
239
|
+
'12345'
|
251
240
|
}
|
252
241
|
|
253
242
|
```
|
@@ -261,9 +250,8 @@ identify_company_outgoing is a Proc that takes request and response as arguments
|
|
261
250
|
|
262
251
|
moesif_options['identify_company_outgoing'] = Proc.new { |request, response|
|
263
252
|
|
264
|
-
#
|
265
|
-
|
266
|
-
'the_company_id'
|
253
|
+
# Add your custom code that returns a string for company id
|
254
|
+
'67890'
|
267
255
|
}
|
268
256
|
|
269
257
|
```
|
@@ -279,12 +267,11 @@ metadata to this event.
|
|
279
267
|
|
280
268
|
moesif_options['get_metadata_outgoing'] = Proc.new { |request, response|
|
281
269
|
|
282
|
-
#
|
270
|
+
# Add your custom code that returns a dictionary
|
283
271
|
value = {
|
284
|
-
'
|
285
|
-
'
|
272
|
+
'datacenter' => 'westus',
|
273
|
+
'deployment_version' => 'v1.2.3'
|
286
274
|
}
|
287
|
-
|
288
275
|
value
|
289
276
|
}
|
290
277
|
```
|
@@ -297,9 +284,8 @@ Optional. A Proc that takes request, response and returns a string.
|
|
297
284
|
|
298
285
|
moesif_options['identify_session_outgoing'] = Proc.new { |request, response|
|
299
286
|
|
300
|
-
|
301
|
-
|
302
|
-
'the_session_token'
|
287
|
+
# Add your custom code that returns a string for session/API token
|
288
|
+
'XXXXXXXXX'
|
303
289
|
}
|
304
290
|
|
305
291
|
```
|
@@ -312,8 +298,7 @@ Optional. A Proc that takes request, response and returns a boolean. If `true` w
|
|
312
298
|
|
313
299
|
moesif_options['skip_outgoing'] = Proc.new{ |request, response|
|
314
300
|
|
315
|
-
#
|
316
|
-
|
301
|
+
# Add your custom code that returns true to skip logging the API call
|
317
302
|
false
|
318
303
|
}
|
319
304
|
|
@@ -328,8 +313,8 @@ With mask_data_outgoing, you can make modifications to headers or body of the ev
|
|
328
313
|
|
329
314
|
moesif_options['mask_data_outgoing'] = Proc.new { |event_model|
|
330
315
|
|
331
|
-
#
|
332
|
-
|
316
|
+
# Add your custom code that returns a event_model after modifying any fields
|
317
|
+
event_model.response.body.password = nil
|
333
318
|
event_model
|
334
319
|
}
|
335
320
|
|
@@ -341,103 +326,169 @@ Optional. Boolean. Default true. If false, will not log request and response bod
|
|
341
326
|
|
342
327
|
## Update User
|
343
328
|
|
344
|
-
###
|
345
|
-
|
346
|
-
The metadata field can be any
|
329
|
+
### Update a Single User
|
330
|
+
Create or update a user profile in Moesif.
|
331
|
+
The metadata field can be any customer demographic or other info you want to store.
|
332
|
+
Only the `user_id` field is required.
|
333
|
+
This method is a convenient helper that calls the Moesif API lib.
|
334
|
+
For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-a-user).
|
347
335
|
|
348
336
|
```ruby
|
349
|
-
metadata =
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
337
|
+
metadata = {
|
338
|
+
:email => 'john@acmeinc.com',
|
339
|
+
:first_name => 'John',
|
340
|
+
:last_name => 'Doe',
|
341
|
+
:title => 'Software Engineer',
|
342
|
+
:salesInfo => {
|
343
|
+
:stage => 'Customer',
|
344
|
+
:lifetime_value => 24000,
|
345
|
+
:accountOwner => 'mary@contoso.com',
|
346
|
+
}
|
347
|
+
}
|
357
348
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
349
|
+
# Campaign object is optional, but useful if you want to track ROI of acquisition channels
|
350
|
+
# See https://www.moesif.com/docs/api#users for campaign schema
|
351
|
+
campaign = MoesifApi::CampaignModel.new()
|
352
|
+
campaign.utm_source = "google"
|
353
|
+
campaign.utm_medium = "cpc"
|
354
|
+
campaign.utm_campaign = "adwords"
|
355
|
+
campaign.utm_term = "api+tooling"
|
356
|
+
campaign.utm_content = "landing"
|
357
|
+
|
358
|
+
# Only user_id is required.
|
359
|
+
# metadata can be any custom object
|
360
|
+
user = MoesifApi::UserModel.new()
|
361
|
+
user.user_id = "12345"
|
362
|
+
user.company_id = "67890" # If set, associate user with a company object
|
363
|
+
user.campaign = campaign
|
364
|
+
user.metadata = metadata
|
363
365
|
|
364
366
|
update_user = MoesifRack::MoesifMiddleware.new(@app, @options).update_user(user_model)
|
365
367
|
```
|
366
368
|
|
367
|
-
###
|
368
|
-
|
369
|
-
|
369
|
+
### Update Users in Batch
|
370
|
+
Similar to update_user, but used to update a list of users in one batch.
|
371
|
+
Only the `user_id` field is required.
|
372
|
+
This method is a convenient helper that calls the Moesif API lib.
|
373
|
+
For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-users-in-batch).
|
370
374
|
|
371
375
|
```ruby
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
376
|
+
users = []
|
377
|
+
|
378
|
+
metadata = {
|
379
|
+
:email => 'john@acmeinc.com',
|
380
|
+
:first_name => 'John',
|
381
|
+
:last_name => 'Doe',
|
382
|
+
:title => 'Software Engineer',
|
383
|
+
:salesInfo => {
|
384
|
+
:stage => 'Customer',
|
385
|
+
:lifetime_value => 24000,
|
386
|
+
:accountOwner => 'mary@contoso.com',
|
387
|
+
}
|
388
|
+
}
|
389
|
+
|
390
|
+
# Campaign object is optional, but useful if you want to track ROI of acquisition channels
|
391
|
+
# See https://www.moesif.com/docs/api#users for campaign schema
|
392
|
+
campaign = MoesifApi::CampaignModel.new()
|
393
|
+
campaign.utm_source = "google"
|
394
|
+
campaign.utm_medium = "cpc"
|
395
|
+
campaign.utm_campaign = "adwords"
|
396
|
+
campaign.utm_term = "api+tooling"
|
397
|
+
campaign.utm_content = "landing"
|
398
|
+
|
399
|
+
# Only user_id is required.
|
400
|
+
# metadata can be any custom object
|
401
|
+
user = MoesifApi::UserModel.new()
|
402
|
+
user.user_id = "12345"
|
403
|
+
user.company_id = "67890" # If set, associate user with a company object
|
404
|
+
user.campaign = campaign
|
405
|
+
user.metadata = metadata
|
406
|
+
|
407
|
+
users << user
|
408
|
+
|
409
|
+
response = MoesifRack::MoesifMiddleware.new(@app, @options).update_users_batch(users)
|
392
410
|
```
|
393
411
|
|
394
412
|
## Update Company
|
395
413
|
|
396
|
-
###
|
397
|
-
|
398
|
-
The metadata field can be any
|
414
|
+
### Update a Single Company
|
415
|
+
Create or update a company profile in Moesif.
|
416
|
+
The metadata field can be any company demographic or other info you want to store.
|
417
|
+
Only the `company_id` field is required.
|
418
|
+
This method is a convenient helper that calls the Moesif API lib.
|
419
|
+
For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-a-company).
|
399
420
|
|
400
421
|
```ruby
|
401
|
-
metadata =
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
422
|
+
metadata = {
|
423
|
+
:org_name => 'Acme, Inc',
|
424
|
+
:plan_name => 'Free',
|
425
|
+
:deal_stage => 'Lead',
|
426
|
+
:mrr => 24000,
|
427
|
+
:demographics => {
|
428
|
+
:alexa_ranking => 500000,
|
429
|
+
:employee_count => 47
|
430
|
+
}
|
431
|
+
}
|
409
432
|
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
433
|
+
# Campaign object is optional, but useful if you want to track ROI of acquisition channels
|
434
|
+
# See https://www.moesif.com/docs/api#update-a-company for campaign schema
|
435
|
+
campaign = MoesifApi::CampaignModel.new()
|
436
|
+
campaign.utm_source = "google"
|
437
|
+
campaign.utm_medium = "cpc"
|
438
|
+
campaign.utm_campaign = "adwords"
|
439
|
+
campaign.utm_term = "api+tooling"
|
440
|
+
campaign.utm_content = "landing"
|
441
|
+
|
442
|
+
# Only company_id is required.
|
443
|
+
# metadata can be any custom object
|
444
|
+
company = MoesifApi::CompanyModel.new()
|
445
|
+
company.company_id = "67890"
|
446
|
+
company.company_domain = "acmeinc.com" # If domain is set, Moesif will enrich your profiles with publicly available info
|
447
|
+
company.campaign = campaign
|
448
|
+
company.metadata = metadata
|
414
449
|
|
415
450
|
update_company = MoesifRack::MoesifMiddleware.new(@app, @options).update_company(company_model)
|
416
451
|
```
|
417
452
|
|
418
|
-
###
|
419
|
-
|
420
|
-
|
453
|
+
### Update Companies in Batch
|
454
|
+
Similar to update_company, but used to update a list of companies in one batch.
|
455
|
+
Only the `company_id` field is required.
|
456
|
+
This method is a convenient helper that calls the Moesif API lib.
|
457
|
+
For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-companies-in-batch).
|
421
458
|
|
422
459
|
```ruby
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
company_model_B = { "company_id" => "67890",
|
436
|
-
"company_domain" => "acmeinc.com",
|
437
|
-
"metadata" => metadata }
|
460
|
+
companies = []
|
461
|
+
|
462
|
+
metadata = {
|
463
|
+
:org_name => 'Acme, Inc',
|
464
|
+
:plan_name => 'Free',
|
465
|
+
:deal_stage => 'Lead',
|
466
|
+
:mrr => 24000,
|
467
|
+
:demographics => {
|
468
|
+
:alexa_ranking => 500000,
|
469
|
+
:employee_count => 47
|
470
|
+
}
|
471
|
+
}
|
438
472
|
|
439
|
-
|
440
|
-
|
473
|
+
# Campaign object is optional, but useful if you want to track ROI of acquisition channels
|
474
|
+
# See https://www.moesif.com/docs/api#update-a-company for campaign schema
|
475
|
+
campaign = MoesifApi::CampaignModel.new()
|
476
|
+
campaign.utm_source = "google"
|
477
|
+
campaign.utm_medium = "cpc"
|
478
|
+
campaign.utm_campaign = "adwords"
|
479
|
+
campaign.utm_term = "api+tooling"
|
480
|
+
campaign.utm_content = "landing"
|
481
|
+
|
482
|
+
# Only company_id is required.
|
483
|
+
# metadata can be any custom object
|
484
|
+
company = MoesifApi::CompanyModel.new()
|
485
|
+
company.company_id = "67890"
|
486
|
+
company.company_domain = "acmeinc.com" # If domain is set, Moesif will enrich your profiles with publicly available info
|
487
|
+
company.campaign = campaign
|
488
|
+
company.metadata = metadata
|
489
|
+
|
490
|
+
companies << company
|
491
|
+
response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_batch(companies)
|
441
492
|
```
|
442
493
|
|
443
494
|
## How to test
|
@@ -457,7 +508,7 @@ response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_bat
|
|
457
508
|
|
458
509
|
## Other integrations
|
459
510
|
|
460
|
-
To view more
|
511
|
+
To view more documentation on integration options, please visit [the Integration Options Documentation](https://www.moesif.com/docs/getting-started/integration-options/).
|
461
512
|
|
462
513
|
[ico-built-for]: https://img.shields.io/badge/built%20for-rack-blue.svg
|
463
514
|
[ico-version]: https://img.shields.io/gem/v/moesif_rack.svg
|
@@ -6,6 +6,8 @@ require_relative './client_ip.rb'
|
|
6
6
|
require_relative './app_config.rb'
|
7
7
|
require_relative './update_user.rb'
|
8
8
|
require_relative './update_company.rb'
|
9
|
+
require 'zlib'
|
10
|
+
require 'stringio'
|
9
11
|
|
10
12
|
module MoesifRack
|
11
13
|
|
@@ -34,6 +36,45 @@ module MoesifRack
|
|
34
36
|
@config_dict = Hash.new
|
35
37
|
@disable_transaction_id = options['disable_transaction_id'] || false
|
36
38
|
@log_body = options.fetch('log_body', true)
|
39
|
+
@batch_size = options['batch_size'] || 25
|
40
|
+
@events_queue = Queue.new
|
41
|
+
@event_response_config_etag = nil
|
42
|
+
|
43
|
+
Thread::new do
|
44
|
+
loop do
|
45
|
+
begin
|
46
|
+
until @events_queue.empty? do
|
47
|
+
batch_events = []
|
48
|
+
until batch_events.size == @batch_size || @events_queue.empty? do
|
49
|
+
batch_events << @events_queue.pop
|
50
|
+
end
|
51
|
+
event_api_response = @api_controller.create_events_batch(batch_events)
|
52
|
+
@event_response_config_etag = event_api_response[:x_moesif_config_etag]
|
53
|
+
if @debug
|
54
|
+
puts("Events successfully sent to Moesif")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
if @events_queue.empty?
|
59
|
+
if @debug
|
60
|
+
puts("No events to read from the queue")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sleep for 5 seconds
|
65
|
+
sleep 5
|
66
|
+
rescue MoesifApi::APIException => e
|
67
|
+
if e.response_code.between?(401, 403)
|
68
|
+
puts "Unathorized accesss sending event to Moesif. Please verify your Application Id."
|
69
|
+
end
|
70
|
+
if @debug
|
71
|
+
puts "Error sending event to Moesif, with status code: "
|
72
|
+
puts e.response_code
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
37
78
|
begin
|
38
79
|
if !@config.nil?
|
39
80
|
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
@@ -45,7 +86,8 @@ module MoesifRack
|
|
45
86
|
end
|
46
87
|
end
|
47
88
|
@capture_outoing_requests = options['capture_outoing_requests']
|
48
|
-
|
89
|
+
@capture_outgoing_requests = options['capture_outgoing_requests']
|
90
|
+
if @capture_outoing_requests || @capture_outgoing_requests
|
49
91
|
if @debug
|
50
92
|
puts 'Start Capturing outgoing requests'
|
51
93
|
end
|
@@ -70,6 +112,39 @@ module MoesifRack
|
|
70
112
|
CompanyHelper.new.update_companies_batch(@api_controller, @debug, company_profiles)
|
71
113
|
end
|
72
114
|
|
115
|
+
def start_with_json(body)
|
116
|
+
body.start_with?('{') || body.start_with?('[')
|
117
|
+
end
|
118
|
+
|
119
|
+
def decompress_body(body)
|
120
|
+
Zlib::GzipReader.new(StringIO.new(body)).read
|
121
|
+
end
|
122
|
+
|
123
|
+
def transform_headers(headers)
|
124
|
+
Hash[headers.map { |k, v| [k.downcase, v]}]
|
125
|
+
end
|
126
|
+
|
127
|
+
def base64_encode_body(body)
|
128
|
+
return Base64.encode64(body), 'base64'
|
129
|
+
end
|
130
|
+
|
131
|
+
def parse_body(body, headers)
|
132
|
+
begin
|
133
|
+
if start_with_json(body)
|
134
|
+
parsed_body = JSON.parse(body)
|
135
|
+
transfer_encoding = 'json'
|
136
|
+
elsif headers.key?('content-encoding') && ((headers['content-encoding'].downcase).include? "gzip")
|
137
|
+
uncompressed_string = decompress_body(body)
|
138
|
+
parsed_body, transfer_encoding = base64_encode_body(uncompressed_string)
|
139
|
+
else
|
140
|
+
parsed_body, transfer_encoding = base64_encode_body(body)
|
141
|
+
end
|
142
|
+
rescue
|
143
|
+
parsed_body, transfer_encoding = base64_encode_body(body)
|
144
|
+
end
|
145
|
+
return parsed_body, transfer_encoding
|
146
|
+
end
|
147
|
+
|
73
148
|
def call env
|
74
149
|
start_time = Time.now.utc.iso8601
|
75
150
|
|
@@ -85,7 +160,7 @@ module MoesifRack
|
|
85
160
|
complex_copy = env.dup
|
86
161
|
|
87
162
|
req_headers = {}
|
88
|
-
complex_copy.select {|k,v| k.start_with?
|
163
|
+
complex_copy.select {|k,v| k.start_with?('HTTP_', 'CONTENT_') }.each do |key, val|
|
89
164
|
new_key = key.sub(/^HTTP_/, '')
|
90
165
|
new_key = new_key.sub('_', '-')
|
91
166
|
req_headers[new_key] = val
|
@@ -98,12 +173,7 @@ module MoesifRack
|
|
98
173
|
|
99
174
|
if @log_body
|
100
175
|
if req_body_string && req_body_string.length != 0
|
101
|
-
|
102
|
-
req_body = JSON.parse(req_body_string)
|
103
|
-
rescue
|
104
|
-
req_body = Base64.encode64(req_body_string)
|
105
|
-
req_body_transfer_encoding = 'base64'
|
106
|
-
end
|
176
|
+
req_body, req_body_transfer_encoding = parse_body(req_body_string, transform_headers(req_headers))
|
107
177
|
end
|
108
178
|
end
|
109
179
|
|
@@ -115,12 +185,7 @@ module MoesifRack
|
|
115
185
|
|
116
186
|
if @log_body
|
117
187
|
if rsp_body_string && rsp_body_string.length != 0
|
118
|
-
|
119
|
-
rsp_body = JSON.parse(rsp_body_string)
|
120
|
-
rescue
|
121
|
-
rsp_body = Base64.encode64(rsp_body_string)
|
122
|
-
rsp_body_transfer_encoding = 'base64'
|
123
|
-
end
|
188
|
+
rsp_body, rsp_body_transfer_encoding = parse_body(rsp_body_string, transform_headers(rsp_headers))
|
124
189
|
end
|
125
190
|
end
|
126
191
|
|
@@ -177,6 +242,7 @@ module MoesifRack
|
|
177
242
|
event_model = MoesifApi::EventModel.new()
|
178
243
|
event_model.request = event_req
|
179
244
|
event_model.response = event_rsp
|
245
|
+
event_model.direction = "Incoming"
|
180
246
|
|
181
247
|
if @identify_user
|
182
248
|
if @debug
|
@@ -231,10 +297,14 @@ module MoesifRack
|
|
231
297
|
end
|
232
298
|
|
233
299
|
if @sampling_percentage > @random_percentage
|
234
|
-
|
235
|
-
|
300
|
+
event_model.weight = @app_config.calculate_weight(@sampling_percentage)
|
301
|
+
# Add Event to the queue
|
302
|
+
@events_queue << event_model
|
303
|
+
if @debug
|
304
|
+
puts("Event added to the queue ")
|
305
|
+
end
|
236
306
|
|
237
|
-
if
|
307
|
+
if !@event_response_config_etag.nil? && !@config_etag.nil? && @config_etag != @event_response_config_etag && Time.now.utc > @last_updated_time + 300
|
238
308
|
begin
|
239
309
|
@config = @app_config.get_config(@api_controller, @debug)
|
240
310
|
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
@@ -245,21 +315,15 @@ module MoesifRack
|
|
245
315
|
end
|
246
316
|
end
|
247
317
|
end
|
248
|
-
if @debug
|
249
|
-
puts("Event successfully sent to Moesif")
|
250
|
-
end
|
251
318
|
else
|
252
319
|
if @debug
|
253
320
|
puts("Skipped Event due to sampling percentage: " + @sampling_percentage.to_s + " and random percentage: " + @random_percentage.to_s)
|
254
321
|
end
|
255
322
|
end
|
256
|
-
rescue
|
257
|
-
if e.response_code.between?(401, 403)
|
258
|
-
puts "Unathorized accesss sending event to Moesif. Please verify your Application Id."
|
259
|
-
end
|
323
|
+
rescue => exception
|
260
324
|
if @debug
|
261
|
-
puts "Error
|
262
|
-
puts
|
325
|
+
puts "Error adding event to the queue "
|
326
|
+
puts exception.to_s
|
263
327
|
end
|
264
328
|
end
|
265
329
|
|
@@ -3,6 +3,7 @@ require 'rack'
|
|
3
3
|
require 'moesif_api'
|
4
4
|
require 'json'
|
5
5
|
require 'base64'
|
6
|
+
require_relative '../../lib/moesif_rack/app_config.rb'
|
6
7
|
|
7
8
|
module MoesifCaptureOutgoing
|
8
9
|
|
@@ -23,6 +24,22 @@ module MoesifCaptureOutgoing
|
|
23
24
|
@skip_outgoing = options['skip_outgoing']
|
24
25
|
@mask_data_outgoing = options['mask_data_outgoing']
|
25
26
|
@log_body_outgoing = options.fetch('log_body_outgoing', true)
|
27
|
+
@app_config = AppConfig.new
|
28
|
+
@config = @app_config.get_config(@api_controller, @debug)
|
29
|
+
@config_etag = nil
|
30
|
+
@sampling_percentage = 100
|
31
|
+
@last_updated_time = Time.now.utc
|
32
|
+
@config_dict = Hash.new
|
33
|
+
begin
|
34
|
+
if !@config.nil?
|
35
|
+
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
36
|
+
end
|
37
|
+
rescue => exception
|
38
|
+
if @debug
|
39
|
+
puts 'Error while parsing application configuration on initialization'
|
40
|
+
puts exception.to_s
|
41
|
+
end
|
42
|
+
end
|
26
43
|
end
|
27
44
|
|
28
45
|
def call (url, request, request_time, response, response_time)
|
@@ -102,6 +119,7 @@ module MoesifCaptureOutgoing
|
|
102
119
|
event_model = MoesifApi::EventModel.new()
|
103
120
|
event_model.request = event_req
|
104
121
|
event_model.response = event_rsp
|
122
|
+
event_model.direction = "Outgoing"
|
105
123
|
|
106
124
|
# Metadata for Outgoing Request
|
107
125
|
if @get_metadata_outgoing
|
@@ -156,11 +174,45 @@ module MoesifCaptureOutgoing
|
|
156
174
|
|
157
175
|
# Send Event to Moesif
|
158
176
|
begin
|
159
|
-
|
160
|
-
|
161
|
-
|
177
|
+
@random_percentage = Random.rand(0.00..100.00)
|
178
|
+
begin
|
179
|
+
@sampling_percentage = @app_config.get_sampling_percentage(@config, event_model.user_id, event_model.company_id, @debug)
|
180
|
+
rescue => exception
|
181
|
+
if @debug
|
182
|
+
puts 'Error while getting sampling percentage, assuming default behavior'
|
183
|
+
puts exception.to_s
|
184
|
+
end
|
185
|
+
@sampling_percentage = 100
|
186
|
+
end
|
187
|
+
|
188
|
+
if @sampling_percentage > @random_percentage
|
189
|
+
event_model.weight = @app_config.calculate_weight(@sampling_percentage)
|
190
|
+
if @debug
|
191
|
+
puts 'Sending Outgoing Request Data to Moesif'
|
192
|
+
puts event_model.to_json
|
193
|
+
end
|
194
|
+
event_api_response = @api_controller.create_event(event_model)
|
195
|
+
event_response_config_etag = event_api_response[:x_moesif_config_etag]
|
196
|
+
|
197
|
+
if !event_response_config_etag.nil? && !@config_etag.nil? && @config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 300
|
198
|
+
begin
|
199
|
+
@config = @app_config.get_config(@api_controller, @debug)
|
200
|
+
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
201
|
+
rescue => exception
|
202
|
+
if @debug
|
203
|
+
puts 'Error while updating the application configuration'
|
204
|
+
puts exception.to_s
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
if @debug
|
209
|
+
puts("Event successfully sent to Moesif")
|
210
|
+
end
|
211
|
+
else
|
212
|
+
if @debug
|
213
|
+
puts("Skipped outgoing Event due to sampling percentage: " + @sampling_percentage.to_s + " and random percentage: " + @random_percentage.to_s)
|
214
|
+
end
|
162
215
|
end
|
163
|
-
@api_controller.create_event(event_model)
|
164
216
|
rescue MoesifApi::APIException => e
|
165
217
|
if e.response_code.between?(401, 403)
|
166
218
|
puts "Unathorized accesss sending event to Moesif. Please verify your Application Id."
|
data/test/moesif_rack_test.rb
CHANGED
@@ -10,7 +10,7 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
10
10
|
@options = { 'application_id' => 'Your Moesif Application Id',
|
11
11
|
'debug' => true,
|
12
12
|
'disable_transaction_id' => true,
|
13
|
-
'
|
13
|
+
'capture_outgoing_requests' => true,
|
14
14
|
'get_metadata' => Proc.new {|request, response|
|
15
15
|
{
|
16
16
|
'foo' => 'abc',
|
@@ -108,6 +108,8 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
108
108
|
|
109
109
|
def test_log_event
|
110
110
|
response = @moesif_rack_app.call(Rack::MockRequest.env_for("https://acmeinc.com/items/42752/reviews"))
|
111
|
+
# Sleep to allow queue to flush for testing purpose
|
112
|
+
sleep 5
|
111
113
|
assert_equal response, @app.call(nil)
|
112
114
|
end
|
113
115
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moesif_rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Moesif, Inc
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2020-05-28 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
@@ -31,14 +31,14 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: 1.2.
|
34
|
+
version: 1.2.12
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: 1.2.
|
41
|
+
version: 1.2.12
|
42
42
|
description: Collection/Data Ingestion SDK for Rack (also Rails) Middleware / RoR
|
43
43
|
email: xing@moesif.com
|
44
44
|
executables: []
|
@@ -76,7 +76,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
78
|
requirements: []
|
79
|
-
rubygems_version: 3.0.
|
79
|
+
rubygems_version: 3.0.4
|
80
80
|
signing_key:
|
81
81
|
specification_version: 4
|
82
82
|
summary: moesif_rack
|