Author image 🦖🦜Graham Ollis🦃🦕


NewRelic::Agent::FFI - Perl Agent for NewRelic APM


version 0.03


 use NewRelic::Agent::FFI;
 my $agent = NewRelic:Agent::FFI->new(
   license_key => 'abc123',
   app_name    => 'REST API',
 my $txn_id = $agent->begin_transaction;
 my $err_id = $agent->end_transaction($txn_id);


NOTE: This module is deprecated. It is based on the NewRelic Agent SDK, which was only ever released as beta software. Please use NewFangle instead.

This module provides bindings for the NewRelic Agent SDK.

It is a drop in replacement for NewRelic::Agent that is implemented using FFI::Platypus instead of XS and C++. If you are writing new code, then I highly recommend the procedural interface instead: NewRelic::Agent::FFI::Procedural.

Why use NewRelic::Agent::FFI module instead of NewRelic::Agent?

Powerful Alien technology

This module uses Alien::nragent to either download the NR agent or to use a locally installed copy. The other module has a serious bug which will break when the install files are removed! You can choose the version of the NR SDK that you want to use instead of relying on the maintainer of NewRelic::Agent to do so.

Possible license issues

Related to the last point, the other module bundles the NR SDK, which may have legal risks (I am not a lawyer). In the very least I think goes against the Open Source philosophy of CPAN.

No C++ compiler required!

Since this module is built with powerful FFI and Platypus technology, you don't need to build XS bindings for it. The other module has its bindings written in C++, which is IMO unnecessary and doesn't add anything.


The test suite for NewRelic::Agent is IMO insufficient to have confidence in it, especially if the SDK needs to be upgraded. This module comes with a number of tests that will at least make sure that the calls to NewRelic will not crash your application. The live test can even be configured (not on by default) to send data to NR so that you can be sure it works.

Active Development

At least as of this writing, this module is being actively developed. The other module has a number of unanswered open issues, bugs and pull requests.

Why use the other module instead of this one?

This module is newer

The other module has been around for longer, and may have been used in production more. Peoples will probably have noticed if it were broken by now.



 my $agent = NewRelic::Agent::FFI->new(%options);

Instantiates a new NewRelic::Agent client object. Options include:


A valid NewRelic license key for your account.

This value is also automatically sourced from the NEWRELIC_LICENSE_KEY environment variable.


The name of your application.

This value is also automatically sourced from the NEWRELIC_APP_NAME environment variable.


The language that your application is written in.

This value defaults to perl, and can also be automatically sourced from the NEWRELIC_APP_LANGUAGE environment variable.


The version of the language that your application is written in.

This value defaults to your perl version, and can also be automatically sourced from the NEWRELIC_APP_LANGUAGE_VERSION environment variable.


Methods noted below that return $rc return 0 for success or non-zero for failure. See the NR SDK documentation for error codes.



Embeds the collector agent for harvesting NewRelic data. This should be called before init, if the agent is being used in Embedded mode and not Daemon mode.


 my $rc = $agent->init;

Initialize the connection to NewRelic.


 my $tx = $agent->begin_transaction;

Identifies the beginning of a transaction, which is a timed operation consisting of multiple segments. By default, transaction type is set to WebTransaction and transaction category is set to Uri.

Returns the transaction's ID on success, else negative warning code or error code.


 my $rc = $agent->set_transaction_name($tx, $name);

Sets the transaction name.


 my $rc = $agent->set_transaction_request_url($tx, $url);

Sets the transaction URL.


 my $rc = $agent->set_transaction_max_trace_segments($tx, $max);

Sets the maximum trace section for the transaction.


 my $rc = $agent->set_transaction_category($tx, $category);

Sets the transaction category.


 my $rc = $agent->set_transaction_type_web($tx);

Sets the transaction type to 'web'


 my $rc = $agent->set_transaction_type_other($tx);

Sets the transaction type to 'other'


 my $rc = $agent->add_transaction_attribute($tx, $key => $value);

Adds the given attribute (key/value pair) for the transaction.


 my $rc = $agent->notice_transaction_error($tx, $exception_type, $error_message, $stack_trace, $stack_frame_delimiter);

Identify an error that occurred during the transaction. The first identified error is sent with each transaction.


 my $rc = $agent->end_transaction($tx);


 my $rc = $agent->record_metric($key => $value);

Records the given metric (key/value pair). The $value should be a floating point.


 my $rc = $agent->record_cpu_usage($cpu_user_time_seconds, $cpu_usage_percent);

Records the CPU usage. $cpu_user_time_seconds and $cpu_usage_percent are floating point values.


 my $rc = $agent->record_memory_usage($memory_megabytes);

Records the memory usage. $memory_megabytes is a floating point value.


 my $seg = $agent->begin_generic_segment($tx, $parent_seg, $name);

Begins a new generic segment. $parent_seg is a parent segment id (undef no parent). $name is a string.


 my $seg = $agent->begin_datastore_segment($tx, $parent_seg, $table, $operation, $sql, $sql_trace_rollup_name);

Begins a new datastore segment. $parent_seg is a parent segment id (undef no parent).


 my $seg = $agent->begin_external_segment($tx, $parent_seg, $host, $name);

Begins a new external segment. $parent_seg is a parent segment id (undef no parent).


 my $rc = $agent->end_segment($tx, $seg);

End the given segment.


 my $key = $agent->get_license_key;

Get the license key.


 my $name = $agent->get_app_name;

Get the application name.


 my $lang = $agent->get_app_language;

Get the language name (usually perl).


 my $version = $agent->get_app_language_version;

Get the language version.


Platform Limitations

The SDK binaries provided by New Relic only work on Linux x86_64. The binaries are labeled as a "beta" and were released in July 2016. It doesn't seem likely that New Relic will be releasing new versions of the SDK. The author of this module has had good success getting this module to work on Ubuntu Precise and Xenial, and heard from user feedback that it works with Bionic. I have heard that it does NOT work with CentOS 7. Your mileage may vary.

Not Fork Safe!

Bad things will happen if you call init before forking. So don't do that.



Procedural interface, recommended over this one.


Graham Ollis <>


This software is copyright (c) 2019 by Graham Ollis.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.