The New Relic Ruby agent automatically collects many metrics. It also includes an API you can use to collect additional metrics about your application. If you see large Application Code segments in transaction trace details, custom instrumentation can give a more complete picture of what is going on in your application. For details about all available API methods, please see our Ruby agent API documentation.
Tip
Collecting too many metrics can impact the performance of your application and New Relic. To avoid data problems, keep the total number of unique metrics introduced by custom instrumentation under 2000.
Method tracers
The easiest way to capture custom instrumentation is by tracing calls to a particular method. Tracing a method as described below will insert an additional node in your transaction traces for each invocation of that method, providing greater detail about where time is going in your transactions.
This is best used when you feel certain a transaction already exists. Method tracers give you an additional level of granularity within the context of something already instrumented by the agent. If you are uncertain if a transaction exists, see Tracing Transaction Entry Points.
Method tracers are software probes you can put on a method of any class. The probes use module prepending to insert themselves when the target methods execute and gather custom instrumentation on their performance.
Tracing in class definitions
Method tracers can be used within normal class definitions, as long as the target method has been defined first:
require 'new_relic/agent/method_tracer'class Foo include ::NewRelic::Agent::MethodTracer
def generate_image ... end
add_method_tracer :generate_image, 'Custom/generate_image'end
To instrument a class method, add the method tracer in the class singleton:
require 'new_relic/agent/method_tracer'class Foo def self.generate_image ... end
class << self include ::NewRelic::Agent::MethodTracer
add_method_tracer :generate_image, 'Custom/generate_image' endend
The add_method_tracer
method takes an optional metric name and a hash of options. For more information, see add_method_tracer in the New Relic RubyDoc.
Tracing initializers
For Rails, a common way to add instrumentation is to create an initializer and "monkey patch" the instrumentation directives.
For example, to add a method tracer to MyCache#get
:
Make sure the MyCache class is loaded before adding the method tracer.
Add the following in a file named config/initializers/rpm_instrumentation.rb:
require 'new_relic/agent/method_tracer'MyCache.class_eval doinclude ::NewRelic::Agent::MethodTraceradd_method_tracer :getend
Tracing blocks of code
Sometimes a single method is so complex that tracking overall time doesn't give enough detail. If you have an exisiting transaction for which you would like to have more granular information on an individual method, you can wrap a block of code with a tracer. Call trace_execution_scoped
passing the code to trace as a block:
extend ::NewRelic::Agent::MethodTracer
def slow_action self.class.trace_execution_scoped(['Custom/slow_action/beginning_work']) do # do stuff and report execution time with a custom metric name end
# more stuff, whose time will be "blamed" to slow_actionend
For more information, see add_method_tracer in the New Relic RubyDoc. If you aren't sure if a transaction already exists or need to start a new one, see instrumenting a section of code under Advanced Custom Instrumentation.
Naming transactions
Instrumented transactions are used to determine the throughput and overall response time for your application. The name of the method and the class will be used for the name of the transaction as reported to New Relic. For more information, see Viewing transaction traces.
Normally the agent automatically chooses the transaction name. If you want to change the name of a transaction while it is still running, use NewRelic::Agent.set_transaction_name
and the corresponding NewRelic::Agent.get_transaction_name
.
Important
Do not use brackets [suffix]
at the end of your transaction name. New Relic automatically strips brackets from the name. Instead, use parentheses (suffix)
or other symbols if needed.
This is useful if you want to segment your transaction based on some criteria. For example, if you wanted to vary the transaction name by response format in Rails:
class UsersController def index @users = User.all respond_to do |format| format.html format.json do NewRelic::Agent.set_transaction_name('Users/index.json') render :json => @users end format.xml do NewRelic::Agent.set_transaction_name('Users/index.xml') render :xml => @users end end endend
Renaming transactions can also be used to segment your requests around some business criteria. For example, you could segment a transaction into "Big Customer" and "Small Customer" with code like this:
class UsersController
before_filter :segment_new_relic_by_customer_size
def segment_new_relic_by_customer_size new_relic_name = NewRelic::Agent.get_transaction_name if current_user.big_customer? NewRelic::Agent.set_transaction_name("#{new_relic_name} - big customer") else NewRelic::Agent.set_transaction_name("#{new_relic_name} - small customer") end end
end
Tracing transaction entry points
Ordinarily the agent will be able to identify transactions within your application, but if you're not using a supported framework, or if you'd like to record transactions that the agent is not automatically recording, you can define methods as being transaction entry points:
class Controller include NewRelic::Agent::Instrumentation::ControllerInstrumentation
def transaction # execute a transaction end add_transaction_tracer :transactionend
To instrument a class method, add the method tracer in the class singleton:
class Controller include NewRelic::Agent::Instrumentation::ControllerInstrumentation
class << self def transaction # execute a transaction end add_transaction_tracer :transaction endend
Instrumenting non-web transactions
Along with method-level tracing, you can instrument non-web transactions, such as background tasks, with the same level of transaction and error detail as web transactions. For more information, see Monitoring Ruby background processes and daemons.
Applying method tracers automatically via config
With New Relic Ruby agent v9.14.0 and higher, method tracers can be applied automatically by the agent for any Ruby method defined in the agent's configuration (set via the YAML configuration file or environment variables).
The :automatic_custom_instrumentation_method_list
configuration parameter can be used to define a list of fully qualified (namespaced) Ruby methods for which the agent will try to add a tracer. This doesn't require any code modifications of the classes that define the methods.
The list should be an array of CLASS#METHOD
(for instance methods) and/or CLASS.METHOD
(for class methods) strings.
Use fully qualified class names (using the ::
delimiter) that include any module or class namespacing.
Here is some Ruby source code that defines a render_png
instance method for an Image
class and a notify
class method for a User
class, both within a MyCompany
module namespace:
module MyCompany class Image def render_png # code to render a PNG end end
class User def self.notify # code to notify users end endend
Given that source code, the newrelic.yml
config file might request instrumentation for both of these methods like so:
automatic_custom_instrumentation_method_list: - MyCompany::Image#render_png - MyCompany::User.notify
That configuration example uses YAML array syntax to specify both methods. Alternatively, you can use a comma-delimited string:
automatic_custom_instrumentation_method_list: 'MyCompany::Image#render_png, MyCompany::User.notify'
Whitespace around the comma(s) in the list is optional. When configuring the agent with a list of methods via the NEW_RELIC_AUTOMATIC_CUSTOM_INSTRUMENTATION_METHOD_LIST
environment variable, use this comma-delimited string format:
export NEW_RELIC_AUTOMATIC_CUSTOM_INSTRUMENTATION_METHOD_LIST='MyCompany::Image#render_png, MyCompany::User.notify'
The YAML entry or environment variable configuration is all that is needed. With this approach, there is no need to add any of the require
, include
, or add_method_tracer
lines of code to the application.
Advanced custom instrumentation
When tracing code not automatically instrumented by the agent, the standard method tracers will usually be enough.
However, sometimes you need to instrument something more complex than a single method call. For example, you may want to instrument a few lines of code within a method, or you may want to start a transaction in one part of your code and finish it elsewhere.
The Tracer module, introduced in agent version 6.0, provides a flexible API that lets you create transactions and segments as well as interact with the current transaction.
Instrumenting a section of code
To instrument a section of code, wrap the code in a block, then pass the block to the Tracer.in_transaction
method. The agent will ensure that a transaction exists, and will create a segment within it for the code inside the block.
require 'new_relic/agent/tracer'
def long_and_complex_process expensive_setup
NewRelic::Agent::Tracer.in_transaction( partial_name: 'Complex/process', category: :task ) do code_to_be_instrumented end
expensive_teardownend
Starting a transaction or segment
If you need to start a transaction at one location in your code but finish it in another (as can happen with callback-based events), call NewRelic::Agent::Tracer.start_transaction_or_segment
. You must call finish
on the return value of this method:
class MyEventWatcher def event_started @transaction = NewRelic::Agent::Tracer.start_transaction_or_segment( partial_name: 'MyEventWatcher/my_event', category: :task) end
def event_completed @transaction.finish endend
For more information, see Tracer#start_transaction_or_segment in the New Relic RubyDoc.
Instrumenting Threads
In 8.7.0 and higher, use the class NewRelic::TracedThread
in applications to create threads that are instrumented by New Relic.
Use this class as a replacement for the native Thread
class. See our TracedThread API documentation for more detail.