moesif_rack 1.3.4 → 1.3.9

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 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