moesif_rack 1.3.2 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +66 -27
- data/lib/moesif_rack/app_config.rb +121 -0
- data/lib/moesif_rack/moesif_middleware.rb +59 -51
- data/moesif_capture_outgoing/httplog/http_log.rb +23 -15
- data/test/moesif_rack_test.rb +21 -9
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5ea251711b21a0465e4809ec1af04084680fa3bdc19086007364480ade75978
|
4
|
+
data.tar.gz: ed0c2f983227785746f0064bc29d124576609b16b17984f817139ffa283332dc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 66d166cc2b06b3ec6194dceaf257cc447a9db391f693ac812e5434786683e94a5414edcf149f332f02e43de7000d9d021d2451bdb291018e06c9d1f2bc4b043f
|
7
|
+
data.tar.gz: ee4a947e33e26510af23386d7046a174eac99c8e88fe3b2faca67091062b2d53d93ac9d1f5bc53187bb61352f2dea5f6d7056660ffe17c43dac9c5e4480f21d1
|
data/README.md
CHANGED
@@ -6,7 +6,9 @@
|
|
6
6
|
[![Software License][ico-license]][link-license]
|
7
7
|
[![Source Code][ico-source]][link-source]
|
8
8
|
|
9
|
-
Rack Middleware that logs
|
9
|
+
Rack Middleware that logs API calls and sends
|
10
|
+
to [Moesif](https://www.moesif.com) for API analytics and log analysis.
|
11
|
+
|
10
12
|
Supports Ruby on Rails apps and other Ruby frameworks built on Rack.
|
11
13
|
|
12
14
|
[Source Code on GitHub](https://github.com/moesif/moesif-rack)
|
@@ -20,7 +22,7 @@ gem install moesif_rack
|
|
20
22
|
and if you have a `Gemfile` in your project, please add this line to
|
21
23
|
|
22
24
|
```
|
23
|
-
gem 'moesif_rack', '~> 1.3.
|
25
|
+
gem 'moesif_rack', '~> 1.3.4'
|
24
26
|
|
25
27
|
```
|
26
28
|
|
@@ -30,19 +32,40 @@ gem 'moesif_rack', '~> 1.3.1'
|
|
30
32
|
|
31
33
|
```ruby
|
32
34
|
moesif_options = {
|
33
|
-
'application_id' => 'Your
|
35
|
+
'application_id' => 'Your Moesif Application Id',
|
36
|
+
'log_body' => true,
|
34
37
|
}
|
35
38
|
```
|
36
39
|
|
37
|
-
|
40
|
+
Your Moesif Application Id can be found in the [_Moesif Portal_](https://www.moesif.com/).
|
41
|
+
After signing up for a Moesif account, your Moesif Application Id will be displayed during the onboarding steps.
|
42
|
+
|
43
|
+
You can always find your Moesif Application Id at any time by logging
|
44
|
+
into the [_Moesif Portal_](https://www.moesif.com/), click on the top right menu,
|
45
|
+
and then clicking _Installation_.
|
38
46
|
|
39
47
|
### Add to middleware
|
40
48
|
|
41
|
-
|
49
|
+
Using strings or symbols for middleware class names is deprecated for newer frameworks like Ruby 5.0,
|
50
|
+
so you should pass the class directly.
|
51
|
+
|
52
|
+
#### For Rails 5.0 or newer:
|
42
53
|
|
43
54
|
```ruby
|
55
|
+
class Application < Rails::Application
|
56
|
+
# snip
|
44
57
|
|
58
|
+
config.middleware.use MoesifRack::MoesifMiddleware, moesif_options
|
45
59
|
|
60
|
+
# snip
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
#### For other frameworks:
|
65
|
+
|
66
|
+
within `config/application.rb`
|
67
|
+
|
68
|
+
```ruby
|
46
69
|
class Application < Rails::Application
|
47
70
|
# snip
|
48
71
|
|
@@ -50,35 +73,37 @@ within `config/application.rb`
|
|
50
73
|
|
51
74
|
# snip
|
52
75
|
end
|
53
|
-
|
54
76
|
```
|
55
77
|
|
56
78
|
#### Order of Middleware Matters
|
57
79
|
|
58
|
-
Since Moesif Rack is
|
59
|
-
Many
|
80
|
+
Since Moesif Rack is a logging middleware, the ordering of middleware matters for accuracy and data collection.
|
81
|
+
Many middleware are installed by default by Rails.
|
60
82
|
|
61
|
-
|
62
|
-
|
63
|
-
```bash
|
64
|
-
bin/rails middleware
|
65
|
-
```
|
66
|
-
|
67
|
-
The best place for "MoesifRack::MoesifMidleware" is on top as possible (so it captures the data closest to the wire).
|
83
|
+
The best place for "MoesifRack::MoesifMidleware" is on top (so it captures the data closest to the wire).
|
68
84
|
Typically, right above the default logger of Rails apps, "Rails::Rack::Logger" is a good spot.
|
69
85
|
Or if you want to be as close as wire as possible, put it before "ActionDispatch::Static"
|
70
86
|
|
71
|
-
|
87
|
+
To insert the Moesif middleware before "Rails::Rack::Logger", you can use the `insert_before` method instead of
|
88
|
+
`use`
|
72
89
|
|
73
90
|
```ruby
|
91
|
+
class Application < Rails::Application
|
92
|
+
# snip
|
74
93
|
|
75
|
-
config.middleware.insert_before
|
94
|
+
config.middleware.insert_before Rails::Rack::Logger, MoesifRack::MoesifMiddleware, moesif_options
|
76
95
|
|
96
|
+
# snip
|
97
|
+
end
|
77
98
|
```
|
99
|
+
If you are using "Rack::Deflater" or other compression middleware, make sure Moesif is after
|
100
|
+
it, so it can capture the uncompressed data.
|
78
101
|
|
79
|
-
|
80
|
-
is below it, so it can capture uncompressed data.
|
102
|
+
To see your current list of middleware:
|
81
103
|
|
104
|
+
```bash
|
105
|
+
bin/rails middleware
|
106
|
+
```
|
82
107
|
|
83
108
|
## Configuration options
|
84
109
|
|
@@ -106,7 +131,7 @@ moesif_options['identify_user'] = Proc.new { |env, headers, body|
|
|
106
131
|
|
107
132
|
#snip
|
108
133
|
|
109
|
-
'
|
134
|
+
'my_user_id'
|
110
135
|
}
|
111
136
|
|
112
137
|
```
|
@@ -122,7 +147,7 @@ moesif_options['identify_company'] = Proc.new { |env, headers, body|
|
|
122
147
|
|
123
148
|
#snip
|
124
149
|
|
125
|
-
'
|
150
|
+
'my_company_id'
|
126
151
|
}
|
127
152
|
|
128
153
|
```
|
@@ -203,6 +228,10 @@ For details for the spec of event model, please see the [Moesif Ruby API Documen
|
|
203
228
|
|
204
229
|
Optional. Boolean. Default false. If true, it will print out debug messages. In debug mode, the processing is not done in backend thread.
|
205
230
|
|
231
|
+
#### __`log_body`__
|
232
|
+
|
233
|
+
Optional. Boolean. Default true. If false, will not log request and response body to Moesif.
|
234
|
+
|
206
235
|
#### __`capture_outoing_requests`__
|
207
236
|
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.
|
208
237
|
|
@@ -306,6 +335,10 @@ moesif_options['mask_data_outgoing'] = Proc.new { |event_model|
|
|
306
335
|
|
307
336
|
```
|
308
337
|
|
338
|
+
#### __`log_body_outgoing`__
|
339
|
+
|
340
|
+
Optional. Boolean. Default true. If false, will not log request and response body to Moesif.
|
341
|
+
|
309
342
|
## Update User
|
310
343
|
|
311
344
|
### update_user method
|
@@ -319,7 +352,8 @@ metadata = JSON.parse('{'\
|
|
319
352
|
'"custom": "testdata"'\
|
320
353
|
'}')
|
321
354
|
|
322
|
-
user_model = { "user_id" => "
|
355
|
+
user_model = { "user_id" => "12345",
|
356
|
+
"company_id" => "67890",
|
323
357
|
"modified_time" => Time.now.utc.iso8601,
|
324
358
|
"metadata" => metadata }
|
325
359
|
|
@@ -339,11 +373,13 @@ metadata = JSON.parse('{'\
|
|
339
373
|
|
340
374
|
user_models = []
|
341
375
|
|
342
|
-
user_model_A = { "user_id" => "
|
376
|
+
user_model_A = { "user_id" => "12345",
|
377
|
+
"company_id" => "67890",
|
343
378
|
"modified_time" => Time.now.utc.iso8601,
|
344
379
|
"metadata" => metadata }
|
345
380
|
|
346
|
-
user_model_B = { "user_id" => "
|
381
|
+
user_model_B = { "user_id" => "1234",
|
382
|
+
"company_id" => "6789",
|
347
383
|
"modified_time" => Time.now.utc.iso8601,
|
348
384
|
"metadata" => metadata }
|
349
385
|
|
@@ -364,7 +400,8 @@ metadata = JSON.parse('{'\
|
|
364
400
|
'"custom": "testdata"'\
|
365
401
|
'}')
|
366
402
|
|
367
|
-
company_model = { "company_id" => "
|
403
|
+
company_model = { "company_id" => "12345",
|
404
|
+
"company_domain" => "acmeinc.com",
|
368
405
|
"metadata" => metadata }
|
369
406
|
|
370
407
|
update_company = MoesifRack::MoesifMiddleware.new(@app, @options).update_company(company_model)
|
@@ -383,10 +420,12 @@ metadata = JSON.parse('{'\
|
|
383
420
|
|
384
421
|
company_models = []
|
385
422
|
|
386
|
-
company_model_A = { "company_id" => "
|
423
|
+
company_model_A = { "company_id" => "12345",
|
424
|
+
"company_domain" => "nowhere.com",
|
387
425
|
"metadata" => metadata }
|
388
426
|
|
389
|
-
company_model_B = { "company_id" => "
|
427
|
+
company_model_B = { "company_id" => "67890",
|
428
|
+
"company_domain" => "acmeinc.com",
|
390
429
|
"metadata" => metadata }
|
391
430
|
|
392
431
|
company_models << company_model_A << company_model_B
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'moesif_api'
|
2
|
+
require 'json'
|
3
|
+
require 'time'
|
4
|
+
require 'zlib'
|
5
|
+
require 'stringio'
|
6
|
+
|
7
|
+
class AppConfig
|
8
|
+
|
9
|
+
def get_config(api_controller, debug)
|
10
|
+
# Get Application Config
|
11
|
+
begin
|
12
|
+
config_api_response = api_controller.get_app_config()
|
13
|
+
return config_api_response
|
14
|
+
rescue MoesifApi::APIException => e
|
15
|
+
if e.response_code.between?(401, 403)
|
16
|
+
puts 'Unauthorized access getting application configuration. Please check your Appplication Id.'
|
17
|
+
end
|
18
|
+
if debug
|
19
|
+
puts 'Error getting application configuration, with status code:'
|
20
|
+
puts e.response_code
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_configuration(config_api_response, debug)
|
26
|
+
# Parse configuration object and return Etag, sample rate and last updated time
|
27
|
+
begin
|
28
|
+
# Rails return gzipped compressed response body, so decompressing it and getting JSON response body
|
29
|
+
response_body = decompress_gzip_body(config_api_response, debug)
|
30
|
+
|
31
|
+
# Check if response body is not nil
|
32
|
+
if !response_body.nil? then
|
33
|
+
# Return Etag, sample rate and last updated time
|
34
|
+
return config_api_response.headers[:x_moesif_config_etag], response_body.fetch("sample_rate", 100), Time.now.utc
|
35
|
+
else
|
36
|
+
if debug
|
37
|
+
puts 'Response body is nil, assuming default behavior'
|
38
|
+
end
|
39
|
+
# Response body is nil, so assuming default behavior
|
40
|
+
return nil, 100, Time.now.utc
|
41
|
+
end
|
42
|
+
rescue => exception
|
43
|
+
if debug
|
44
|
+
puts 'Error while parsing the configuration object, assuming default behavior'
|
45
|
+
puts exception.to_s
|
46
|
+
end
|
47
|
+
# Assuming default behavior
|
48
|
+
return nil, 100, Time.now.utc
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def get_sampling_percentage(config_api_response, user_id, company_id, debug)
|
53
|
+
# Get sampling percentage
|
54
|
+
begin
|
55
|
+
# Rails return gzipped compressed response body, so decompressing it and getting JSON response body
|
56
|
+
response_body = decompress_gzip_body(config_api_response, debug)
|
57
|
+
|
58
|
+
# Check if response body is not nil
|
59
|
+
if !response_body.nil? then
|
60
|
+
|
61
|
+
# Get user sample rate object
|
62
|
+
user_sample_rate = response_body.fetch('user_sample_rate', nil)
|
63
|
+
|
64
|
+
# Get company sample rate object
|
65
|
+
company_sample_rate = response_body.fetch('company_sample_rate', nil)
|
66
|
+
|
67
|
+
# Get sample rate for the user if exist
|
68
|
+
if !user_id.nil? && !user_sample_rate.nil? && user_sample_rate.key?(user_id)
|
69
|
+
return user_sample_rate.fetch(user_id)
|
70
|
+
end
|
71
|
+
|
72
|
+
# Get sample rate for the company if exist
|
73
|
+
if !company_id.nil? && !company_sample_rate.nil? && company_sample_rate.key?(company_id)
|
74
|
+
return company_sample_rate.fetch(company_id)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Return sample rate
|
78
|
+
return response_body.fetch('sample_rate', 100)
|
79
|
+
else
|
80
|
+
if debug
|
81
|
+
puts 'Assuming default behavior as response body is nil - '
|
82
|
+
end
|
83
|
+
return 100
|
84
|
+
end
|
85
|
+
rescue => exception
|
86
|
+
if debug
|
87
|
+
puts 'Error while geting sampling percentage, assuming default behavior'
|
88
|
+
end
|
89
|
+
return 100
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def decompress_gzip_body(config_api_response, debug)
|
94
|
+
# Decompress gzip response body
|
95
|
+
begin
|
96
|
+
# Check if the content-encoding header exist and is of type zip
|
97
|
+
if config_api_response.headers.key?(:content_encoding) && config_api_response.headers[:content_encoding].eql?( 'gzip' ) then
|
98
|
+
|
99
|
+
# Create a GZipReader object to read data
|
100
|
+
gzip_reader = Zlib::GzipReader.new(StringIO.new(config_api_response.raw_body.to_s))
|
101
|
+
|
102
|
+
# Read the body
|
103
|
+
uncompressed_string = gzip_reader.read
|
104
|
+
|
105
|
+
# Return the parsed body
|
106
|
+
return JSON.parse( uncompressed_string )
|
107
|
+
else
|
108
|
+
if debug
|
109
|
+
puts 'Content Encoding is of type other than gzip, returning nil'
|
110
|
+
end
|
111
|
+
return nil
|
112
|
+
end
|
113
|
+
rescue => exception
|
114
|
+
if debug
|
115
|
+
puts 'Error while decompressing the response body'
|
116
|
+
puts exception.to_s
|
117
|
+
end
|
118
|
+
return nil
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -3,6 +3,7 @@ require 'json'
|
|
3
3
|
require 'time'
|
4
4
|
require 'base64'
|
5
5
|
require_relative './client_ip.rb'
|
6
|
+
require_relative './app_config.rb'
|
6
7
|
require_relative './update_user.rb'
|
7
8
|
require_relative './update_company.rb'
|
8
9
|
|
@@ -12,7 +13,7 @@ module MoesifRack
|
|
12
13
|
def initialize app, options = {}
|
13
14
|
@app = app
|
14
15
|
if not options['application_id']
|
15
|
-
raise 'application_id
|
16
|
+
raise 'application_id required for Moesif Middleware'
|
16
17
|
end
|
17
18
|
@api_client = MoesifApi::MoesifAPIClient.new(options['application_id'])
|
18
19
|
@api_controller = @api_client.api
|
@@ -25,11 +26,23 @@ module MoesifRack
|
|
25
26
|
@mask_data = options['mask_data']
|
26
27
|
@skip = options['skip']
|
27
28
|
@debug = options['debug']
|
29
|
+
@app_config = AppConfig.new
|
30
|
+
@config = @app_config.get_config(@api_controller, @debug)
|
31
|
+
@config_etag = nil
|
32
|
+
@sampling_percentage = 100
|
33
|
+
@last_updated_time = Time.now.utc
|
28
34
|
@config_dict = Hash.new
|
29
35
|
@disable_transaction_id = options['disable_transaction_id'] || false
|
30
|
-
@
|
31
|
-
|
32
|
-
|
36
|
+
@log_body = options.fetch('log_body', true)
|
37
|
+
begin
|
38
|
+
if !@config.nil?
|
39
|
+
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
40
|
+
end
|
41
|
+
rescue => exception
|
42
|
+
if @debug
|
43
|
+
puts 'Error while parsing application configuration on initialization'
|
44
|
+
puts exception.to_s
|
45
|
+
end
|
33
46
|
end
|
34
47
|
@capture_outoing_requests = options['capture_outoing_requests']
|
35
48
|
if @capture_outoing_requests
|
@@ -41,35 +54,6 @@ module MoesifRack
|
|
41
54
|
end
|
42
55
|
end
|
43
56
|
|
44
|
-
def get_config(cached_config_etag)
|
45
|
-
sample_rate = 100
|
46
|
-
begin
|
47
|
-
# Calling the api
|
48
|
-
config_api_response = @api_controller.get_app_config()
|
49
|
-
# Fetch the response ETag
|
50
|
-
response_config_etag = JSON.parse( config_api_response.to_json )["headers"]["x_moesif_config_etag"]
|
51
|
-
# Remove ETag from the global dict if exist
|
52
|
-
if !cached_config_etag.nil? && @config_dict.key?(cached_config_etag)
|
53
|
-
@config_dict.delete(cached_config_etag)
|
54
|
-
end
|
55
|
-
# Fetch the response body
|
56
|
-
@config_dict[response_config_etag] = JSON.parse(JSON.parse( config_api_response.to_json )["raw_body"])
|
57
|
-
#
|
58
|
-
app_config = @config_dict[response_config_etag]
|
59
|
-
# Fetch the sample rate
|
60
|
-
if !app_config.nil?
|
61
|
-
sample_rate = app_config.fetch("sample_rate", 100)
|
62
|
-
end
|
63
|
-
# Set the last updated time
|
64
|
-
@last_updated_time = Time.now.utc
|
65
|
-
rescue
|
66
|
-
# Set the last updated time
|
67
|
-
@last_updated_time = Time.now.utc
|
68
|
-
end
|
69
|
-
# Return the sample rate
|
70
|
-
return sample_rate
|
71
|
-
end
|
72
|
-
|
73
57
|
def update_user(user_profile)
|
74
58
|
UserHelper.new.update_user(@api_controller, @debug, user_profile)
|
75
59
|
end
|
@@ -110,13 +94,16 @@ module MoesifRack
|
|
110
94
|
req_body_string = req.body.read
|
111
95
|
req.body.rewind
|
112
96
|
req_body_transfer_encoding = nil
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
97
|
+
req_body = nil
|
98
|
+
|
99
|
+
if @log_body
|
100
|
+
if req_body_string && req_body_string.length != 0
|
101
|
+
begin
|
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
|
120
107
|
end
|
121
108
|
end
|
122
109
|
|
@@ -124,13 +111,16 @@ module MoesifRack
|
|
124
111
|
|
125
112
|
rsp_body_string = get_response_body(body);
|
126
113
|
rsp_body_transfer_encoding = nil
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
114
|
+
rsp_body = nil
|
115
|
+
|
116
|
+
if @log_body
|
117
|
+
if rsp_body_string && rsp_body_string.length != 0
|
118
|
+
begin
|
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
|
134
124
|
end
|
135
125
|
end
|
136
126
|
|
@@ -229,13 +219,31 @@ module MoesifRack
|
|
229
219
|
# Perform the API call through the SDK function
|
230
220
|
begin
|
231
221
|
@random_percentage = Random.rand(0.00..100.00)
|
222
|
+
|
223
|
+
begin
|
224
|
+
@sampling_percentage = @app_config.get_sampling_percentage(@config, event_model.user_id, event_model.company_id, @debug)
|
225
|
+
rescue => exception
|
226
|
+
if @debug
|
227
|
+
puts 'Error while getting sampling percentage, assuming default behavior'
|
228
|
+
puts exception.to_s
|
229
|
+
end
|
230
|
+
@sampling_percentage = 100
|
231
|
+
end
|
232
|
+
|
232
233
|
if @sampling_percentage > @random_percentage
|
233
234
|
event_api_response = @api_controller.create_event(event_model)
|
234
|
-
cached_config_etag = @config_dict.keys[0]
|
235
235
|
event_response_config_etag = event_api_response[:x_moesif_config_etag]
|
236
236
|
|
237
|
-
if !event_response_config_etag.nil? &&
|
238
|
-
|
237
|
+
if !event_response_config_etag.nil? && !@config_etag.nil? && @config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 300
|
238
|
+
begin
|
239
|
+
@config = @app_config.get_config(@api_controller, @debug)
|
240
|
+
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
241
|
+
rescue => exception
|
242
|
+
if @debug
|
243
|
+
puts 'Error while updating the application configuration'
|
244
|
+
puts exception.to_s
|
245
|
+
end
|
246
|
+
end
|
239
247
|
end
|
240
248
|
if @debug
|
241
249
|
puts("Event successfully sent to Moesif")
|
@@ -278,7 +286,7 @@ module MoesifRack
|
|
278
286
|
|
279
287
|
def get_response_body(response)
|
280
288
|
body = response.respond_to?(:body) ? response.body : response
|
281
|
-
body = body.inject("") { |i, a| i << a } if body.respond_to?(:each)
|
289
|
+
body = body.inject("") { |i, a| i << a } if (body.respond_to?(:each) && body.respond_to?(:inject))
|
282
290
|
body.to_s
|
283
291
|
end
|
284
292
|
|
@@ -22,6 +22,7 @@ module MoesifCaptureOutgoing
|
|
22
22
|
@identify_session_outgoing = @moesif_options['identify_session_outgoing']
|
23
23
|
@skip_outgoing = options['skip_outgoing']
|
24
24
|
@mask_data_outgoing = options['mask_data_outgoing']
|
25
|
+
@log_body_outgoing = options.fetch('log_body_outgoing', true)
|
25
26
|
end
|
26
27
|
|
27
28
|
def call (url, request, request_time, response, response_time)
|
@@ -50,25 +51,32 @@ module MoesifCaptureOutgoing
|
|
50
51
|
# Request Body
|
51
52
|
req_body_string = request.body.nil? || request.body.empty? ? nil : request.body
|
52
53
|
req_body_transfer_encoding = nil
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
req_body = nil
|
55
|
+
|
56
|
+
if @log_body_outgoing
|
57
|
+
if req_body_string && req_body_string.length != 0
|
58
|
+
begin
|
59
|
+
req_body = JSON.parse(req_body_string)
|
60
|
+
rescue
|
61
|
+
req_body = Base64.encode64(req_body_string)
|
62
|
+
req_body_transfer_encoding = 'base64'
|
63
|
+
end
|
59
64
|
end
|
60
65
|
end
|
61
66
|
|
62
67
|
# Response Body and encoding
|
63
68
|
rsp_body_string = get_response_body(response.body)
|
64
69
|
rsp_body_transfer_encoding = nil
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
rsp_body = nil
|
71
|
+
|
72
|
+
if @log_body_outgoing
|
73
|
+
if rsp_body_string && rsp_body_string.length != 0
|
74
|
+
begin
|
75
|
+
rsp_body = JSON.parse(rsp_body_string)
|
76
|
+
rescue
|
77
|
+
rsp_body = Base64.encode64(rsp_body_string)
|
78
|
+
rsp_body_transfer_encoding = 'base64'
|
79
|
+
end
|
72
80
|
end
|
73
81
|
end
|
74
82
|
|
@@ -79,7 +87,7 @@ module MoesifCaptureOutgoing
|
|
79
87
|
event_req.verb = request.method.to_s.upcase
|
80
88
|
event_req.headers = request.each_header.collect.to_h
|
81
89
|
event_req.api_version = nil
|
82
|
-
event_req.body =
|
90
|
+
event_req.body = req_body
|
83
91
|
event_req.transfer_encoding = req_body_transfer_encoding
|
84
92
|
|
85
93
|
# Event Response
|
@@ -87,7 +95,7 @@ module MoesifCaptureOutgoing
|
|
87
95
|
event_rsp.time = response_time
|
88
96
|
event_rsp.status = response.code.to_i
|
89
97
|
event_rsp.headers = response.each_header.collect.to_h
|
90
|
-
event_rsp.body =
|
98
|
+
event_rsp.body = rsp_body
|
91
99
|
event_rsp.transfer_encoding = rsp_body_transfer_encoding
|
92
100
|
|
93
101
|
# Prepare Event Model
|
data/test/moesif_rack_test.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'test/unit'
|
2
2
|
require 'rack'
|
3
3
|
require 'net/http'
|
4
|
+
require_relative '../lib/moesif_rack/app_config.rb'
|
4
5
|
require_relative '../lib/moesif_rack'
|
5
6
|
|
6
7
|
class MoesifRackTest < Test::Unit::TestCase
|
7
8
|
def setup
|
8
9
|
@app = ->(env) { [200, { "Content-Type" => "application/json" }, ["{ \"key\": \"value\"}"]]}
|
9
|
-
@options = { 'application_id' => 'Your Application Id',
|
10
|
+
@options = { 'application_id' => 'Your Moesif Application Id',
|
10
11
|
'debug' => true,
|
11
12
|
'disable_transaction_id' => true,
|
12
13
|
'capture_outoing_requests' => true,
|
@@ -26,7 +27,7 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
26
27
|
'my_user_id'
|
27
28
|
},
|
28
29
|
'identify_company' => Proc.new{|request, response|
|
29
|
-
'
|
30
|
+
'my_company_id'
|
30
31
|
},
|
31
32
|
'identify_user_outgoing' => Proc.new{|request, response|
|
32
33
|
'outgoing_user_id'
|
@@ -45,6 +46,7 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
45
46
|
}
|
46
47
|
}
|
47
48
|
@moesif_rack_app = MoesifRack::MoesifMiddleware.new(@app, @options)
|
49
|
+
@app_config = AppConfig.new
|
48
50
|
end
|
49
51
|
|
50
52
|
def test_capture_outgoing
|
@@ -67,7 +69,8 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
67
69
|
'"custom": "testdata"'\
|
68
70
|
'}')
|
69
71
|
|
70
|
-
user_model = { "user_id" => "
|
72
|
+
user_model = { "user_id" => "12345",
|
73
|
+
"company_id" => "67890",
|
71
74
|
"modified_time" => Time.now.utc.iso8601,
|
72
75
|
"metadata" => metadata }
|
73
76
|
|
@@ -84,11 +87,13 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
84
87
|
|
85
88
|
user_models = []
|
86
89
|
|
87
|
-
user_model_A = { "user_id" => "
|
90
|
+
user_model_A = { "user_id" => "12345",
|
91
|
+
"company_id" => "67890",
|
88
92
|
"modified_time" => Time.now.utc.iso8601,
|
89
93
|
"metadata" => metadata }
|
90
94
|
|
91
|
-
user_model_B = { "user_id" => "
|
95
|
+
user_model_B = { "user_id" => "1234",
|
96
|
+
"company_id" => "6789",
|
92
97
|
"modified_time" => Time.now.utc.iso8601,
|
93
98
|
"metadata" => metadata }
|
94
99
|
|
@@ -103,7 +108,11 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
103
108
|
end
|
104
109
|
|
105
110
|
def test_get_config
|
106
|
-
|
111
|
+
@api_client = MoesifApi::MoesifAPIClient.new(@options['application_id'])
|
112
|
+
@api_controller = @api_client.api
|
113
|
+
@config = @app_config.get_config(@api_controller, @debug)
|
114
|
+
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
115
|
+
assert_operator 100, :>=, @sampling_percentage
|
107
116
|
end
|
108
117
|
|
109
118
|
def test_update_company
|
@@ -113,7 +122,8 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
113
122
|
'"custom": "testdata"'\
|
114
123
|
'}')
|
115
124
|
|
116
|
-
company_model = { "company_id" => "
|
125
|
+
company_model = { "company_id" => "12345",
|
126
|
+
"company_domain" => "acmeinc.com",
|
117
127
|
"metadata" => metadata }
|
118
128
|
|
119
129
|
response = @moesif_rack_app.update_company(company_model)
|
@@ -129,10 +139,12 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
129
139
|
|
130
140
|
company_models = []
|
131
141
|
|
132
|
-
company_model_A = { "company_id" => "
|
142
|
+
company_model_A = { "company_id" => "12345",
|
143
|
+
"company_domain" => "nowhere.com",
|
133
144
|
"metadata" => metadata }
|
134
145
|
|
135
|
-
company_model_B = { "company_id" => "
|
146
|
+
company_model_B = { "company_id" => "1234",
|
147
|
+
"company_domain" => "acmeinc.com",
|
136
148
|
"metadata" => metadata }
|
137
149
|
|
138
150
|
company_models << company_model_A << company_model_B
|
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.3.
|
4
|
+
version: 1.3.7
|
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: 2019-
|
12
|
+
date: 2019-10-17 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.8
|
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.8
|
42
42
|
description: Collection/Data Ingestion SDK for Rack (also Rails) Middleware / RoR
|
43
43
|
email: xing@moesif.com
|
44
44
|
executables: []
|
@@ -48,6 +48,7 @@ files:
|
|
48
48
|
- LICENSE
|
49
49
|
- README.md
|
50
50
|
- lib/moesif_rack.rb
|
51
|
+
- lib/moesif_rack/app_config.rb
|
51
52
|
- lib/moesif_rack/client_ip.rb
|
52
53
|
- lib/moesif_rack/moesif_middleware.rb
|
53
54
|
- lib/moesif_rack/update_company.rb
|
@@ -75,7 +76,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
76
|
- !ruby/object:Gem::Version
|
76
77
|
version: '0'
|
77
78
|
requirements: []
|
78
|
-
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.7.7
|
79
81
|
signing_key:
|
80
82
|
specification_version: 4
|
81
83
|
summary: moesif_rack
|