moesif_rack 1.4.6 → 1.4.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +55 -22
- data/lib/moesif_rack/client_ip.rb +2 -4
- data/lib/moesif_rack/moesif_middleware.rb +10 -4
- data/moesif_capture_outgoing/httplog/adapters/net_http.rb +2 -2
- data/moesif_capture_outgoing/httplog/http_log.rb +10 -8
- data/test/moesif_rack_test.rb +2 -2
- metadata +6 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 2678540c8127f1b07cb8a1dac28bb681bc8b0816daa2f9d46d673c20967db417
|
4
|
+
data.tar.gz: 88d9fbe0dab363880469c208a9af2f205e6878b19798836f50e1ad6059e2c4e8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1407385871aa2466c1f74a8493628dd2d6614b8f25554cd676aeb302c7caa548bc554c5bedb2eeb856c099a7bd5475279db8b03bfd45886dfd2f37627dfa0359
|
7
|
+
data.tar.gz: 8d712814d497c179e02918ba66bd12ac8048866a6e19724cc192f2ab1c4ae77f14aa29d14766a9be26d398a81fc886ac6982b7065857255fe52e5edfd650e9ed
|
data/README.md
CHANGED
@@ -7,33 +7,37 @@
|
|
7
7
|
[![Source Code][ico-source]][link-source]
|
8
8
|
|
9
9
|
Rack Middleware that logs API calls and sends
|
10
|
-
to [Moesif](https://www.moesif.com) for API analytics and
|
10
|
+
to [Moesif](https://www.moesif.com) for API analytics and monitoring.
|
11
11
|
|
12
|
-
Supports Ruby on Rails
|
12
|
+
Supports Ruby on Rails, Grape, and other Ruby frameworks built on Rack.
|
13
13
|
|
14
14
|
[Source Code on GitHub](https://github.com/moesif/moesif-rack)
|
15
15
|
|
16
16
|
## How to install
|
17
17
|
|
18
|
+
Install the Moesif gem.
|
19
|
+
|
18
20
|
```bash
|
19
21
|
gem install moesif_rack
|
20
22
|
```
|
21
23
|
|
22
|
-
|
24
|
+
If you're using Bundler, add the gem to your `Gemfile`.
|
23
25
|
|
24
|
-
```
|
26
|
+
```ruby
|
25
27
|
gem 'moesif_rack'
|
26
|
-
|
27
28
|
```
|
28
29
|
|
30
|
+
Then, run `bundle install`
|
31
|
+
|
29
32
|
## How to use
|
30
33
|
|
31
|
-
###
|
34
|
+
### 1. Enter Moesif Application Id
|
35
|
+
|
36
|
+
Create an options hash containing application_id and any other options.
|
32
37
|
|
33
38
|
```ruby
|
34
39
|
moesif_options = {
|
35
|
-
'application_id' => 'Your Moesif Application Id'
|
36
|
-
'log_body' => true,
|
40
|
+
'application_id' => 'Your Moesif Application Id'
|
37
41
|
}
|
38
42
|
```
|
39
43
|
|
@@ -44,43 +48,67 @@ You can always find your Moesif Application Id at any time by logging
|
|
44
48
|
into the [_Moesif Portal_](https://www.moesif.com/), click on the top right menu,
|
45
49
|
and then clicking _Installation_.
|
46
50
|
|
47
|
-
### Add
|
51
|
+
### 2. Add the middleware
|
52
|
+
|
53
|
+
#### For Rails 5.0 or newer:
|
48
54
|
|
49
55
|
Using strings or symbols for middleware class names is deprecated for newer frameworks like Ruby 5.0,
|
50
56
|
so you should pass the class directly.
|
51
57
|
|
52
|
-
#### For Rails 5.0 or newer:
|
53
|
-
|
54
58
|
```ruby
|
55
59
|
class Application < Rails::Application
|
56
|
-
|
60
|
+
moesif_options = {
|
61
|
+
'application_id' => 'Your Moesif Application Id'
|
62
|
+
}
|
57
63
|
|
58
64
|
config.middleware.use MoesifRack::MoesifMiddleware, moesif_options
|
59
|
-
|
60
|
-
# snip
|
61
65
|
end
|
62
66
|
```
|
63
67
|
|
64
|
-
#### For other frameworks:
|
68
|
+
#### For Rails 4.0 and other frameworks:
|
69
|
+
|
70
|
+
For most rack-based frameworks including Rails 4.x or older, add the middleware `MoesifRack::MoesifMiddleware`.
|
65
71
|
|
66
72
|
within `config/application.rb`
|
67
73
|
|
68
74
|
```ruby
|
69
75
|
class Application < Rails::Application
|
70
|
-
|
76
|
+
moesif_options = {
|
77
|
+
'application_id' => 'Your Moesif Application Id'
|
78
|
+
}
|
71
79
|
|
72
80
|
config.middleware.use "MoesifRack::MoesifMiddleware", moesif_options
|
81
|
+
end
|
82
|
+
```
|
73
83
|
|
74
|
-
|
84
|
+
#### For Grape API:
|
85
|
+
|
86
|
+
For [Grape APIs](https://github.com/ruby-grape/grape), we can add the middleware after any custom parsers or formatters.
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
module Acme
|
90
|
+
class Ping < Grape::API
|
91
|
+
format :json
|
92
|
+
|
93
|
+
moesif_options = {
|
94
|
+
'application_id' => 'Your Moesif Application Id'
|
95
|
+
}
|
96
|
+
|
97
|
+
insert_after Grape::Middleware::Formatter, MoesifRack::MoesifMiddleware, moesif_options
|
98
|
+
|
99
|
+
get '/ping' do
|
100
|
+
{ ping: 'pong' }
|
101
|
+
end
|
75
102
|
end
|
103
|
+
end
|
76
104
|
```
|
77
105
|
|
78
106
|
#### Order of Middleware Matters
|
79
107
|
|
80
|
-
Since Moesif Rack is a logging middleware, the ordering of middleware matters
|
81
|
-
|
108
|
+
Since Moesif Rack is a logging middleware, the ordering of middleware matters.
|
109
|
+
The best place for "MoesifRack::MoesifMidleware" is near the top (so it captures the data closest to the wire), but after
|
110
|
+
any body parsers or authentication middleware.
|
82
111
|
|
83
|
-
The best place for "MoesifRack::MoesifMidleware" is on top (so it captures the data closest to the wire).
|
84
112
|
Typically, right above the default logger of Rails apps, "Rails::Rack::Logger" is a good spot.
|
85
113
|
Or if you want to be as close as wire as possible, put it before "ActionDispatch::Static"
|
86
114
|
|
@@ -107,7 +135,7 @@ To see your current list of middleware:
|
|
107
135
|
|
108
136
|
## Configuration options
|
109
137
|
|
110
|
-
|
138
|
+
Options is a hash with these possible key/value pairs.
|
111
139
|
|
112
140
|
#### __`application_id`__
|
113
141
|
|
@@ -206,7 +234,12 @@ Optional. A Proc that takes env, headers, body and returns a boolean.
|
|
206
234
|
|
207
235
|
moesif_options['skip'] = Proc.new { |env, headers, body|
|
208
236
|
# Add your custom code that returns true to skip logging the API call
|
209
|
-
|
237
|
+
if env.key?("REQUEST_URI")
|
238
|
+
# Skip probes to health page
|
239
|
+
env["REQUEST_URI"].include? "/health"
|
240
|
+
else
|
241
|
+
false
|
242
|
+
end
|
210
243
|
}
|
211
244
|
|
212
245
|
```
|
@@ -2,10 +2,8 @@
|
|
2
2
|
def is_ip?(value)
|
3
3
|
ipv4 = /^(?:(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])\.){3}(?:\d|[1-9]\d|1\d{2}|2[0-4]\d|25[0-5])$/
|
4
4
|
ipv6 = /^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$/
|
5
|
-
|
6
|
-
|
7
|
-
!!(value =~ ipv4 or value=~ ipv6)
|
8
|
-
end
|
5
|
+
# We use !! to convert the return value to a boolean
|
6
|
+
!!(value =~ ipv4 or value=~ ipv6)
|
9
7
|
end
|
10
8
|
|
11
9
|
def get_client_ip_from_x_forwarded_for(value)
|
@@ -102,7 +102,10 @@ module MoesifRack
|
|
102
102
|
|
103
103
|
def parse_body(body, headers)
|
104
104
|
begin
|
105
|
-
if
|
105
|
+
if (body.instance_of?(Hash) || body.instance_of?(Array))
|
106
|
+
parsed_body = body
|
107
|
+
transfer_encoding = 'json'
|
108
|
+
elsif start_with_json(body)
|
106
109
|
parsed_body = JSON.parse(body)
|
107
110
|
transfer_encoding = 'json'
|
108
111
|
elsif headers.key?('content-encoding') && ((headers['content-encoding'].downcase).include? "gzip")
|
@@ -153,12 +156,12 @@ module MoesifRack
|
|
153
156
|
end
|
154
157
|
|
155
158
|
def call env
|
156
|
-
start_time = Time.now.utc.iso8601
|
159
|
+
start_time = Time.now.utc.iso8601(3)
|
157
160
|
|
158
161
|
@helpers.log_debug('Calling Moesif middleware')
|
159
162
|
|
160
163
|
status, headers, body = @app.call env
|
161
|
-
end_time = Time.now.utc.iso8601
|
164
|
+
end_time = Time.now.utc.iso8601(3)
|
162
165
|
|
163
166
|
process_send = lambda do
|
164
167
|
req = Rack::Request.new(env)
|
@@ -293,7 +296,7 @@ module MoesifRack
|
|
293
296
|
# Add Event to the queue
|
294
297
|
@events_queue << event_model
|
295
298
|
@helpers.log_debug("Event added to the queue ")
|
296
|
-
if Time.now.utc > (@
|
299
|
+
if Time.now.utc > (@last_worker_run + 60)
|
297
300
|
start_worker()
|
298
301
|
end
|
299
302
|
|
@@ -341,6 +344,9 @@ module MoesifRack
|
|
341
344
|
|
342
345
|
def get_response_body(response)
|
343
346
|
body = response.respond_to?(:body) ? response.body : response
|
347
|
+
if (body.instance_of?(Hash) || body.instance_of?(Array))
|
348
|
+
return body
|
349
|
+
end
|
344
350
|
body = body.inject("") { |i, a| i << a } if (body.respond_to?(:each) && body.respond_to?(:inject))
|
345
351
|
body.to_s
|
346
352
|
end
|
@@ -7,7 +7,7 @@ module Net
|
|
7
7
|
def request(request, body = nil, &block)
|
8
8
|
|
9
9
|
# Request Start Time
|
10
|
-
request_time = Time.now.utc.iso8601
|
10
|
+
request_time = Time.now.utc.iso8601(3)
|
11
11
|
|
12
12
|
# URL
|
13
13
|
url = "https://#{@address}#{request.path}"
|
@@ -16,7 +16,7 @@ module Net
|
|
16
16
|
@response = orig_request(request, body, &block)
|
17
17
|
|
18
18
|
# Response Time
|
19
|
-
response_time = Time.now.utc.iso8601
|
19
|
+
response_time = Time.now.utc.iso8601(3)
|
20
20
|
|
21
21
|
# Log Event to Moesif
|
22
22
|
if started?
|
@@ -24,15 +24,15 @@ module MoesifCaptureOutgoing
|
|
24
24
|
@skip_outgoing = options['skip_outgoing']
|
25
25
|
@mask_data_outgoing = options['mask_data_outgoing']
|
26
26
|
@log_body_outgoing = options.fetch('log_body_outgoing', true)
|
27
|
-
@app_config = AppConfig.new
|
28
|
-
@config = @app_config.get_config(@api_controller, @debug)
|
27
|
+
@app_config = AppConfig.new(@debug)
|
29
28
|
@config_etag = nil
|
30
29
|
@sampling_percentage = 100
|
31
30
|
@last_updated_time = Time.now.utc
|
32
31
|
@config_dict = Hash.new
|
33
32
|
begin
|
34
|
-
|
35
|
-
|
33
|
+
new_config = @app_config.get_config(@api_controller)
|
34
|
+
if !new_config.nil?
|
35
|
+
@config, @config_etag, @last_config_download_time = @app_config.parse_configuration(new_config)
|
36
36
|
end
|
37
37
|
rescue => exception
|
38
38
|
if @debug
|
@@ -176,7 +176,7 @@ module MoesifCaptureOutgoing
|
|
176
176
|
begin
|
177
177
|
@random_percentage = Random.rand(0.00..100.00)
|
178
178
|
begin
|
179
|
-
@sampling_percentage = @app_config.get_sampling_percentage(@config, event_model.user_id, event_model.company_id
|
179
|
+
@sampling_percentage = @app_config.get_sampling_percentage(@config, event_model.user_id, event_model.company_id)
|
180
180
|
rescue => exception
|
181
181
|
if @debug
|
182
182
|
puts 'Error while getting sampling percentage, assuming default behavior'
|
@@ -196,8 +196,10 @@ module MoesifCaptureOutgoing
|
|
196
196
|
|
197
197
|
if !event_response_config_etag.nil? && !@config_etag.nil? && @config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 300
|
198
198
|
begin
|
199
|
-
|
200
|
-
|
199
|
+
new_config = @app_config.get_config(@api_controller)
|
200
|
+
if !new_config.nil?
|
201
|
+
@config, @config_etag, @last_config_download_time = @app_config.parse_configuration(new_config)
|
202
|
+
end
|
201
203
|
rescue => exception
|
202
204
|
if @debug
|
203
205
|
puts 'Error while updating the application configuration'
|
@@ -222,7 +224,7 @@ module MoesifCaptureOutgoing
|
|
222
224
|
puts e.response_code
|
223
225
|
end
|
224
226
|
rescue => e
|
225
|
-
if debug
|
227
|
+
if @debug
|
226
228
|
puts e.to_s
|
227
229
|
end
|
228
230
|
end
|
data/test/moesif_rack_test.rb
CHANGED
@@ -46,7 +46,7 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
46
46
|
}
|
47
47
|
}
|
48
48
|
@moesif_rack_app = MoesifRack::MoesifMiddleware.new(@app, @options)
|
49
|
-
@app_config = AppConfig.new
|
49
|
+
@app_config = AppConfig.new(true)
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_capture_outgoing
|
@@ -116,7 +116,7 @@ class MoesifRackTest < Test::Unit::TestCase
|
|
116
116
|
def test_get_config
|
117
117
|
@api_client = MoesifApi::MoesifAPIClient.new(@options['application_id'])
|
118
118
|
@api_controller = @api_client.api
|
119
|
-
@config = @app_config.get_config(@api_controller
|
119
|
+
@config = @app_config.get_config(@api_controller)
|
120
120
|
@config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
|
121
121
|
assert_operator 100, :>=, @sampling_percentage
|
122
122
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moesif_rack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.
|
4
|
+
version: 1.4.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Moesif, Inc
|
8
8
|
- Xing Wang
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-06-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|
@@ -81,7 +81,7 @@ metadata:
|
|
81
81
|
mailing_list_uri: https://github.com/Moesif/moesif-rack
|
82
82
|
source_code_uri: https://github.com/Moesif/moesif-rack
|
83
83
|
wiki_uri: https://github.com/Moesif/moesif-rack
|
84
|
-
post_install_message:
|
84
|
+
post_install_message:
|
85
85
|
rdoc_options: []
|
86
86
|
require_paths:
|
87
87
|
- lib
|
@@ -96,9 +96,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
98
|
requirements: []
|
99
|
-
|
100
|
-
|
101
|
-
signing_key:
|
99
|
+
rubygems_version: 3.1.4
|
100
|
+
signing_key:
|
102
101
|
specification_version: 4
|
103
102
|
summary: moesif_rack
|
104
103
|
test_files: []
|