Introduction to the New Relic Agent SDK

Deprecated
Do not use

This is deprecated beta software and should not be used. If you are a current user of the APM Agent SDK and are interested in participating in the private beta for the C agent, contact Jodee Varney (Product Manager) at jvarney@newrelic.com.

Early access to this limited beta release allows you to view web transactions, but the APM Agent SDK intentionally does not support the full capabilities of standard APM agents.

Contents

Compatibility and requirements

The Agent SDK helps you use New Relic to gain visibility into application performance for apps that were not written in one of our supported languages. Make sure your app meets these requirements.

Requirements

As a standard security measure for data collection, New Relic requires that your application server supports SHA-2 (256-bit). SHA-1 is not supported.

Category Requirements
Language

The instructions in this tutorial assume your application is written in C or C++. If you are not using C or C++, then you will need to create a wrapper around the APIs.

How to create your wrapper will vary from language to language. For example, with perl you can use SWIG or XS. Other languages have direct support for calling native functions.

Operating system and compiler support

The SDK only supports 64 bit Linux at this time.

The SDK libraries for build environments use glibc 2.12 or higher. If you need a release built using an older version of glibc, create a request via the standard support channels.

Libraries

You will need to install:

  • Boost, because although the SDK statically links to boost, boost itself dynamically links to the rt and pthreads libraries.
  • cURL, because the SDK uses libcurl for http requests (for supported versions, see the Libraries table, below).
Libraries

The SDK dynamically links to the openssl and cURL libraries. The SDK works with the following libraries:

Library Compiled against Known to work
libopenssl 1.0.2a 1.0.0r, 1.0.1e, 1.0.1m
libcurl 7.39.0 7.19.0
Thread safety

Some portions of the Agent SDK's transaction library are thread-safe, while others are not. The following activities should be considered thread-safe:

  • Starting transactions on different threads
  • Starting, modifying, and ending segments on different threads for different transactions

The following activities should not be considered thread-safe:

  • Modifying and ending a single transaction from different threads
  • Starting, modifying, and ending segments on different threads within the same transaction

Security considerations

Security considerations for the APM agent SDK include:

HTTPS communication

By default, the Agent SDK enables HTTPS for communication between the SDK and New Relic. However, developers are responsible for obfuscating or hiding any sensitive data that should not appear in the New Relic UI. For example, you may want to hide certain parameters inside a request URL or database query. For more information, see Obfuscating query data.

Naming considerations

Use caution when naming custom metrics, transactions, and segments. Issues come about when the granularity of names is too fine, resulting in metric explosion, which can impact the performance of both your application and New Relic. Your application may also get blacklisted. For more information, including best practices, see Metric grouping issues.

Install and configure

Before you install the agent SDK, make sure you meet the compatibility and requirements.

Installing the agent SDK

The Agent SDK consists of three C++ libraries and three C header files. To install the SDK:

  1. Download the SDK to your development machine (Linux only).
  2. Unzip nr_agent_sdk-<version>-beta.<architecture>.tar.gz to a working directory.
  3. For instructions on implementing the Agent SDK, read the AgentSDK.pdf included in the download.

New Relic's public repo on Github includes Agent SDK sample wrappers and code.

Customizing your log4cplus files

The New Relic Agent SDK uses log4cplus for logging. This provides flexibility into log levels, log file locations, etc.

The SDK searches for a log4cplus.properties file in this order:

  1. The location specified by NEWRELIC_LOG_PROPERTIES_FILE environment variable
  2. Your $HOME/.newrelic directory
  3. The current working directory

To configure logging:

  1. Copy the config/log4cplus.properties file to one of the locations specified above.
  2. Optional: Modify the log4cplus.properties file by following the instructions at http://sourceforge.net/p/log4cplus/wiki/Home/.
Reviewing log files

All functions in the SDK return integers or longs. Any positive number indicates success and any negative number indicates a failure. For a list of all error codes, see the New Relic header files for a list of all error codes.

Instrumenting your code

To measure transactions and important segments of code in your application:

  1. Include the newrelic_transaction.h and newrelic_common.h header files.
  2. Link your application to the libnewrelic-transaction and libnewrelic-common libraries.
  3. Create a transaction; for example:

    long transaction_id = newrelic_transaction_begin();
  4. Optional: Set a name for the transaction any time before the transaction ends. For example:

    int return_code = newrelic_transaction_set_name
        (
        transaction_id,
        "create_account"
        );
        
  5. Measure segments; for example:

    long segment_id = newrelic_segment_generic_begin
        (
        transaction_id,
        parent_id,
        "check_if_account_exists"
        );
        <call check_if_account_exists>
        int return_code = newrelic_segment_end
        (
        transaction_id,
        segment_id
        );
        
  6. Optional: If this is not a web transaction, set the transaction type any time before the transaction ends. For example:

    newrelic_transaction_set_type_other(transaction_id);
  7. End your transaction; for example:

    int error_code = newrelic_transaction_end(transaction_id);
  8. Start your app, and then wait a few minutes to start seeing data in your New Relic dashboards.
Limiting or disabling Agent SDK settings

The New Relic Agent SDK is designed to have a minimal impact on your system's performance. However, in addition to the default settings, you can use these controls to limit or disable data collection.

If you want to... Use this setting...
Disable data collection during a transaction
newrelic_enable_instrumentation(0);

If you are running a web server that spawns off new processes per transaction, you may need to call this for every transaction.

Shut down the agent
  • If running in embedded-mode:

    newrelic_request_shutdown(“reason for shutting down…”);
  • If running in daemon mode:

    Stop the newrelic-collector-client-daemon process.

Configure transaction trace thresholds
newrelic_transaction_set_threshold(transaction_id, 5000);

If you are running a web server that spawns off new processes per transaction, you may need to call this for every transaction.

Configure the number of trace segments collected in a transaction trace

// Only collect up to 50 trace segments
newrelic_transaction_set_max_trace_segments(transaction_id, 50);

If you are running a web server that spawns off new processes per transaction, you may need to call this for every transaction.

Configure usage mode

After you install the New Relic Agent SDK, update your configuration so that your agent can run in the appropriate usage mode (daemon-mode or embedded-mode).

Choosing a usage mode

In order to maintain communication with New Relic, the Agent SDK requires a thread to be started that harvests data once per minute. This means that your app will need to be able to start a thread that runs continuously as long as transactions are being executed.

For some languages, this is simple to do. For others, there is no mechanism to start a thread within the same process running your web transactions. For example, if you are running perl apps through Apache, then each perl script is a short-lived process that exits upon completion of the script. There is no ability to start up a thread that lives beyond the life of the script.

To solve this problem, New Relic designed the SDK so that your agent can run in two different modes: daemon-mode or embedded-mode.

  • In daemon-mode you will run the newrelic-collector-client-daemon that came with the Agent SDK as a standalone process. The daemon will collect and send data to New Relic.
  • In embedded-mode your application will start a thread that has the same responsibilities as the daemon. However, it will run within the same process as your transactions.
Using Agent SDK environmental variables

Adjust these values in your configuration as applicable for your selected mode (daemon-mode or embedded-mode).

NEWRELIC_LICENSE_KEY (required for daemon-mode)

Format: <your license key>

NEWRELIC_APP_NAME (required for daemon-mode)

Format: "Hello World"

NEWRELIC_APP_LANGUAGE (required for daemon-mode)

Format: "Perl"

NEWRELIC_APP_LANGUAGE_VERSION (required for daemon-mode)

Format: 5.18.2

NEWRELIC_ENABLE_SSL

Format: 0 (disabled) or 1 (enabled, default)

Required for daemon-mode: No

NEWRELIC_ENABLE_HIGH_SECURITY

Format: 0 (disabled, default) or 1 (enabled)

Required for daemon-mode: No

NEWRELIC_LOG_PROPERTIES_FILE

Format: <path/to/log4cplus.properties>

For example:

  • ~/.newrelic
  • <current working dir>

Required for daemon-mode: No

NEWRELIC_APP_SERVER_APDEX_T

Format: 0.25 (default is 0.5)

Required for daemon-mode: No

http_proxy

Format: "http://<name>:<passwd>@<proxy>:<port>"

Required for daemon-mode: No

Running in daemon-mode

The SDK daemon will run with the privileges of the application starting it, which may be elevated. For example, if the daemon is started by Apache, it may run as root.

  1. Set the required environment variables before launching the daemon, including:

    
    	export NEWRELIC_LICENSE_KEY=<your license key>
    	export NEWRELIC_APP_NAME="Hello World"
    	export NEWRELIC_APP_LANGUAGE="Perl"
    	export NEWRELIC_APP_LANGUAGE_VERSION="5.5"
    	

    Start the daemon by executing the following command in a terminal window:

    ./newrelic-collector-client-daemon
  2. Start your app, and then wait a few minutes to start seeing data in New Relic.
Running in embedded-mode

To run in embedded-mode, embed the collector client in your app by following these steps:

  1. Include the newrelic_collector_client.h and newrelic_common.h header files.
  2. Link your application to the libnewrelic-common and libnewrelic-collector-client libraries.
  3. Optional: Create a function to receive status change notifications. For example:

    
        void newrelic_status_update(int status)
        {
        if (status == NEWRELIC_STATUS_CODE_SHUTDOWN)
        {
        // do something when the agent shuts down
        }
        }
        newrelic_register_status_callback(newrelic_status_update);
        
  4. To send data to New Relic when transactions are completed, register a callback that has already been defined inside the libnewrelic-collector-client library:

    newrelic_register_message_handler(newrelic_message_handler);
  5. Initialize the library. For example:

    
        newrelic_init
        (
        my_license_key_string,
        "Hello World", 
        "Perl", 
        "5.5"
        );
        
  6. Optional: Shut down the connection to New Relic. For example:

    
        newrelic_request_shutdown("insert your reason here");
        
  7. Start your app, and then wait a few minutes to start seeing data in New Relic.

Using the Agent SDK

Here is an overview of how to use the Agent SDK with some of the standard features of any other New Relic agent. It is not intended to be a comprehensive description of all the features and functions available to you.

Viewing transaction traces

New Relic APM automatically generates traces when transactions exceed the threshold, which defaults to two seconds. A maximum of two traces will be sent to New Relic per minute. To modify the threshold for any of your application's transactions, change your Apdex settings.

Recording and viewing custom metrics

Custom metrics give you a way to record arbitrary metrics about your application. You can also instrument your code, which will report performance metrics automatically whenever that code is executed. With a custom metric, you provide the value to be recorded for a specified metric name; for example:

newrelic_record_metric("ActiveUsers", 25);

To view custom metrics, create a custom dashboard.

Obfuscating query data

A query trace is automatically generated for each Datastore segment. Every minute the agent sends several of these traces to New Relic APM. The selected traces will represent the worst performing query statements during that minute.

Your database code may contain sensitive information that you do not want or need to send to New Relic APM. By default, the Agent SDK obfuscates your query strings. It uses a basic literal replacement obfuscator that strips the string literals and numeric sequences, and then replaces them with the ? character. For example:

SELECT * FROM table WHERE ssn=‘000-00-0000’

Obfuscates to:

SELECT * FROM table WHERE ssn=?

For more information, see Security options for transaction traces.

Because New Relic's default obfuscator only replaces literals, there could be cases that it does not handle well. For example:

  • Default obfuscation will not strip out comments from your query string.
  • Default obfuscation will not handle certain database-specific language features.
  • Default obfuscation could fail for other complex cases.

If this level of obfuscation is not sufficient, you can supply your own custom obfuscator.

Measuring customer satisfaction (Apdex T)

Apdex T is the response time threshold used to measure customer satisfaction. The transaction trace threshold is calculated as four times the Apdex T value. The default Apdex T value is 0.5 seconds.

To change the Apdex T value across all transactions of your application, use the environment variable NEWRELIC_APP_SERVER_APDEX_T. If you do not set this environment variable, New Relic uses the default.

To change the Apdex T for a specific transaction, create a key transaction.

Known limitations

This summarizes the APM agent SDK's known limitations and bugs.

Keep track of shared data (parent IDs)

In order to build a transaction trace, you need to provide information to the SDK about the relationships between segments. To accomplish this, your agent needs to pass parent IDs when starting new segments. Depending on your language, you might be able to take advantage of the SDK's auto-scoping feature.

Auto-scoping can be used to automatically identify the transaction ID and parent ID of a newly started segment. It works by keeping track of the last segment started within the current thread (using thread local storage). This is useful, for example, when a transaction runs uninterrupted from beginning to end within the same thread. For more information about threading considerations, see the threading section below.

If auto-scoping does not work, you will need to find a way to keep track of the current call stack. A simple way to do this is to keep a stack of segment IDs in memory. When a new segment starts, add it to the stack. When a segment ends, remove it from the stack. The challenge then becomes one of identifying where to store the stack. Here are some options:

  • You can use a global web context object if your language supports it.
  • You can use thread local storage.
  • You can create a global map of running transactions.

Recommendation: For segments at the transaction's root, set the parent_segment_id to NEWRELIC_ROOT_SEGMENT.

Name transactions

Recommendation: Name the transactions based on their purpose, but use caution.

Issues arise when the granularity of the transaction name is too fine. This results in hundreds if not thousands of different transactions. If you name transactions poorly, your application may get blacklisted due to too many metrics being sent to New Relic.

A basic rule is to name transactions based on the controller action rather than the URL. For more information, see Metric grouping issues.

Threading considerations

Different languages support different threading models. Depending on the characteristics of your threading model, you will need to consider how your threads will interact with the SDK.

Threading scenarios Comments
Simple case In some languages, all segments of a transaction occur within the same thread. Additionally, a transaction will run from start to finish on the thread before another transaction begins on the same thread. This threading model is fully supported by the SDK.
Multiplexing Some languages are single threaded but can support multiple "simultaneous" transactions. In these languages, when a routine is blocked on I/O, it can be switched out in favor of a different routine on the same thread. The SDK should work in this scenario if you keep track of transaction IDs and parent IDs.
Multi-threading within a single transaction The SDK does not currently support segments occurring on different threads simultaneously within the same transaction. For more information, see thread safety.
Send events to Insights

Transaction events are not reported to Insights, and the SDK does not provide an API call to report custom events to Insights. You must insert custom events via the Insights API.

Known bugs

Known bugs in the New Relic Agent SDK include:

  • You will see an error page if you select Settings directly from Applications > (selected app).
  • You will also see an error page if you select Settings > Application.

For more help

This is deprecated software and should not be used. If you are a current user of the APM Agent SDK and are interested in participating in the private beta for the C agent, contact Jodee Varney (Product Manager) at jvarney@newrelic.com.