Your data. Anywhere you go.

New Relic for iOS or Android


Download on the App Store    Android App on Google play


New Relic Insights App for iOS


Download on the App Store


Learn more

Close icon

Rename segment after creation


#1

Hi!

We are working on tracking cache performance in rails app. ActiveSupport::Cache provides instrumentation features similar to other rails components. So we have implemented class inherited from NewRelic::Agent::Instrumentation::EventedSubscriber similar to https://github.com/newrelic/rpm/blob/master/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb which tracks cache methods within Custom/Cache/%method_name% segments.

It gives us some useful information, but we want to improve collection of this data: to track cache hits and misses separately. We added segment.name = "Custom/Cache/read:#{payload[:hit] ? 'hit' : 'miss'}" after request is performed and before segment.finish. But it seems to work not for every request. I have not found something similar to set_transaction_name for segments. Is it possible to rename segments?

I also wonder how it’s better to see hit/miss breakdown by caller similar to breakdown of datastore/external transactions? Can I use Datastore/Cache/... metric name to make it appear on that tab?

I’ve also checked if we could implement this with Insights and found only custom events option. Docs warn about high throughput and it looks like custom events are not suitable for tracking cache requests.

We use latest newrelic_rpm 5.3.0.346.


#2

Hi, melentievm. Thank you for writing!

You point out a couple of possibilities here for tracking cache hits and misses. The approach I might suggest is to use custom metrics instead of segments or custom events. Metrics have the advantage of being easy to use and suitable for high-throughput applications.

Here’s an example taken from a Rails 5 application’s config/initializers directory:

ActiveSupport::Notifications.subscribe 'cache_read.active_support' do |_, _, _, _, data|
  if data[:hit]
    ::NewRelic::Agent::increment_metric 'Custom/Cache/read:hit'
  else
    ::NewRelic::Agent::increment_metric 'Custom/Cache/read:miss'
  end
end

This example doesn’t customize the metric name by caller, but it should be possible to do so based on the cache key or other information passed into the notification handler.

From there, you can use the Metric explorer in New Relic Insights to build a custom dashboard to track the hit and miss metrics.

I hope this solution will work for your application. Happy coding!

Sincerely,

Erin Dees
Lead Software Engineer
Ruby Agent Team
New Relic


#3

Hi Erin, and thanks for reply!

We have already implemented collection of custom metrics but faced an issue with combining this values in calculations: it looks like it’s impossible to use metrics in NRQL or any other calculations. So it’s impossible to calculate even simple cache hit-ratio. We just have 2 separate charts for now and have to approximately guess trends without exact numbers. Is there any workarounds for this or plans to add support for metrics in NRQL?

Docs says that it’s better to keep metrics count under 2000, but having different names hit/miss for every transaction that accesses cache will result in huge number.


#4

Hi, Melentievm!

Indeed, there’s no current way to do math across metrics using NRQL. However, if you’re looking for a way to calculate hit/miss percentages, there are a couple of alternative approaches:

  1. Keep the hit/miss counts in Ruby variables, and report the cache hit percentage to New Relic using the Ruby agent’s record_metric method.
  2. Add a custom attribute to your transactions, as in ::NewRelic::Agent.add_custom_attributes(cache_hit: true), and then query with NRQL using something like SELECT Percentage(Count(*), WHERE cache_hit IS TRUE) FROM Transaction.
  3. Per your suggestion in the original post, use a custom event rather than a custom attribute.

Approach 2, custom attributes, would likely require the smallest code change to implement. Plus, you’d have access to all of NRQL for doing things like FACET by controller or action. The only downside is that if your app is high-throughput, the agent will have to sample transactions, meaning that fewer than 100% of transactions will be recorded. If your main priority is calculating percentages, sampling should be fine.

Sincerely,

Erin


#5

Hi Erin,

With first option it’ll be much harder to implement calculating hit-rate per transaction type: we have to calculate values for each transaction type internally and report all of them each time.

Does third one will work with high throughput? Docs says

Sending a lot of events can increase the memory overhead of the agent. Additionally, posts greater than 1MB in size will not be recorded regardless of the maximum number of events.

As of second one. Single web request can access cache several times. Some async workers can access cache hundreds times. Does NewRelic::Agent.add_custom_attributes sets attribute only for topmost transaction or will it add attribute for custom segment when called inside one?

For me it looks like segments are the most appropriate tool for tracking this values now. Back to original message, is there any technical reasons for preventing rename of opened segment?

I see that segments are tracked as metrics in Insights, so we will not be able to perform calculations, however it’s still be possible to see breakdown by transactions in APM. While waiting for metrics support in NRQL :slight_smile:

Thank you,
Max


#6

Hi, Max.

Thanks for giving us additional information. We are still thinking custom attributes may be a good solution for you. If you need to keep track of how many times the cache gets accessed, rather than a boolean attribute such as ::NewRelic::Agent.add_custom_attributes(cache_hit: true) as we suggested before, you could keep a count of all hits and misses and add numeric attributes, like so: ::NewRelic::Agent.add_custom_attributes({ cache_hits: @cache_hits, cache_misses: @cache_misses })

Then you could easily see the percentage of cache hits with a NRQL query such as:
SELECT 100 * SUM(cache_hits) / SUM(cache_hits + cache_misses) FROM Transaction

Sincerely,
Rachel Klein
Software Engineer
Ruby Agent Team
New Relic