Create transactions via XML (.NET)

New Relic instruments supported frameworks automatically. However, New Relic cannot automatically instrument non-web applications because they do not have an HttpContext object. You may also have a web framework for which some transactions are not being created automatically. You can add custom instrumentation to these methods by creating transactions. Transactions created via XML are classified as non-web in the New Relic UI.

This document describes creating transactions with an XML file. To instead add detail to an existing transaction, see Add detail to transactions via XML. Or, you can both create transactions and add detail to existing transactions with the .NET agent API.

If you have a non-IIS application, XML instrumentation requires enabling of the Instrument all option during the .NET agent install.

Create transactions via XML

"Custom" transactions are defined in a custom instrumentation XML file. You define a method which triggers the creation of a transaction. You can also instrument additional methods called by the trigger method. These additional methods appear in the transaction's breakdown table and in transaction traces. Database and external calls do not need manual instrumentation, because they are automatically instrumented by the agent.

To create a custom instrumentation file:

  1. Create a new .xml file in the extensions directory. The .NET agent reads every xml file in this extensions directory to define its instrumentation set. The file is located in:

    C:\ProgramData\New Relic\.NET Agent\Extensions
  2. Copy this template into the file you created:

    <?xml version="1.0" encoding="utf-8"?>
    <extension xmlns="urn:newrelic-extension">
      <instrumentation>
        <!-- Define the method which triggers the creation of a transaction. -->
        <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Category/Name">
          <match assemblyName="AssemblyName" className="NameSpace.ClassName">
            <exactMethodMatcher methodName="MethodName" />
          </match>
        </tracerFactory>
        <!-- Instrument 0 or more methods called by the trigger method. These methods appear in the transaction breakdown table and in transaction traces. -->
        <tracerFactory metricName="Category/Name">
          <match assemblyName="AssemblyName" className="NameSpace.ClassName">
            <exactMethodMatcher methodName="MethodName" />
          </match>
        </tracerFactory>
      </instrumentation>
    </extension>
  3. In the file you created, customize the attribute values Category/Name, AssemblyName, NameSpace.ClassName, and MethodName. Customize these values for both the trigger method and for any methods called by the trigger method.
    • Category/Name: Defines the transaction type. The New Relic UI groups transactions under these names in the transaction type field. The category and name must both be specified, and must be separated by a slash.
    • AssemblyName: The assembly that contains the trigger method.
    • NameSpace.ClassName: The fully-qualified class name that contains the trigger method.
    • MethodName: The exact name of the trigger method.

Do not use brackets [suffix] at the end of your transaction name. New Relic automatically strips brackets from the name. Instead, use parentheses (suffix) or other symbols if needed.

View transactions in the UI

The custom transaction starts when the method specified by methodName is invoked in the assembly specified by assemblyName. The transaction ends when the method returns or throws an exception.

You can view these metrics in the Transactions page and in transaction traces. To view the transaction: Go to rpm.newrelic.com/apm > (select an app) > Monitoring > Transactions > Type > (select a type). The type is defined by Category/Name.

screen-custom-transactions-rpm
rpm.newrelic.com/apm > (select an app) > Monitoring > Transactions > Type > (selected type): Use the Type menu to view your custom transactions.

Example: Instrument three methods

This example presents a simple implementation of creating transactions. For an example of asynchronous methods, see .NET custom instrumentation.

Example custom instrumentation file

This custom instrumentation file defines the three methods to instrument:

<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
  <instrumentation>
    <!-- Define the method which triggers the creation of a transaction. -->
    <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Background/Bars">
      <match assemblyName="Foo" className="Foo.Bar">
        <exactMethodMatcher methodName="Bar1" />
        <exactMethodMatcher methodName="Bar2" />
      </match>
    </tracerFactory>
    <!-- Instrument 0 or more methods called by the trigger method. These methods appear in the transaction breakdown table and in transaction traces. -->
    <tracerFactory>
      <match assemblyName="Foo" className="Foo.Bar">
        <exactMethodMatcher methodName="Bar3" />
      </match>
    </tracerFactory>
  </instrumentation>
</extension>
Example methods to be instrumented

This code contains the three methods, with comments explaining when each one will be instrumented by the agent:

var bar = new Bar();
bar.Bar1(); // Creates a transaction named Bars in the Background category.
bar.Bar2(); // Creates a transaction named Bars in the Background category.
bar.Bar3(); // Won't create a new transaction. See `If Bar3 is called directly`, below.

namespace Foo
{
    public class Bar
    {
        // The agent creates a transaction that includes an external service request in its transaction traces.
        public void Bar1()
        {
            new WebClient().DownloadString("http://www.google.com/");
        }
 
        // Creates  a transaction containing one segment.
        public void Bar2()
        {
            // The Bar3 segment will contain your SQL query inside of it and possibly an execution plan.
            Bar3();
        }
 
        // If Bar3 is called directly, the agent will not create a transaction.
        // However, if Bar3 is called from Bar1 or Bar2, Bar3 will appear as a segment containing its SQL query.
        private void Bar3()
        {
            using (var connection = new SqlConnection(ConnectionStrings["MsSqlConnection"].ConnectionString))
            {
                connection.Open();
                using (var command = new SqlCommand("SELECT * FROM table", connection))
                using (var reader = command.ExecuteReader())
                {
                    reader.Read();
                }
            }
        }
    }
}

Example: Instrument a console app

This simple console app demonstrates creating transactions. After running the application a few times, you see the transactions you created in the Transactions page (at rpm.newrelic.com/apm > (select an app) > Transactions > Type). The Dummy segment will be visible in the transactions breakdown table and in any transaction traces.

Example custom instrumentation file

This custom instrumentation file defines two methods to instrument:

<?xml version="1.0" encoding="utf-8"?>
<extension xmlns="urn:newrelic-extension">
    <instrumentation>
        <!-- Define the method which triggers the creation of a transaction. -->
        <tracerFactory name="NewRelic.Agent.Core.Tracer.Factories.BackgroundThreadTracerFactory" metricName="Background/CustomTransaction">
          <match assemblyName="ConsoleApplication1" className="ConsoleApplication1.CustomTransaction">
            <exactMethodMatcher methodName="StartTransaction" />
          </match>
        </tracerFactory>
        <!-- Instrument 0 or more methods called by the trigger method. These methods appear in the transaction breakdown table and in transaction traces. -->
        <tracerFactory>
          <match assemblyName="ConsoleApplication1" className="ConsoleApplication1.CustomTransaction">
            <exactMethodMatcher methodName="Dummy" />
          </match>
        </tracerFactory>
    </instrumentation>
</extension>
Example app

This code contains the two methods specified by the custom instrumentation file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Custom Transactions");
            var t = new CustomTransaction();
            while (true)
                t.StartTransaction();
        }
    }
    class CustomTransaction
    {
        public void StartTransaction()
        {
            Console.WriteLine("StartTransaction");     
            Dummy();
        }
        void Dummy()
        {
            System.Threading.Thread.Sleep(5000);
        }
    }
 
}

For more help

Additional documentation resources include:

Recommendations for learning more: