[Ruby] How to send custom metric attributes

I have a ruby class that is sending HTTP requests to multiple different URLs. Each URL is connected with an internal code and I wanted to create two graphs on new relic that will display

  1. average duration of the request grouped by internal code ( so basically one label for every internal code )

  2. count of HTTP response codes grouped by internal code + response code number ( so basically one label for every combination of “#{internal_code + http_code_number}” )

I’m using ruby newrelic_rpm v6.15.0

Here is what I tried already.

extend ::NewRelic::Agent::MethodTracer
def call(internal_code)
  request = send_request(internal_code)

  NewRelic::Agent.add_custom_attributes(
    internal_code: internal_code,
    response_duration: request.duration,
  )
end
add_method_tracer :call

unfortunately, custom_attributes are not added to the custom metric.

After I tried to use Module: NewRelic::Agent — Documentation for newrelic/rpm (dev) but it does not support custom attributes.

I could create a custom metric using dynamic interpolation but newrelic doc says I should not create more than 2k of custom metrics. Unfortunately, I have over 1k internal_codes so this solution won’t work.

record_metric("Custom/SomeSpecificServiceHttpDuration#{internal_code}", request.duration)
increment_metric("Custom/SomeSpecificServiceHttpCode/#{internal_code}/#{request.code}")

I tried to find an answer on the forum and in newrelic documentation but without much success. I assume sending contextual data is one of the most important features so I wonder how it can be implemented using newrelic?

Hi, @lefty313: add_custom_attributes() adds attributes to the Transaction event. To record dimensional metrics, you should use the Metric API.

Will adding another custom_attribute e.g request_target: 'SomeSpecificHttpService' allow me to plot the graphs I described in the initial post using Transaction in the query builder?

Basically can I filter/group using custom_attributes in the Event[Transaction] query?

To record dimensional metrics, you should use the [Metric API]

AFIK there is no official gem to interact with metric api and I can’t simply hardcode it directly in my code because I would be too dependant on newrelic api since my business request will always be coupled with metric api request. I tried to use newrelic_rpm because AFIK it batch requests and sends everything using the background thread once every minute. (please correct me if I’m wrong)

I assume using

NewRelic::Agent.record_custom_event(
  'SomeSpecificHttpService',
  foo: "bar",
  baz: "foo"
)

will allow me to create graphs but data won’t be displayed in the transaction overview and it could also be sampled right?

Yes. If you add attributes for request.duration and internal_code, you can do this:

SELECT average(`request.duration`)
FROM Transaction
WHERE appName = 'Your Application'
FACET internal_code

SELECT count(*)
FROM Transaction
WHERE appName = 'Your Application'
FACET internal_code, httpResponseCode

I assume using record_custom_event() will allow me to create graphs but data won’t be displayed in the transaction overview and it could also be sampled right?

Correct. It should not be sampled unless you exceed the ingest limit, which is currently 10,000 events per minute, per host.

The first query works without any problems but in the second query httpResponseCode is always missing.


do you know why is this happening? I found a similar issue here Missing httpResponseCode attribute in Transaction events when updating agent (from 3.30.1 to 4.5.0) - #7 by fgaule

I am not sure why httpResponseCode is missing, but in any case I think I misunderstood your question, and it will not provide what you are looking for. httpResponseCode returns the response code of the transaction; I believe you want to record the response code of the external request. If that is the case, you will need to send the external response code as a custom attribute.

I assumed newrelic will automatically instrument the external get request sent through Net::Http and the httpResponseCode will be basically the result of that request.

If that is the case, you will need to send the external response code as a custom attribute.

Thank you for the explanation :slight_smile: