How to instrument your Ruby app with the Elastic APM Ruby agent



  • 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](/solutions/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: ```prettyprint class ApplicationController < ActionController::Base before_action do ElasticAPM.set_tag :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. ![Listing only requests by the company Opbeans][1] Users are another widespread concept, and Elastic APM has a place for that as well: ```prettyprint class ApplicationController < ActionController::Base before_action do ElasticAPM.set_tag :company_id, current_company.id ElasticAPM.set_user current_user end end ``` The agent will include the `id`, `email` and `username` fields of whatever is passed. You can of course customize the fields [to whatever they may be called in your app][custom-user]. ## The `SpanHelpers` module 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, `span_method` and `span_class_method`. ```prettyprint 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 ``` See the [Elastic APM Ruby agent `SpanHelpers` docs][span-helpers]. 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][supported-tech], then you're most likely already inside a transaction. If you aren't, create a transaction like so: ```prettyprint 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: ```prettyprint 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][supported-tech] all you have to do is wrap them in a transaction. If you need additional spans, the API matches the transaction: ```prettyprint 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 ``` ![Why does this take so long… oh][2] See [the APM Ruby agent docs](https://www.elastic.co/guide/en/apm/agent/ruby/2.x/api.html) 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. [supported-tech]: https://www.elastic.co/guide/en/apm/agent/ruby/2.x/supported-technologies.html [custom-user]: https://github.com/elastic/apm-agent-ruby/blob/2.x/lib/elastic_apm/config.rb#L29-L31 [span-helpers]: https://www.elastic.co/guide/en/apm/agent/ruby/2.x/custom-instrumentation.html#_helpers ## 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](https://www.elastic.co/cloud/) on [Elastic Cloud](https://cloud.elastic.co/) 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](https://discuss.elastic.co/c/apm) forum. [1]: https://www.elastic.co/assets/blt0b8d4408de377f0d/image1.png [2]: https://www.elastic.co/assets/blt4abfdb2603d7ed40/image2.png

    https://www.elastic.co/blog/how-to-instrument-your-ruby-app-with-the-elastic-apm-ruby-agent

Log in to reply
 

© Lightnetics 2024