ruby-on-railsperformancenewrelicnewrelic-platform

New relic custom instrumentation for Grape::Middleware::Formatter#call method in Rails app


In my Rails app's New Relic transaction section, I can see that this particular method call (Grape::Middleware::Formatter#call) is the most time consuming one (taking almost 90% of the time):

Middleware  Grape::Middleware::Formatter#call   89.2 % (Time)   824 ms (Avg Time)

But there is not enough information provided about what is actually causing the performance issue in the New Relic's transaction breakdown table. So I want to add Ruby custom instrumentation for this method so that New Relic can provide me with more information about the problem by showing all the events that are happening when Grape::Middleware::Formatter#call method is called.

Looking at the New Relic's documentation for adding custom instrumentation I have created a new file with the name config/initializers/rpm_instrumentation.rb and following content:

require 'new_relic/agent/method_tracer'

Grape::Middleware::Formatter.class_eval do
  include ::NewRelic::Agent::MethodTracer

  add_method_tracer :call
end

But in my development mode, New Relic does not show any extra information under this call: Grape::Middleware::Formatter/call. Only Summary, SQL calls are shown which was there before adding this custom tracer which means my custom tracer is not working as expected.

So my question is am I missing something here? Does New Relic support this type of method instrumentation which are not direct part of the Rails app but coming from the gems that are being used by the Rails app? (in my case, Grape::Middleware::Formatter#call method is part of 'grape' gem).


Solution

  • New Relic does not fully support grape at this time. What you're seeing by default is that we do time the entire grape transaction, starting in middleware and ending at the grape endpoint. However, the Ruby agent just lists that entire time under one transaction name right now (the Grape::Middleware::Formatter#call that you're seeing). To break apart that grape transaction into the various endpoints, you should use set_transaction_name to provide a unique name for the transaction for each endpoint.

    To get more details on the methods within call, you'll need to use add_method_tracer, but not by adding a method tracer to call itself, rather by using add_method_tracer on other methods within call. You'll generally want to set this up in an initializer or other setup phase of your application, before any transactions happen, while set_transaction_name is called during the transaction (e.g. in the controller).