Moesif Middleware for Ruby on Rails and Rack
Rack Middleware that logs incoming API calls to Moesif's AI-powered API analytics service. Supports Ruby on Rails apps and other Ruby frameworks built on Rack.
How to install
gem install moesif_rack
and if you have a Gemfile
in your project, please add this line to
gem 'moesif_rack', '~> 1.3.2'
How to use
Create the options
= {
'application_id' => 'Your application Id'
}
You can find your Application Id from Moesif Dashboard -> Top Right Menu -> App Setup
Add to middleware
within config/application.rb
class Application < Rails::Application
# snip
config.middleware.use "MoesifRack::MoesifMiddleware",
# snip
end
Order of Middleware Matters
Since Moesif Rack is basically a logging middleware, the ordering of middleware matters for accuracy and completeness. Many middlewares are installed by default by Rails.
To see the list of middlewares that your system already have, type this into the bash.
bin/rails middleware
The best place for "MoesifRack::MoesifMidleware" is on top as possible (so it captures the data closest to the wire). Typically, right above the default logger of Rails apps, "Rails::Rack::Logger" is a good spot. Or if you want to be as close as wire as possible, put it before "ActionDispatch::Static"
You should use the following line of code to insert the middleware into the right spot.
config.middleware.insert_before "Rails::Rack::Logger", "MoesifRack::MoesifMiddleware",
Please note, if you are using "Rack::Deflater" please make sure that "MoesifRack::MoesifMiddlware" is below it, so it can capture uncompressed data.
Configuration options
The options is a hash with these possible key value pairs.
application_id
Required. String. This is the Moesif application_id under settings from your Moesif account.
api_version
Optional. String. Tag requests with the version of your API.
identify_user
Optional. identify_user is a Proc that takes env, headers, and body as arguments and returns a user_id string. This helps us attribute requests to unique users. Even though Moesif can automatically retrieve the user_id without this, this is highly recommended to ensure accurate attribution.
['identify_user'] = Proc.new { |env, headers, body|
#snip
'the_user_id'
}
identify_company
Optional. identify_company is a Proc that takes env, headers, and body as arguments and returns a company_id string. This helps us attribute requests to unique company.
['identify_company'] = Proc.new { |env, headers, body|
#snip
'the_company_id'
}
get_metadata
Optional. get_metadata is a Proc that takes env, headers, and body as arguments and returns a Hash that is representation of a JSON object. This allows you to attach any metadata to this event.
['get_metadata'] = Proc.new { |env, headers, body|
#snip
value = {
'foo' => 'abc',
'bar' => '123'
}
value
}
identify_session
Optional. A Proc that takes env, headers, body and returns a string.
['identify_session'] = Proc.new { |env, headers, body|
#snip
'the_session_token'
}
mask_data
Optional. A Proc that takes event_model as an argument and returns event_model. With mask_data, you can make modifications to headers or body of the event before it is sent to Moesif.
['mask_data'] = Proc.new { |event_model|
#snip
event_model
}
For details for the spec of event model, please see the moesifapi-ruby
skip
Optional. A Proc that takes env, headers, body and returns a boolean.
['skip'] = Proc.new { |env, headers, body|
#snip
false
}
For details for the spec of event model, please see the Moesif Ruby API Documentation
debug
Optional. Boolean. Default false. If true, it will print out debug messages. In debug mode, the processing is not done in backend thread.
log_body
Optional. Boolean. Default true. If false, will not log request and response body to Moesif.
capture_outoing_requests
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 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 request and Response response objects.
identify_user_outgoing
Optional. identify_user_outgoing is a Proc that takes request and response as arguments and returns a user_id string. This helps us attribute requests to unique users. Even though Moesif can automatically retrieve the user_id without this, this is highly recommended to ensure accurate attribution.
['identify_user_outgoing'] = Proc.new { |request, response|
#snip
'the_user_id'
}
identify_company_outgoing
Optional. identify_company_outgoing is a Proc that takes request and response as arguments and returns a company_id string. This helps us attribute requests to unique company.
['identify_company_outgoing'] = Proc.new { |request, response|
#snip
'the_company_id'
}
get_metadata_outgoing
Optional. get_metadata_outgoing is a Proc that takes request and response as arguments and returns a Hash that is representation of a JSON object. This allows you to attach any metadata to this event.
['get_metadata_outgoing'] = Proc.new { |request, response|
#snip
value = {
'foo' => 'abc',
'bar' => '123'
}
value
}
identify_session_outgoing
Optional. A Proc that takes request, response and returns a string.
['identify_session_outgoing'] = Proc.new { |request, response|
#snip
'the_session_token'
}
skip_outgoing
Optional. A Proc that takes request, response and returns a boolean. If true
would skip sending the particular event.
['skip_outgoing'] = Proc.new{ |request, response|
#snip
false
}
mask_data_outgoing
Optional. A Proc that takes event_model as an argument and returns event_model. With mask_data_outgoing, you can make modifications to headers or body of the event before it is sent to Moesif.
['mask_data_outgoing'] = Proc.new { |event_model|
#snip
event_model
}
log_body_outgoing
Optional. Boolean. Default true. If false, will not log request and response body to Moesif.
Update User
update_user method
A method is attached to the moesif middleware object to update the user profile or metadata.
The metadata field can be any custom data you want to set on the user. The user_id
field is required.
= JSON.parse('{'\
'"email": "[email protected]",'\
'"name": "ruby api user",'\
'"custom": "testdata"'\
'}')
user_model = { "user_id" => "testrubyapiuser",
"modified_time" => Time.now.utc.iso8601,
"metadata" => }
update_user = MoesifRack::MoesifMiddleware.new(@app, @options).update_user(user_model)
update_users_batch method
A method is attached to the moesif middleware object to update the users profile or metadata in batch.
The metadata field can be any custom data you want to set on the user. The user_id
field is required.
= JSON.parse('{'\
'"email": "[email protected]",'\
'"name": "ruby api user",'\
'"custom": "testdata"'\
'}')
user_models = []
user_model_A = { "user_id" => "testrubyapiuser",
"modified_time" => Time.now.utc.iso8601,
"metadata" => }
user_model_B = { "user_id" => "testrubyapiuser1",
"modified_time" => Time.now.utc.iso8601,
"metadata" => }
user_models << user_model_A << user_model_B
response = MoesifRack::MoesifMiddleware.new(@app, @options).update_users_batch(user_models)
Update Company
update_company method
A method is attached to the moesif middleware object to update the company profile or metadata.
The metadata field can be any custom data you want to set on the company. The company_id
field is required.
= JSON.parse('{'\
'"email": "[email protected]",'\
'"name": "ruby api company",'\
'"custom": "testdata"'\
'}')
company_model = { "company_id" => "testrubyapicompany",
"company_domain" => "acmeinc.com",
"metadata" => }
update_company = MoesifRack::MoesifMiddleware.new(@app, @options).update_company(company_model)
update_companies_batch method
A method is attached to the moesif middleware object to update the companies profile or metadata in batch.
The metadata field can be any custom data you want to set on the company. The company_id
field is required.
= JSON.parse('{'\
'"email": "[email protected]",'\
'"name": "ruby api user",'\
'"custom": "testdata"'\
'}')
company_models = []
company_model_A = { "company_id" => "testrubyapicompany",
"company_domain" => "nowhere.com",
"metadata" => }
company_model_B = { "company_id" => "testrubyapicompany1",
"company_domain" => "acmeinc.com",
"metadata" => }
company_models << company_model_A << company_model_B
response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_batch(company_models)
How to test
- Manually clone the git repo
- From terminal/cmd navigate to the root directory of the middleware.
- Invoke 'gem install moesif_rack'
- Add your own application id to 'test/moesif_rack_test.rb'. You can find your Application Id from Moesif Dashboard -> Top Right Menu -> Installation
- Invoke 'ruby test/moesif_rack_test.rb'
- Invoke 'ruby -I test test/moesif_rack_test.rb -n test_capture_outgoing' to test capturing outgoing API calls from your app to third parties like Stripe, Github or to your own dependencies.
Example Code
Moesif Rack Example is an example of Moesif Rack applied to an Rail application. Please check it out for reference.
Other integrations
To view more more documentation on integration options, please visit the Integration Options Documentation.