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 +4 -4
- data/README.md +47 -20
- data/lib/moesif_rack/app_config.rb +121 -0
- data/lib/moesif_rack/moesif_middleware.rb +39 -37
- data/moesif_capture_outgoing/httplog/http_log.rb +1 -0
- data/test/moesif_rack_test.rb +17 -3
- 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: 8f5cd1d13df1da4833bc55a10462721bdabae0a09cb6d8ab6398c378bd546975
|
4
|
+
data.tar.gz: ab2e62d3c6c4f76532bf8dbad38b4fdb2747413897e72228dc1ac23265d134c9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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
|
-
|
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
|
67
|
-
Many
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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-
|
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
|
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
|
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
|
-
|
32
|
-
|
33
|
-
|
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? &&
|
245
|
-
|
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
|
data/test/moesif_rack_test.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
+
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-
|
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.
|
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.
|
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
|
-
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.7.7
|
79
81
|
signing_key:
|
80
82
|
specification_version: 4
|
81
83
|
summary: moesif_rack
|