Sending performance metrics from your Ruby app to APM Server can be as easy as installing the
elastic-apm Rubygem. Most integrations are plug-n-play, and Rails and Rack support is built in.
However there are several ways to add more information to the data as well as ways to set up your own custom instrumentations.
Adding more info to the already instrumented parts
To add more information to the data you are already gathering, Elastic APM has a few concepts.
Let's say your app is built around the concept of
companies, you could assign the
current_company.short_name to every transaction and error. Tags are simple key-value pairs, and they are indexed in Elasticsearch and thereby both filterable and queryable, so you can slice and dice your metrics in any way you want:
class ApplicationController < ActionController::Base before_action do ElasticAPM.set_label :company, current_company.short_name end end
This will make it way easier to see if certain performance problems or exceptions are only affecting some of your customers.
Users are another widespread concept, and Elastic APM has a place for that as well:
class ApplicationController < ActionController::Base before_action do ElasticAPM.set_label :company_id, current_company.id ElasticAPM.set_user current_user end end
The agent will include the
username fields of whatever is passed. You can of course customize the fields to whatever they may be called in your app.
If you have your eyes on a specific method that you want to track the duration of, you can use the
SpanHelpers module. It provides two methods,
class ThingsController < ApplicationController include ElasticAPM::SpanHelpers # ... def do_the_work # ... end span_method :do_the_work def self.do_other_work # ... end span_class_method :do_other_work # ... alternative syntax for newer versions of Ruby span_method \ def do_the_work # ... end end
This approach is great if what you want to measure is a simple method call. If you want more granular control there's the general usage API.
Creating transactions and spans manually
To create transactions and spans manually, the agent provides a public API. The agent itself uses this API internally to instrument most of the supported libraries.
The first thing you'll need is a transaction. If you are inside a request in your Rails app, Rack app using middleware, or a background job in one of the supported job runners, then you're most likely already inside a transaction.
If you aren't, create a transaction like so:
ElasticAPM.start # if it isn't started already begin transaction = ElasticAPM.start_transaction 'Optional name', 'optional.type' # It's your responsibility to make sure the transactions are ended. # To make sure we do so, we wrap in begin..ensure. ensure ElasticAPM.end_transaction end
Alternatively, there's a block version of the same that makes sure to end afterwards:
ElasticAPM.with_transaction do |transaction| # if you need to, you can alter the transaction inside, eg: transaction.name = method_that_returns_the_name # be aware that if the agent isn't started, `transaction` is nil but the block is still evaluated end
Inside transactions, spans are the individual pieces of work that your app performs. If you are using any of the automatically instrumented libraries all you have to do is wrap them in a transaction.
If you need additional spans, the API matches the transaction:
begin span = ElasticAPM.start_span 'Required name', 'optional.type' ensure ElasticAPM.end_span end # Or the block form ElasticAPM.with_span 'Hard work' do |span| # ... end
See the APM Ruby agent docs for the public API.
Easy to get going, easy to expand
We've done our best to make the initial, minimal setup of the Ruby APM agent as easy as possible. If you don't want to, you don't need any of the above and you will still, most likely, get a lot of usable information.
However, if you'd like to get your hands dirty dissecting every part of the beast that is your app, Elastic APM provides the tools to do that, too.
Try it out
How well is your Ruby running? Where is it spending its time? Where should you focus your next sprint to improve the user experience? Elastic APM and the Ruby agent can help answer all of these questions, and more. Instrument your app, and either download the Elastic stack and run locally, or send your traces to the Elasticsearch Service on Elastic Cloud with a free trial, which includes an APM server. As always, if you have any questions, ideas, thoughts, or concerns, reach out on the Discuss forum.