moesif_rack 1.3.4 → 1.3.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 78140d9557e785d6def875ef2ff36d1966fc322f0b50f54840e9489bafa1f03d
4
- data.tar.gz: f3b9000be0288be9f9bc786a1072cdaf09a15bbbc7e99720f39479098a468ff3
3
+ metadata.gz: 8f5cd1d13df1da4833bc55a10462721bdabae0a09cb6d8ab6398c378bd546975
4
+ data.tar.gz: ab2e62d3c6c4f76532bf8dbad38b4fdb2747413897e72228dc1ac23265d134c9
5
5
  SHA512:
6
- metadata.gz: 87afa9da20ecade3ea36a3dd9791f2d7d68245db9838f287eacd5905c2230ed0736237bd320a934186c84760fa658575d05eac9538d5b37903e99207e59defcc
7
- data.tar.gz: 17752a036f01c4b26949a71a6856d29d5e89beb3e818859c22df8a20a01eeaae291d19a7b52805cd93d55a4bf246ce832c98cdaef4e4e317a97ae1b7abf858d5
6
+ metadata.gz: f42082b67c965208ba8d13bb2552a2b44ee08c3930ed58825838804431bfda1655acbcd82099ea0d0baec4573e31c0db4dc91dc95a7c2e7b5f23fb401e5f7076
7
+ data.tar.gz: ac4f6d15abbb9cce97e8206a158666883a002575d9921b4c64c54a3f38f384034e189c5dbb26ae44ac6636b66fb8a842fee1ad02b09e3c59b9fd9408815f813e
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.3.4'
25
+ gem 'moesif_rack', '~> 1.3.9'
26
26
 
27
27
  ```
28
28
 
@@ -46,11 +46,26 @@ and then clicking _Installation_.
46
46
 
47
47
  ### Add to middleware
48
48
 
49
- within `config/application.rb`
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:
50
53
 
51
54
  ```ruby
55
+ class Application < Rails::Application
56
+ # snip
52
57
 
58
+ config.middleware.use MoesifRack::MoesifMiddleware, moesif_options
59
+
60
+ # snip
61
+ end
62
+ ```
53
63
 
64
+ #### For other frameworks:
65
+
66
+ within `config/application.rb`
67
+
68
+ ```ruby
54
69
  class Application < Rails::Application
55
70
  # snip
56
71
 
@@ -58,35 +73,37 @@ within `config/application.rb`
58
73
 
59
74
  # snip
60
75
  end
61
-
62
76
  ```
63
77
 
64
78
  #### Order of Middleware Matters
65
79
 
66
- Since Moesif Rack is basically a logging middleware, the ordering of middleware matters for accuracy and completeness.
67
- Many middlewares are installed by default by Rails.
68
-
69
- To see the list of middlewares that your system already have, type this into the bash.
70
-
71
- ```bash
72
- bin/rails middleware
73
- ```
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.
74
82
 
75
- 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).
76
84
  Typically, right above the default logger of Rails apps, "Rails::Rack::Logger" is a good spot.
77
85
  Or if you want to be as close as wire as possible, put it before "ActionDispatch::Static"
78
86
 
79
- You should use the following line of code to insert the middleware into the right spot.
87
+ To insert the Moesif middleware before "Rails::Rack::Logger", you can use the `insert_before` method instead of
88
+ `use`
80
89
 
81
90
  ```ruby
91
+ class Application < Rails::Application
92
+ # snip
82
93
 
83
- config.middleware.insert_before "Rails::Rack::Logger", "MoesifRack::MoesifMiddleware", moesif_options
94
+ config.middleware.insert_before Rails::Rack::Logger, MoesifRack::MoesifMiddleware, moesif_options
84
95
 
96
+ # snip
97
+ end
85
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.
86
101
 
87
- Please note, if you are using "Rack::Deflater" please make sure that "MoesifRack::MoesifMiddlware"
88
- is below it, so it can capture uncompressed data.
102
+ To see your current list of middleware:
89
103
 
104
+ ```bash
105
+ bin/rails middleware
106
+ ```
90
107
 
91
108
  ## Configuration options
92
109
 
@@ -335,10 +352,14 @@ metadata = JSON.parse('{'\
335
352
  '"custom": "testdata"'\
336
353
  '}')
337
354
 
355
+ campaign_model = {"utm_source" => "Newsletter",
356
+ "utm_medium" => "Email"}
357
+
338
358
  user_model = { "user_id" => "12345",
339
359
  "company_id" => "67890",
340
360
  "modified_time" => Time.now.utc.iso8601,
341
- "metadata" => metadata }
361
+ "metadata" => metadata,
362
+ "campaign" => campaign_model }
342
363
 
343
364
  update_user = MoesifRack::MoesifMiddleware.new(@app, @options).update_user(user_model)
344
365
  ```
@@ -383,9 +404,13 @@ metadata = JSON.parse('{'\
383
404
  '"custom": "testdata"'\
384
405
  '}')
385
406
 
407
+ campaign_model = {"utm_source" => "Adwords",
408
+ "utm_medium" => "Twitter"}
409
+
386
410
  company_model = { "company_id" => "12345",
387
411
  "company_domain" => "acmeinc.com",
388
- "metadata" => metadata }
412
+ "metadata" => metadata,
413
+ "campaign" => campaign_model }
389
414
 
390
415
  update_company = MoesifRack::MoesifMiddleware.new(@app, @options).update_company(company_model)
391
416
  ```
@@ -426,11 +451,13 @@ response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_bat
426
451
 
427
452
  ## Example Code
428
453
 
429
- [Moesif Rack Example](https://github.com/Moesif/moesif-rack-example) is an example of Moesif Rack applied to an Rail application. Please check it out for reference.
454
+ [Moesif Rack Example with Rails](https://github.com/Moesif/moesif-rails-example) is an example of Moesif Rack applied to a Rails application.
455
+
456
+ [Moesif Rack Example](https://github.com/Moesif/moesif-rack-example) is an example of Moesif Rack applied to a Rack application.
430
457
 
431
458
  ## Other integrations
432
459
 
433
- To view more more documentation on integration options, please visit [the Integration Options Documentation](https://www.moesif.com/docs/getting-started/integration-options/).
460
+ To view more documentation on integration options, please visit [the Integration Options Documentation](https://www.moesif.com/docs/getting-started/integration-options/).
434
461
 
435
462
  [ico-built-for]: https://img.shields.io/badge/built%20for-rack-blue.svg
436
463
  [ico-version]: https://img.shields.io/gem/v/moesif_rack.svg
@@ -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 requird for Moesif Middleware'
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,12 +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
36
  @log_body = options.fetch('log_body', true)
31
- @sampling_percentage = get_config(nil)
32
- if not @sampling_percentage.is_a? Numeric
33
- raise "Sampling Percentage should be a number"
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
34
46
  end
35
47
  @capture_outoing_requests = options['capture_outoing_requests']
36
48
  if @capture_outoing_requests
@@ -42,35 +54,6 @@ module MoesifRack
42
54
  end
43
55
  end
44
56
 
45
- def get_config(cached_config_etag)
46
- sample_rate = 100
47
- begin
48
- # Calling the api
49
- config_api_response = @api_controller.get_app_config()
50
- # Fetch the response ETag
51
- response_config_etag = JSON.parse( config_api_response.to_json )["headers"]["x_moesif_config_etag"]
52
- # Remove ETag from the global dict if exist
53
- if !cached_config_etag.nil? && @config_dict.key?(cached_config_etag)
54
- @config_dict.delete(cached_config_etag)
55
- end
56
- # Fetch the response body
57
- @config_dict[response_config_etag] = JSON.parse(JSON.parse( config_api_response.to_json )["raw_body"])
58
- #
59
- app_config = @config_dict[response_config_etag]
60
- # Fetch the sample rate
61
- if !app_config.nil?
62
- sample_rate = app_config.fetch("sample_rate", 100)
63
- end
64
- # Set the last updated time
65
- @last_updated_time = Time.now.utc
66
- rescue
67
- # Set the last updated time
68
- @last_updated_time = Time.now.utc
69
- end
70
- # Return the sample rate
71
- return sample_rate
72
- end
73
-
74
57
  def update_user(user_profile)
75
58
  UserHelper.new.update_user(@api_controller, @debug, user_profile)
76
59
  end
@@ -194,6 +177,7 @@ module MoesifRack
194
177
  event_model = MoesifApi::EventModel.new()
195
178
  event_model.request = event_req
196
179
  event_model.response = event_rsp
180
+ event_model.direction = "Incoming"
197
181
 
198
182
  if @identify_user
199
183
  if @debug
@@ -236,13 +220,31 @@ module MoesifRack
236
220
  # Perform the API call through the SDK function
237
221
  begin
238
222
  @random_percentage = Random.rand(0.00..100.00)
223
+
224
+ begin
225
+ @sampling_percentage = @app_config.get_sampling_percentage(@config, event_model.user_id, event_model.company_id, @debug)
226
+ rescue => exception
227
+ if @debug
228
+ puts 'Error while getting sampling percentage, assuming default behavior'
229
+ puts exception.to_s
230
+ end
231
+ @sampling_percentage = 100
232
+ end
233
+
239
234
  if @sampling_percentage > @random_percentage
240
235
  event_api_response = @api_controller.create_event(event_model)
241
- cached_config_etag = @config_dict.keys[0]
242
236
  event_response_config_etag = event_api_response[:x_moesif_config_etag]
243
237
 
244
- if !event_response_config_etag.nil? && cached_config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 30
245
- @sampling_percentage = get_config(cached_config_etag)
238
+ if !event_response_config_etag.nil? && !@config_etag.nil? && @config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 300
239
+ begin
240
+ @config = @app_config.get_config(@api_controller, @debug)
241
+ @config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
242
+ rescue => exception
243
+ if @debug
244
+ puts 'Error while updating the application configuration'
245
+ puts exception.to_s
246
+ end
247
+ end
246
248
  end
247
249
  if @debug
248
250
  puts("Event successfully sent to Moesif")
@@ -285,7 +287,7 @@ module MoesifRack
285
287
 
286
288
  def get_response_body(response)
287
289
  body = response.respond_to?(:body) ? response.body : response
288
- body = body.inject("") { |i, a| i << a } if body.respond_to?(:each)
290
+ body = body.inject("") { |i, a| i << a } if (body.respond_to?(:each) && body.respond_to?(:inject))
289
291
  body.to_s
290
292
  end
291
293
 
@@ -102,6 +102,7 @@ module MoesifCaptureOutgoing
102
102
  event_model = MoesifApi::EventModel.new()
103
103
  event_model.request = event_req
104
104
  event_model.response = event_rsp
105
+ event_model.direction = "Outgoing"
105
106
 
106
107
  # Metadata for Outgoing Request
107
108
  if @get_metadata_outgoing
@@ -1,6 +1,7 @@
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
@@ -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,10 +69,14 @@ class MoesifRackTest < Test::Unit::TestCase
67
69
  '"custom": "testdata"'\
68
70
  '}')
69
71
 
72
+ campaign_model = {"utm_source" => "Newsletter",
73
+ "utm_medium" => "Email"}
74
+
70
75
  user_model = { "user_id" => "12345",
71
76
  "company_id" => "67890",
72
77
  "modified_time" => Time.now.utc.iso8601,
73
- "metadata" => metadata }
78
+ "metadata" => metadata,
79
+ "campaign" => campaign_model}
74
80
 
75
81
  response = @moesif_rack_app.update_user(user_model)
76
82
  assert_equal response, nil
@@ -106,7 +112,11 @@ class MoesifRackTest < Test::Unit::TestCase
106
112
  end
107
113
 
108
114
  def test_get_config
109
- assert_operator 100, :>=, @moesif_rack_app.get_config(nil)
115
+ @api_client = MoesifApi::MoesifAPIClient.new(@options['application_id'])
116
+ @api_controller = @api_client.api
117
+ @config = @app_config.get_config(@api_controller, @debug)
118
+ @config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
119
+ assert_operator 100, :>=, @sampling_percentage
110
120
  end
111
121
 
112
122
  def test_update_company
@@ -116,9 +126,13 @@ class MoesifRackTest < Test::Unit::TestCase
116
126
  '"custom": "testdata"'\
117
127
  '}')
118
128
 
129
+ campaign_model = {"utm_source" => "Adwords",
130
+ "utm_medium" => "Twitter"}
131
+
119
132
  company_model = { "company_id" => "12345",
120
133
  "company_domain" => "acmeinc.com",
121
- "metadata" => metadata }
134
+ "metadata" => metadata,
135
+ "campaign" => campaign_model }
122
136
 
123
137
  response = @moesif_rack_app.update_company(company_model)
124
138
  assert_equal response, nil
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
4
+ version: 1.3.9
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-08-22 00:00:00.000000000 Z
12
+ date: 2019-12-13 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.8
34
+ version: 1.2.10
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.8
41
+ version: 1.2.10
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
- rubygems_version: 3.0.1
79
+ rubyforge_project:
80
+ rubygems_version: 2.7.7
79
81
  signing_key:
80
82
  specification_version: 4
81
83
  summary: moesif_rack