• Print
  • Share
  • Dark
    Light

Defining Custom Transactions

  • Updated on 02 Aug 2018
  • 3 minutes to read
  • Contributors

By default Retrace only tracks web transactions, however, it can be used to track non web transactions with some minor code changes. This article discusses tracking non web requests and could be applied to background work within a web app, a windows service, console app, or other types of service apps.

You must first configure Retrace to know about and profile your application. By default Retrace only profiles IIS applications. Please review this article on how to tell it to profile your application: Enabling Retrace for non IIS applications

How it works

Tracking custom transactions is done by using the ProfilerTracer object within StackifyLib. This creates a defined operation from start to finish that can be named and tracked as a single operation. Here is a simple code example:

//Create a new ID for the operation for correlation
  Trace.CorrelationManager.ActivityId = Guid.NewGuid();  //name the operation whatever you want
  var tracer = StackifyLib.ProfileTracer.CreateAsOperation("Operation Name", Trace.CorrelationManager.ActivityId.ToString());

  tracer.Exec(() =>   //FYI, async code is also supported via tracer.ExecAsync()
  {
      //Do some stuff here
  });

Key considerations and potential problems

Retrace is designed to track individual transactions, so the transactions should be fairly short in length. If your application has a very long running thread in a loop that never finishes, it is possible that this collection of data could grow continually and use a lot of memory. A good example would be a section of code that is in a never ending loop that runs database queries. You can also prevent this in your own code by using our ProfileTracer object and creating operations. (ProfileTracer.CreateAsOperation) Anytime one of those operations ends, that section of collected data will be processed. If you are having problems getting profiling of a Windows Service to work correctly, feel free to reach out to our support team and will try to help.

What can you track?

Retrace is great for web apps or background apps that do the same "transaction" continually. It isn't designed to track clicks in a desktop application. You can track events that run on a timer, events and more.

You can also enable Retrace for self hosted WCF and Web API apps.

Job Scheduler like Quartz We automatically track some key methods around Quartz jobs so you don't need to StackifyLib.ProfileTracer for Quartz to define the scope of the operations. Instead, you only need to name the jobs by calling SetOperationName, otherwise we will show them all as "Quartz". We also recommend setting the CorrelationManager as shown below. The below code example shows creating a base class that all of your jobs can use so you can put the code in a single place.

using System.Diagnostics;
using Quartz;
using System;

namespace Stackify.JobScheduler
{
    public abstract class BaseJob : IJob
    {
        //method the job needs to implement
        public abstract void ExecuteJob(IJobExecutionContext context);

        public void Execute(IJobExecutionContext context)
        {
            Trace.CorrelationManager.ActivityId = Guid.NewGuid(); //unique id for operation
            StackifyLib.ProfileTracer.SetOperationName("Job-" + this.GetType().Name);
            this.ExecuteJob(context);
        }
    }
}

Processing queue messages

Processing messages off a queue is a perfect example where it makes sense to use a profiler. Retrace keeps your queue processing from being a black box that you have no visibility into. Below are code examples for using our ProfilerTracer with async code to process messages off a Azure Service Bus message pump.

//Psuedo example of code that processes messages of a queue with async

  var options = new OnMessageOptions
  {
      MaxConcurrentCalls = 5,
      AutoComplete = false
  };
  MessagingFactory messagingFactory = null;
  string queue = "";
  QueueClient client = messagingFactory.CreateQueueClient(queue, ReceiveMode.PeekLock);
  client.OnMessageAsync(async m =>
  {
      bool shouldAbandon = false;
      try
      {
          //Create a new ID for the operation for correlation
          Trace.CorrelationManager.ActivityId = Guid.NewGuid();

          //name the operation whatever you want, probably the queue name in this example
          var tracer2 = ProfileTracer.CreateAsOperation("Operation Name",Trace.CorrelationManager.ActivityId.ToString());

          //wrap your code in the ProfileTrace operation
          await tracer2.ExecAsync(() =>
          {
              return ProcessMessageAsync(m);
          });


          // complete if successful processing
          await m.CompleteAsync();
      }
      catch (Exception ex)
      {
          shouldAbandon = true;
          Console.WriteLine(ex);
      }

      if (shouldAbandon)
      {
          await m.AbandonAsync();
      }
  },
  options);

Other event based transactions

There are a lot of scenarios of event based or scheduled services that could be tracked by Retrace. We have already covered a couple common ones like listening to a queue, or using a job scheduler like Quartz. However, there are many other types as well. Some other examples:

  • An app that waits for files to be dropped in a folder
  • An app that utilizes some sort of custom sockets
  • An SMTP mail server
  • Azure Service Bus Relay