moesif_rack 2.1.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +1 -1
- data/lib/moesif_rack/moesif_helpers.rb +19 -0
- data/lib/moesif_rack/moesif_middleware.rb +18 -39
- data/moesif_capture_outgoing/httplog/adapters/net_http.rb +7 -2
- data/moesif_capture_outgoing/httplog/http_log.rb +38 -24
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d22e96756a6c9b59c31a4615d96968dd2ab335540396a65389ddda9d8604b8b2
|
4
|
+
data.tar.gz: 40e942e0599207bb00917b0894f09f3cd42260bbf1bf3fa8e50c54abde0b57c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8fcff7759ab68baa2d7fad3c41e34816da6fb401106ade305e199347293971d52a9be62d52114915e318e46a945060608345bfa85619a1f364680af7211bef4d
|
7
|
+
data.tar.gz: f4740cb9b0181e73884d250b6c16bcdc9223366af390ebfb399e6731c4528a8c5d20ddb04c582234d0c7e763d58991c146d6cbf4da5ebe45d8a9ef69b303cd31
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -262,7 +262,7 @@ Optional. int, default 200, Maximum batch size when sending to Moesif.
|
|
262
262
|
Optional. int in seconds Default 2. This is the maximum wait time (approximately) before triggering flushing of the queue and sending to Moesif.
|
263
263
|
|
264
264
|
#### __`event_queue_size`__
|
265
|
-
Optional. int, Default
|
265
|
+
Optional. int, Default 1000000, Maximum number of events to hold in queue before sending to Moesif. In case of network issues when not able to connect/send event to Moesif, skips adding new to event to queue to prevent memory overflow.
|
266
266
|
|
267
267
|
#### __`capture_outgoing_requests`__
|
268
268
|
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.
|
@@ -38,4 +38,23 @@ class MoesifHelpers
|
|
38
38
|
log_debug 'failed to convert replacement body ' + e.to_s
|
39
39
|
[replacement_body.to_json.to_s]
|
40
40
|
end
|
41
|
+
|
42
|
+
def parse_multipart(multipart_form_data, content_type)
|
43
|
+
log_debug("try to parse multiple part #{content_type}")
|
44
|
+
|
45
|
+
sanitized_multipart_form_data = multipart_form_data.gsub(/\r?\n/, "\r\n")
|
46
|
+
|
47
|
+
io = StringIO.new(sanitized_multipart_form_data)
|
48
|
+
tempfile = Rack::Multipart::Parser::TEMPFILE_FACTORY
|
49
|
+
bufsize = Rack::Multipart::Parser::BUFSIZE
|
50
|
+
query_parser = Rack::Utils.default_query_parser
|
51
|
+
result = Rack::Multipart::Parser.parse(io, sanitized_multipart_form_data.length, content_type, tempfile, bufsize,
|
52
|
+
query_parser)
|
53
|
+
|
54
|
+
log_debug('multipart parse result')
|
55
|
+
log_debug(result.inspect)
|
56
|
+
|
57
|
+
# this is a hash should be treated as JSON down the road.
|
58
|
+
result.params
|
59
|
+
end
|
41
60
|
end
|
@@ -18,7 +18,7 @@ module MoesifRack
|
|
18
18
|
@app = app
|
19
19
|
raise 'application_id required for Moesif Middleware' unless options['application_id']
|
20
20
|
|
21
|
-
@api_client = MoesifApi::MoesifAPIClient.new(options['application_id'], 'moesif-rack/2.
|
21
|
+
@api_client = MoesifApi::MoesifAPIClient.new(options['application_id'], 'moesif-rack/2.2.2')
|
22
22
|
@api_controller = @api_client.api
|
23
23
|
|
24
24
|
@api_version = options['api_version']
|
@@ -59,7 +59,7 @@ module MoesifRack
|
|
59
59
|
|
60
60
|
@moesif_helpers.log_debug 'Start Capturing outgoing requests'
|
61
61
|
require_relative '../../moesif_capture_outgoing/httplog'
|
62
|
-
MoesifCaptureOutgoing.start_capture_outgoing(options, @app_config, @
|
62
|
+
MoesifCaptureOutgoing.start_capture_outgoing(options, @app_config, method(:add_to_queue), @moesif_helpers)
|
63
63
|
end
|
64
64
|
|
65
65
|
def update_user(user_profile)
|
@@ -94,31 +94,6 @@ module MoesifRack
|
|
94
94
|
[Base64.encode64(body), 'base64']
|
95
95
|
end
|
96
96
|
|
97
|
-
def @moesif_helpers.log_debug(message)
|
98
|
-
return unless @debug
|
99
|
-
|
100
|
-
puts("#{Time.now} [Moesif Middleware] PID #{Process.pid} TID #{Thread.current.object_id} #{message}")
|
101
|
-
end
|
102
|
-
|
103
|
-
def parse_multipart(multipart_form_data, content_type)
|
104
|
-
@moesif_helpers.log_debug("try to parse multiple part #{content_type}")
|
105
|
-
|
106
|
-
sanitized_multipart_form_data = multipart_form_data.gsub(/\r?\n/, "\r\n")
|
107
|
-
|
108
|
-
io = StringIO.new(sanitized_multipart_form_data)
|
109
|
-
tempfile = Rack::Multipart::Parser::TEMPFILE_FACTORY
|
110
|
-
bufsize = Rack::Multipart::Parser::BUFSIZE
|
111
|
-
query_parser = Rack::Utils.default_query_parser
|
112
|
-
result = Rack::Multipart::Parser.parse(io, sanitized_multipart_form_data.length, content_type, tempfile, bufsize,
|
113
|
-
query_parser)
|
114
|
-
|
115
|
-
@moesif_helpers.log_debug('multipart parse result')
|
116
|
-
@moesif_helpers.log_debug(result.inspect)
|
117
|
-
|
118
|
-
# this is a hash shold be treated as JSON down the road.
|
119
|
-
result.params
|
120
|
-
end
|
121
|
-
|
122
97
|
def parse_body(body, headers)
|
123
98
|
begin
|
124
99
|
if body.instance_of?(Hash) || body.instance_of?(Array)
|
@@ -128,7 +103,7 @@ module MoesifRack
|
|
128
103
|
parsed_body = JSON.parse(body)
|
129
104
|
transfer_encoding = 'json'
|
130
105
|
elsif headers.key?('content-type') && (headers['content-type'].downcase.include? 'multipart/form-data')
|
131
|
-
parsed_body = parse_multipart(body, headers['content-type'])
|
106
|
+
parsed_body = @moesif_helpers.parse_multipart(body, headers['content-type'])
|
132
107
|
transfer_encoding = 'json'
|
133
108
|
elsif headers.key?('content-encoding') && (headers['content-encoding'].downcase.include? 'gzip')
|
134
109
|
uncompressed_string = decompress_body(body)
|
@@ -143,6 +118,7 @@ module MoesifRack
|
|
143
118
|
end
|
144
119
|
|
145
120
|
def start_worker
|
121
|
+
@moesif_helpers.log_debug('start worker');
|
146
122
|
Thread.new do
|
147
123
|
loop do
|
148
124
|
# Update the last worker run, in case the events_queue is empty
|
@@ -182,6 +158,18 @@ module MoesifRack
|
|
182
158
|
end
|
183
159
|
end
|
184
160
|
|
161
|
+
def add_to_queue(_event_model)
|
162
|
+
# Add Event to the queue
|
163
|
+
if @events_queue.size >= @event_queue_size
|
164
|
+
@moesif_helpers.log_debug("Skipped Event due to events_queue size [#{@events_queue.size}] is over max #{@event_queue_size} ")
|
165
|
+
else
|
166
|
+
@events_queue << _event_model
|
167
|
+
@moesif_helpers.log_debug('Event added to the queue ')
|
168
|
+
end
|
169
|
+
|
170
|
+
start_worker if Time.now.utc > (@last_worker_run + 60)
|
171
|
+
end
|
172
|
+
|
185
173
|
def call(env)
|
186
174
|
start_time = Time.now.utc.iso8601(3)
|
187
175
|
|
@@ -303,10 +291,9 @@ module MoesifRack
|
|
303
291
|
end
|
304
292
|
|
305
293
|
process_send = lambda do |_event_model|
|
306
|
-
@moesif_helpers.log_debug '
|
294
|
+
@moesif_helpers.log_debug 'incoming event to add to queue for sending to moesif'
|
307
295
|
@moesif_helpers.log_debug _event_model.to_json
|
308
296
|
|
309
|
-
# Perform the API call through the SDK function
|
310
297
|
begin
|
311
298
|
random_percentage = Random.rand(0.00..100.00)
|
312
299
|
|
@@ -322,15 +309,7 @@ module MoesifRack
|
|
322
309
|
|
323
310
|
if sampling_percentage > random_percentage
|
324
311
|
_event_model.weight = @app_config.calculate_weight(sampling_percentage)
|
325
|
-
|
326
|
-
if @events_queue.size >= @event_queue_size
|
327
|
-
@moesif_helpers.log_debug("Skipped Event due to events_queue size [#{@events_queue.size}] is over max #{@event_queue_size} ")
|
328
|
-
else
|
329
|
-
@events_queue << _event_model
|
330
|
-
@moesif_helpers.log_debug('Event added to the queue ')
|
331
|
-
end
|
332
|
-
|
333
|
-
start_worker if Time.now.utc > (@last_worker_run + 60)
|
312
|
+
add_to_queue(_event_model)
|
334
313
|
else
|
335
314
|
@moesif_helpers.log_debug('Skipped Event due to sampling percentage: ' + sampling_percentage.to_s + ' and random percentage: ' + random_percentage.to_s)
|
336
315
|
end
|
@@ -7,10 +7,14 @@ module Net
|
|
7
7
|
def request(request, body = nil, &block)
|
8
8
|
# Request Start Time
|
9
9
|
request_time = Time.now.utc.iso8601(3)
|
10
|
-
|
11
10
|
# URL
|
12
11
|
url = "https://#{@address}#{request.path}"
|
13
12
|
|
13
|
+
if (not request.body_stream.nil?) && MoesifCaptureOutgoing.should_capture_body
|
14
|
+
req_body_from_stream = request.body_stream.read
|
15
|
+
request.body_stream.rewind
|
16
|
+
end
|
17
|
+
|
14
18
|
# Response
|
15
19
|
@response = orig_request(request, body, &block)
|
16
20
|
|
@@ -18,7 +22,8 @@ module Net
|
|
18
22
|
response_time = Time.now.utc.iso8601(3)
|
19
23
|
|
20
24
|
# Log Event to Moesif
|
21
|
-
|
25
|
+
body_from_req_call = body
|
26
|
+
MoesifCaptureOutgoing.call(url, request, request_time, @response, response_time, body_from_req_call, req_body_from_stream) if started?
|
22
27
|
|
23
28
|
@response
|
24
29
|
end
|
@@ -7,7 +7,7 @@ require_relative '../../lib/moesif_rack/app_config'
|
|
7
7
|
|
8
8
|
module MoesifCaptureOutgoing
|
9
9
|
class << self
|
10
|
-
def start_capture_outgoing(options, app_config_manager,
|
10
|
+
def start_capture_outgoing(options, app_config_manager, add_to_queue, moesif_helpers)
|
11
11
|
@moesif_options = options
|
12
12
|
raise 'application_id required for Moesif Middleware' unless @moesif_options['application_id']
|
13
13
|
|
@@ -23,15 +23,21 @@ module MoesifCaptureOutgoing
|
|
23
23
|
@log_body_outgoing = options.fetch('log_body_outgoing', true)
|
24
24
|
|
25
25
|
@app_config = app_config_manager
|
26
|
-
# @app_config
|
27
|
-
# so
|
28
|
-
|
26
|
+
# @app_config is shared instance from the middleware
|
27
|
+
# so same loaded @app_config
|
28
|
+
# add_to_queue is method from the middleware so that we can add to the same queue
|
29
|
+
@add_to_queue = add_to_queue
|
29
30
|
@sampling_percentage = 100
|
30
31
|
@last_updated_time = Time.now.utc
|
32
|
+
@moesif_helpers = moesif_helpers
|
31
33
|
end
|
32
34
|
|
33
|
-
def
|
34
|
-
|
35
|
+
def should_capture_body
|
36
|
+
@moesif_options.nil? ? false : @moesif_options['capture_outgoing_requests'] && @log_body_outgoing
|
37
|
+
end
|
38
|
+
|
39
|
+
def call(url, request, request_time, response, response_time, body_from_req_call, req_body_from_stream)
|
40
|
+
send_moesif_event(url, request, request_time, response, response_time, body_from_req_call, req_body_from_stream)
|
35
41
|
end
|
36
42
|
|
37
43
|
def get_response_body(response)
|
@@ -44,18 +50,30 @@ module MoesifCaptureOutgoing
|
|
44
50
|
Rack::Utils::HTTP_STATUS_CODES.detect { |_k, v| v.to_s.casecmp(response_code_name.to_s).zero? }.first
|
45
51
|
end
|
46
52
|
|
47
|
-
def send_moesif_event(url, request, request_time, response, response_time)
|
53
|
+
def send_moesif_event(url, request, request_time, response, response_time, body_from_req_call, req_body_from_stream)
|
48
54
|
if url.downcase.include? 'moesif'
|
49
|
-
|
55
|
+
@moesif_helpers.log_debug 'Skip adding to queue as it is moesif Event'
|
50
56
|
else
|
51
57
|
response.code = transform_response_code(response.code) if response.code.is_a?(Symbol)
|
52
58
|
|
59
|
+
# Request headers
|
60
|
+
req_headers = request.each_header.collect.to_h
|
61
|
+
req_content_type = req_headers['content-type'].nil? ? req_headers['Content-Type'] : req_headers['content-type']
|
62
|
+
|
53
63
|
# Request Body
|
54
|
-
req_body_string = request.body.nil? || request.body.empty? ?
|
64
|
+
req_body_string = request.body.nil? || request.body.empty? ? body_from_req_call : request.body
|
55
65
|
req_body_transfer_encoding = nil
|
56
66
|
req_body = nil
|
57
67
|
|
58
|
-
if @log_body_outgoing && (
|
68
|
+
if @log_body_outgoing && (not req_content_type.nil?) && (req_content_type.downcase.include? 'multipart/form-data')
|
69
|
+
@moesif_helpers.log_debug 'outgoing request is multipart, parsing req_body_from_stream'
|
70
|
+
begin
|
71
|
+
req_body = @moesif_helpers.parse_multipart(req_body_from_stream, req_content_type)
|
72
|
+
rescue StandardError => e
|
73
|
+
@moesif_helpers.log_debug 'outgoing request is multipart, but failed to process req_body_from_stream: ' + req_body_from_stream.to_s + e.to_s
|
74
|
+
req_body = nil
|
75
|
+
end
|
76
|
+
elsif @log_body_outgoing && (req_body_string && req_body_string.length != 0)
|
59
77
|
begin
|
60
78
|
req_body = JSON.parse(req_body_string)
|
61
79
|
rescue StandardError
|
@@ -83,8 +101,9 @@ module MoesifCaptureOutgoing
|
|
83
101
|
event_req.time = request_time
|
84
102
|
event_req.uri = url
|
85
103
|
event_req.verb = request.method.to_s.upcase
|
86
|
-
event_req.headers =
|
104
|
+
event_req.headers = req_headers
|
87
105
|
event_req.api_version = nil
|
106
|
+
|
88
107
|
event_req.body = req_body
|
89
108
|
event_req.transfer_encoding = req_body_transfer_encoding
|
90
109
|
|
@@ -155,19 +174,14 @@ module MoesifCaptureOutgoing
|
|
155
174
|
|
156
175
|
if @sampling_percentage > @random_percentage
|
157
176
|
event_model.weight = @app_config.calculate_weight(@sampling_percentage)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
puts('Outgoing Event successfully added to event queue') if @debug
|
167
|
-
return
|
168
|
-
end
|
169
|
-
elsif @debug
|
170
|
-
puts('Skipped outgoing Event due to sampling percentage: ' + @sampling_percentage.to_s + ' and random percentage: ' + @random_percentage.to_s)
|
177
|
+
@moesif_helpers.log_debug 'Adding Outgoing Request Data to Queue'
|
178
|
+
@moesif_helpers.log_debug event_model.to_json
|
179
|
+
# we put in the queue and forget it.
|
180
|
+
@add_to_queue.call(event_model)
|
181
|
+
@moesif_helpers.log_debug 'Finished adding outgoing request data to Queue'
|
182
|
+
|
183
|
+
else
|
184
|
+
@moesif_helpers.log_debug('Skipped outgoing Event due to sampling percentage: ' + @sampling_percentage.to_s + ' and random percentage: ' + @random_percentage.to_s)
|
171
185
|
end
|
172
186
|
rescue MoesifApi::APIException => e
|
173
187
|
if e.response_code.between?(401, 403)
|
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: 2.
|
4
|
+
version: 2.2.2
|
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: 2023-
|
12
|
+
date: 2023-11-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: test-unit
|