Service-oriented architecture (SOA) is a design pattern that has gradually encompassed a large portion of the software that we use and that we, as software engineers, create. Wikipedia defines SOA as:

"a software design ... based on distinct pieces of software providing application functionality as services to other applications."

Many enterprises have re-designed their applications by separating functional units into services, as shown below. These services could be separately hosted on the same or different machines.

Service-Oriented Application

In the .NET ecosystem, Windows Communication Foundation (WCF) has acted as a swiss army knife of service-enabling features for .NET developers. You can configure a WCF service application so that it can be called from internal administrative tools using TCP bindings as well as for secure communication over HTTPS for web applications. WCF has served as an important bridge for traditional client-server applications and monolithic applications migrating toward the more agile service-oriented architectures of today.

Our .NET agent, which has historically done a great job monitoring web applications, has had limited support for WCF services hosted within a web application, but only if your application ran in WCF's ASP.NET Compatibility Mode. This mode allows web service method calls to be handled within the ASP.NET pipeline, rather than through the WCF service stack. The reason that the .NET agent worked with compatibility mode was because the agent relied on the ability of the ASP.NET pipeline’s HttpContext object to follow a web request across threads.

Last week we released version 3.2.113.0 of the .NET agent, which includes much greater support for WCF services! This new version includes support for:

  • Self-hosted WCF services
  • Internet Information Server (IIS)-hosted WCF services with or without ASP.NET Compatibility Mode
  • WCF service request parameters, so that you can view and filter parameters from view in New Relic

The following is a review each of these points to show you how to get greater value from using New Relic to monitor your service-oriented applications.

Self-Hosted WCF Services

Although IIS provides a lot of host management features, depending on the purpose of a service or the institutional policies around the use of IIS some developers will choose to host their services in either a custom Windows Service, a console app or Windows Forms application.

To take advantage of the .NET agent’s ability to monitor these self-hosted services, you will want to select Instrument All .NET Applications in the agent installer:

.Net Agent Installer

Once the installation is complete, you have to let the agent know that a specific process should be instrumented. We require this to avoid introducing unnecessary loading of the agent into non-web applications that you do not need to monitor. There are a couple of simple ways to accomplish this:

  • Adding an section to the newrelic.config file

    
    
    <instrumentation>
    
        <applications>
    
          <application name="BusinessLogicServices.exe" />
    
          <application name="DataServices.exe" />
    
        </applications>
    
    </instrumentation>
    
    
    
    

    newrelic.config

  • Or, adding an application setting in your process’ configuration file.

    
    
    <?xml version="1.0" encoding="utf-8"?>
    
    <configuration>
    
      <appSettings>
    
        <add key="NewRelic.AgentEnabled" value="true" />
    
      </appSettings>
    
    
    
    

    BusinessLogicServices.exe.config

At New Relic, we’re really excited about the .NET agent’s ability to monitor self-hosted WCF services. In addition to providing a feature that you’ve let us know is so important, we have begun to evolve the .NET agent architecture in such a way that will allow us to more quickly support newer technologies with the same standard of reliability. I’ll now explain what we’ve done for WCF support.

Prior to version 3.2.113.0, the .NET agent was not able to reliably instrument self-hosted WCF service applications, as WCF services use a different context object from standard ASP.NET web applications.

ASP.NET web applications use the HttpContext to identify a request. WCF, on the other hand, uses the ObjectContext (defined in the System.ServiceModel assembly). Just as an ASP.NET web request can execute on multiple thread-pool threads, with the HttpContext following the request, a WCF service request can execute across multiple threads and the OperationContext will follow the request. This built-in behavior is frequently referred to as thread agility.

Our .NET agent now uses either the HttpContext and the OperationContext for storing information about the current transaction, and thus is able to give you web transaction support for your WCF services, wherever they are hosted. If, for example, you have a service endpoint defined in your project as:



[ServiceContract]

public interface IWcfService

{

    [OperationContract]

    string GetData (string value, int amount, string url, bool isCorrect);



    [OperationContract]

    CompositeType GetDataUsingDataContract (CompositeType composite);

}



When the service is hit by client traffic, you would see the following appear under Transactions:

WCF Transaction

Sounds good, but how does this relate to the evolving the .NET agent architecture? To support different contexts in which a transaction can run, we planned for the future by adding Providers for each separate Transaction Context. .NET developers are familiar with the Provider model. An example of where we see it is the database realm, where each vendor delivers a Database Provider for the .NET stack.

Beginning with this release, the .NET agent supports a Provider model for Transaction Context Providers. Only providers developed by New Relic are currently supported, but, in the future, we fully expect to publish instructions for customer-created providers. We will also be expanding on our list of Provider types, but more on that in a later blog post. This agent release includes three providers: one for ASP.NET’s HTTP pipeline, one for WCF’s Operation Context and an internal default context provider that uses a thread static storage model.

IIS-hosted Services

The first iteration of web services that Microsoft’s .NET Framework supported was called ASMX Services, which were predominantly hosted in IIS and could take advantage of the many runtime services of the ASP.NET pipeline. When Microsoft released WCF in .NET 3.5, they removed many of the restrictions of ASMX, such as requiring HTTP transport, by building WCF as a highly-configurable services framework.

The ASP.NET Compatibility Mode that I referred to earlier was created to ease the work of ASMX service developers who were transitioning over to the more flexible WCF model. Since ASMX services used the ASP.NET pipeline and its HttpContext object, using the compatibility mode gave devs the same web infrastructure with which to build their services.

The .NET agent continues to support WCF services running in compatibility mode but now has support for services running within IIS but without ASP.NET Compatibility Mode. The difference is that, without compatibility mode, a web service request uses the WCF OperationContext instead of the HttpContext object, even in IIS.

Here is a Transaction Trace showing an IIS-hosted WCF service running with compatibility mode turned off:

WCF Transaction Trace CompatabilityOff

WCF Service Request Parameters

Within WCF is an XML-based messaging framework that provides for a wide range of interoperability options. This messaging framework uses XML and heavily relies on Simple Object Access Protocol (SOAP) versions 1.1 and 1.2. When a service method is called, the method name, parameters and metadata is passed over the wire, using whatever transport is supported (be it HTTP, TCP or even Named Pipes), and is then decoded into a message object in the WCF channel stack (see the figure below).

WCFRuntimeChannelStack

After a service call has made its way up the channel stack, the WCF Dispatcher is called upon to dispatch the call to the actual service method. It is in this dispatcher that the .NET agent captures the parameters of the service method and records them as Service Request Parameters.

Since the capture and display of Service Request Parameters is new in this release, we want to make sure you aren’t caught by surprise and find your sensitive parameter data traveling over the wire to New Relic servers and shown in APM. So, we disable the capture of these parameters by default. You can enable them, as well as have the agent ignore selected parameters by name (in which case we will not capture them) by adding this section to your newrelic.config file's <parameterGroups> section. An example parameter named "password" is shown.



<parameterGroups>

  <serviceRequestParameters enabled="true">

    <ignore>password</ignore>

  </serviceRequestParameters>



As shown below, when you look at Service Request parameters within a Transaction Trace in APM, the parameter name password is not captured (we report it as being filtered out). The other parameters are captured and displayed because the configuration option for the Service Request parameters has been enabled.

WCF Trace SRP Enabled

Wrapping Up

In summary, the latest release of the .NET agent allows you to get transactions for your WCF services, whether they be hosted in IIS or in a self-hosted process. If you choose, you can also view the parameter values passed to those services in your Transaction Traces.

We hope this release is helpful! Let us know if you have any comments or feedback in the .Net Agent section of our Community Forum.