Create transactions via XML (.NET)

New Relic instruments supported frameworks automatically. However, you may also have other frameworks for which some transactions are not being created automatically or additional methods that you would like to instrument. 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 how to create transactions with an XML file. You can also:

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

Create transactions using XML

Custom transactions (transactions not instrumented automatically) are defined in a custom instrumentation XML file. You define a method that triggers the creation of a transaction. You can also instrument additional methods called by the trigger method.

Some important rules to know before you create a custom transaction:

  • Database and external calls do not require custom instrumentation because they're automatically instrumented.
  • Ensure your XML file is in the correct path. To define its instrumentation set, the .NET agent reads every XML file in the Extensions directory.
  • If a method you attempt to instrument is already part of an existing transaction, it will be added as a segment to that transaction. No new transaction will be created. This will occur even if the parent method is instrumented using custom instrumentation.

To create a custom instrumentation file:

  1. Create a new .xml file in the Extensions directory located in:

    C:\ProgramData\New Relic\.NET Agent\Extensions

    Use the ProgramData directory, not the Program Files directory.

  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.
  4. Optional: To check if the XML file is formatted correctly, you can check it against the XSD (located at C:\ProgramData\New Relic\.NET Agent\Extensions\extension.xsd) using any XSD validator.

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.

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

Recommendations for learning more: