New Relic Ruby Agent

repository·dev·Indexed 22 days ago

https://github.com/newrelic/newrelic-ruby-agent

The New Relic Ruby agent monitors Ruby applications to identify performance issues and collect business data. It can be installed as a standard Gem (newrelic_rpm) or as a Rails plugin. The agent includes diagnostic tools such as NRDiag and nrdebug, a CLI for agent commands, and support for Infinite Tracing via gRPC streaming to a Trace Observer.

Tokens
7.5K
Snippets
10
Records
50
Agent score
78%

What's inside newrelic-ruby-agent

  1. Understand Attribute Translation in the New Relic Ruby Agent

    dev

    The New Relic Ruby agent uses attribute translation to map OpenTelemetry (OTel) semantic conventions to New Relic standards. This process ensures that telemetry data sent via OTel is correctly categorized and formatted for New Relic's platform.

    How it works

    1. Identification: When Tracer#start_span is called, NewRelic::Agent::OpenTelemetry::AttributeTranslator.translate is invoked. It uses the instrumentation scope, attributes, span name, and span kind to identify the correct translator.
    2. Translation: The identified translator (e.g., HttpClientTranslator) uses its corresponding AttributeMappings constant to distribute attributes into categories like intrinsic, agent, instance_variable, or custom.
    3. Application: Before the span completes, the agent applies these translated attributes to the New Relic transaction or segment.
    4. Lifecycle Persistence: The translator is assigned as an instance variable on the span. Consequently, any subsequent calls to Span#add_attributes or Span#set_attribute during the span's life will use that same translator to ensure attributes are correctly categorized.

    If no specific translator is identified, a GenericTranslator is used, and all attributes are treated as custom attributes.

  2. Run unit tests using the Dockerfile

    dev

    To run only Ruby-based unit tests without external dependencies (like databases), you can use the project's Dockerfile. This is suitable for standalone development and quick unit testing.

    1. Navigate to the project root.
    2. Build the image with a tag (e.g., newrelic_rpm).
    3. Run the container with the --rm flag to ensure the container is removed after the tests complete.

    You can override the default Ruby version by passing the ruby_version build argument during the build process.

    $ cd /path/to/project/git/clone
    $ docker build -t newrelic_rpm .
    $ docker run --rm newrelic_rpm
    
    # To override the Ruby version:
    $ docker build --build-arg ruby_version=2.7 .
  3. Run functional tests using Docker Compose

    dev

    To run functional tests that require external data services (PostgreSQL, Redis, memcached, etc.), use Docker Compose. This launches multiple containers, including a Ruby "app" container that executes the tests.

    1. Start the services: In one shell session, run docker-compose up from the project root. You can override the Ruby version by setting the RUBY_VERSION environment variable.
    2. Execute tests: In a separate shell session, run the test:all rake task inside the running app container.

    Note: The docker-compose up session will output logs for all services, while the exec session will output the Ruby test results.

  4. Add a new attribute category for translation

    dev

    To support a new category of OpenTelemetry attributes, follow these three steps:

    1. Create the Translator Class: Create a new class in the lib/new_relic/agent/opentelemetry/translators directory. Name the class after the category you wish to translate.
    2. Define Mappings: Update the NewRelic::Agent::OpenTelemetry::AttributeMappings class by adding a new constant that contains the mappings for your new category.
    3. Register the Translator: Update the NewRelic::Agent::OpenTelemetry::AttributeTranslator::TRANSLATOR_REGISTRY constant. Add the conditions (such as instrumentation scope or span kind) that signal your new translator should be used, using your new translator class as the value.
  5. Access an interactive shell in the Ruby app container

    dev

    For development or debugging, you can drop into an interactive Bash shell inside the running Ruby application container managed by Docker Compose. This provides a prompt as the relic user, with ruby and bundle already available in your PATH.

    $ docker-compose exec app bash
  6. Enable Infinite Tracing

    dev

    Infinite Tracing is enabled only when all of the following conditions are met in your New Relic agent configuration:

    1. Distributed Tracing must be enabled (distributed_tracing.enabled).
    2. Span Events must be enabled (span_events.enabled).
    3. A Trace Observer host must be configured via infinite_tracing.trace_observer.host.

    If the Trace Observer host is not configured, the agent will raise a Trace Observer host not configured! error when attempting to construct the URI.

  7. How Infinite Tracing connection management works

    dev

    The NewRelic::Agent::InfiniteTracing::Connection class is a Singleton that manages the gRPC channel and connection to the New Relic collector.

    Key behaviors:

    • Blocking Calls: Calls to the gRPC server are blocked until the agent successfully connects to the collector and retrieves the necessary license_key and agent_run_token (agent ID) from the server-side configuration.
    • Automatic Reconnection: If the collector instructs the agent to reconnect (via the :server_source_configuration_added event), the connection is notified to restart and re-establish its bi-directional streaming with the new metadata.
    • Singleton Pattern: The connection is implemented as a Singleton and is designed to expect only one client instance.
    • Metadata: RPC calls include metadata containing the license_key and agent_run_token. If compression is enabled in the configuration, GZIP metadata is also merged into the request.
  8. Sidekiq Server Instrumentation

    dev

    The New Relic Ruby agent provides automatic server-side instrumentation for Sidekiq. This instrumentation captures Sidekiq jobs as transactions, allowing you to monitor job execution, duration, and errors in New Relic.

    When a Sidekiq job runs, the agent automatically:

    1. Records the instrumentation invocation.
    2. Extracts job arguments and attributes (subject to filtering).
    3. Handles distributed tracing headers if enabled.
    4. Manages transaction separation if configured.

    If the worker class responds to newrelic_trace_args, the agent uses that method to determine transaction metadata. Otherwise, it defaults to using the job class name and the category OtherTransaction/SidekiqJob.

  9. Redis instrumentation requirements and compatibility

    dev

    The New Relic Redis datastore instrumentation requires the redis gem to be present. The agent checks for version compatibility using the following logic:

    • Supported Redis Version: >= 3.0.0
    • Third-party Gem Conflict: The agent will skip installing its own Redis instrumentation if it detects that the third-party newrelic-redis gem is already bundled/present in the environment to avoid conflicts.
  10. Understand AgentCommandRouter command dispatching

    dev

    The AgentCommandRouter is the central component responsible for receiving and dispatching get_agent_commands messages to specific internal handlers. It manages the lifecycle of commands like thread profiling and ensures that command results are reported back to the New Relic service.

    Key capabilities include:

    • Command Dispatching: Maps command names to specific handler procs.
    • Thread Profiling: Handles start_profiler and stop_profiler commands via a thread_profiler_session.
    • Harvesting: Collects and logs thread profiles using the harvest! method.
    • Error Handling: Catches AgentCommandError and returns a result containing the error message.