Author Archive

I was up at Penn State IST school this past week giving a lecture to a class as part of our recruiting. As part of the class, which was about application integration, I touched on the HTTP protocol. I believe that it’s extremely important that everyone starting out in web application programming or web-based integration have a deep knowledge of the HTTP protocol. Although you should eventually read a book about HTTP and ultimately read the protocol itself, sometimes it’s easier to learn by tinkering. Along these lines, I thought it would be interesting to provide a quick demo of using Fiddler to inspect the HTTP protocol. I’ve included the screencast here. My apologies for the speed of the screencast. I was in a hurry to get it done and it sounds like I had an energy drink of five too many when I did the voice-over.

I used Camtasia for Mac to record the screencast. Camtasia for Mac is a relatively new entrant to the marketplace and is priced at $99 to compete directly with Screenflow, the long time incumbent in the Mac screencast market. The tool couldn’t be easier to use. It took no time at all to capture the screencast and post-capture editing, an area where Camtasia has always shined, is both powerful yet incredibly intuitive. If you’re in the market for a Mac screencasting tool, I can only recommend Camtasia. You can pick up a free 30 day trial and, after that, $99 introductory pricing will get you the full product.

Comments No Comments »

Performance counters for WCF have been available ever since the first release of WCF with the .NET 3.0 Framework. As long as these counters have been available, Microsoft has been cautioning about the memory requirements and potential performance degradation associated with insufficient shared memory allocation. I thought that I had heard at the PDC that WCF 4 would fix some of this but going back to the WCF session video, it looks as if these counters won’t really be addressed by WCF 4 but instead superseded by the ETW instrumentation present in AppFabric. So, until everyone moves to AppFabric, I see a need for a bit more guidance than the “allocate enough memory” that Microsoft offers us.

Enabling WCF Performance Counters

Enabling WCF performance counters is a breeze and is covered pretty well elsewhere.  The configuration change below will turn on all three types of WCF counters: Endpoint, Operation, and Service.

<configuration>
    <system.serviceModel>
        <diagnostics performanceCounters="All" />
    </system.serviceModel>
</configuration>

Your options for enabling the counters are: All, ServiceOnly, and Off. WCF performance counters are included for a reason so I wouldn’t recommend disabling them entirely. Instead, as a rule of thumb you should enable “All” if you’re performing specific service debugging activities that require all the counters and should leave on “ServiceOnly” for normal operations, including in a production environment.

Calculating Performance Counter Memory Size

Before diving into sizing, it’s best to provide a bit of background on performance counter memory allocation. Managed performance counters consume memory that is shared across all the .NET processes running on a machine; essentially a memory-mapped file. Although the .NET Framework 1.0 and 1.1 used global shared memory, .NET 2.0 and above use separate shared memory per performance counter category, with each category having a default size of approximately 128KB (that is ¼ the default global shared memory).

You also need to know about services, endpoints, operations – the WCF counter groups:

  • Services. Services are at the root of the WCF hierarchy. Services can have multiple endpoints and expose multiple operations. WCF has 33 performance counters for each service
  • Endpoints. WCF endpoints provide the client access to a service through address, binding, and contract. You can provide multiple endpoints per service. WCF has 19 performance counters for each instance of an endpoint across a service.
  • Operations. A WCF service operation is a discrete function performed by a WCF service. WCF provides 15 performance counters: per endpoint, per service.

What you’re ultimately looking to come up with is a sizing for each one of the WCF performance counter categories. Without providing a mathematical formula, I’ll walk through a brief hypothetical example to calculate the sizes. In this example, I’ll assume that we have 20 services on a machine, each of these services has 3 endpoints, and each service has 10 operations exposed across each of the three endpoints:

  • We’ll assume an average size per performance counter of 350 bytes, which is a fairly conservative yet accurate estimate.
  • For the service counters, we have 20 services * 33 performance counters * 350 bytes = 231,000 bytes (231 KB)
  • For the endpoint counters, we’ll need 20 services * 3 endpoints * 19 performance counters * 350 bytes = 399,000 bytes (399 KB)
  • Operations counters come in the largest, due to the multiplicative effect, at 20 services * 3 endpoints * 10 operations * 15 counters * 350 bytes = 3,150,000 bytes (3.15 MB).

From the above numbers, you’ll hopefully notice two things. First, I hope you now understand why I recommend the “ServiceOnly” setting unless you’re in an environment where you absolutely need the other counters. Second, even with a medium size service load, we’ve exceeded the default performance counter category maximum memory and are quickly heading for the dreaded “System.InvalidOperationException: Custom counters file view is out of memory” exception.

Setting Performance Counter Memory Size

Aside from the mechanics of setting the performance counter category memory size, there is only so much guidance I can provide. What you will set these values to will depend upon a couple of factors:

  • Whether you’ve set WCF counters to “ServiceOnly” or to “All”. If you’ve used the former, you’ll only need to tweak the service-specific private memory. If you go with “All”, you’ll want to set each category’s memory space individually.
  • The math you do for your counter categories based upon the example I provided in the previous section.

For the size of separate shared memory, the DWORD FileMappingSize value in the registry key HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices<category name>Performance is referenced first, followed by the value specified for the global shared memory in the configuration file. If the FileMappingSize value does not exist, then the separate shared memory size is set to ¼ the global shared memory setting in the configuration file, which is 528KB by default.

To specify the WCF category-specific sizes, simply set the registry value for each of the three registry keys associated with the three WCF service categories and then reboot the machine. Keep in mind that, like other application sizing activities, sizing of the WCF counter memory will need to be repeated as the number of services, endpoints, and operations change on a particular machine.

Comments 3 Comments »

I’ve been blogging for 4 years now and never have filled out the “About Me” section on my blog. I’ve had good intentions for a while but just never got around to it because my vision involved scanning in a bunch of older materials. I’ve finally carved out a bit of time to update the default blurb with suitable material, which you can find here. Unless you’ve known me for a long while, you’re sure to find out an interesting new thing or two. Give it a look!

Comments No Comments »

As many of you likely know, Lutz Roeder turned over control of one of the “must have” .NET developer tools, .NET Reflector to Red Gate software. True to their promise, RedGate has continued to support the free version of Reflector and make continued improvements, including the addition of a Visual Studio plugin to jump into Reflector and the support of .NET 4 assemblies with their most recent release of the tool.

In addition to their support of the free tool, RedGate has extended Reflector’s core disassembly capabilities and is now offering a commercial version of the tool, Reflector Pro. RedGate has rolled the tool into their .NET Developer Bundle. So, if you hold existing .NET Developer Bundle licenses, you can pick up Reflector Pro and start using it. So I did.

Reflector Pro integrates right into Visual Studio (including the VS 2010 RC), which is really important given its core competency. What it allows, simply stated, is for you to step through any assembly in Visual Studio as if it were your own. This is a killer feature that you almost never need… until you really need it. Reflector Pro does this by disassembling assemblies of your choosing and then generating the corresponding debug symbols you need to perform a variety of functions:

  • Stepping into third party libraries
  • Setting breakpoints in third party libraries
  • Watch and modify values in third party libraries

Like the free version of Reflector we’ve all grown to love, the Pro version of the software isn’t needed all the time and it just works the way you want when you need it. RedGate’s site (http://www.red-gate.com/products/reflector/index.htm) provides a simple video demo and walkthrough. More your should not need to get going with this tool.

Comments No Comments »

How would you like to achieve detailed exception and trace logging, including method timing and correlation all within a lightweight in-memory database that you can easily manage and query, as exhibited below?

All of this requiring nothing more of you than simply decorating your methods with a very simple attribute, as highlighted below.

In this post, I’m going to demonstrate how to configure PostSharp, an aspect-oriented framework, along with NLog and SQLite to achieve the benefits highlighted above. Before I get into the details of the configuration and aspect source code, I’ll provide a bit of background on PostSharp.

PostSharp

PostSharp is a powerful framework that supports aspect-oriented programming using .NET attributes. Attributes have been around in the .NET Framework since version 1.0. If you weren’t used to using attributes in the past, their increased usage in WCF (including WCF RIA Services and Data Services), ASP.NET MVC, the Entity Framework, the Enterprise Library and most of Microsoft’s other application frameworks will surely mean you’ll be encountering them in the very near future. PostSharp allows you to create your own attributes to meet a variety of needs (cross-cutting concerns, in aspect-oriented parlance) you may have such as persistence, security, monitoring, multi-threading, and data binding.

PostSharp has recently moved from a freely available to a commercially supported product. PostSharp 1.5 is the last open source version of the product with PostSharp 2.0 being the first release of the commercially supported product. Don’t let the commercial product stigma scare you away, both PostSharp 1.5 and 2.0 are excellent products. If you chose to go with PostSharp 2.0 you can select either a pretty liberal community edition or more powerful yet reasonably priced Professional edition. For the purpose of this post, I’ll be using the community edition of PostSharp for forward compatibility. The Community Edition includes method, field, and property-level aspects, which is more than enough for the purposes of this post. You will also find examples of PostSharp aspects on their site, in the blogosphere, and on community projects such as PostSharp User Plug-ins.

What makes PostSharp stand out among competing aspect-oriented frameworks is how it creates the aspects. PostSharp uses a mechanism called compile-time IL weaving to apply aspects to your business code. What this essentially means is that, at build time, PostSharp opens up the .NET intermediate language binary where you’ve included an aspect and injects the IL specific to your aspect into the binary. I’ve illustrated below what this looks like when you use .NET Reflector to disassemble an assembly that’s been instrumented by PostSharp. The first image is before a PostSharp attribute is applied to the About() method on the controller. The second image represents what the code looks like after PostSharp compile-time weaving.

Before PostSharp Attribute Applied to About() Method


After PostSharp Attribute Applied to About() Method


What this means is that you get very good performance of aspects but will need to pay a higher price at build/compile time. Ayende provides a good overview of various AOP approaches, including the one that PostSharp uses. Don’t be concerned by his “hard to implement” comment. The hard part was done by the creators of PostSharp, who have made it easy for you.

Implementation of Aspect-Oriented Instrumentation

The remainder of this post will focus on the actual implementation of the solution. Much of the code I have here was cobbled together from a blog post I archived long ago from an unknown author. I’d love to provide attribution but, like many blogs out there, it seemed to have disappeared over time. I’ll start off first with the SQLite table structure, which can be found below.

The logging configuration file is very similar to my post on logging with SQLite and NLog with minor changes to the SQLite provider version.

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <targets>
    <target name="File" xsi:type="File" fileName="C:Temp${shortdate}.nlog.txt"/>
    <target name="Database" xsi:type="Database" keepConnection="false" useTransactions="false"
            dbProvider="System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.60.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139, processorArchitecture=x86"
            connectionString="Data Source=C:ProjectsMyApp_Logging.s3db;Version=3;"
            commandText="INSERT into LOGTABLE(Timestamp, Loglevel, ThreadId, Message, Context, User, DurationInMs, Exception) values(@Timestamp, @Loglevel, @ThreadId, @Message, @Context, @User, @DurationInMs, @Exception)">
      <parameter name="@Timestamp" layout="${longdate}"/>
      <parameter name="@Loglevel" layout="${level:uppercase=true}"/>
      <parameter name="@ThreadId" layout="${threadid}"/>
      <parameter name="@Message" layout="${message}"/>
      <parameter name="@Context" layout="${ndc}"/>
      <parameter name="@User" layout="${aspnet-user-identity}"/>
      <parameter name="@DurationInMs" layout="${mdc:item=DurationInMs}"/>
      <parameter name="@Exception" layout="${mdc:item=exception}"/>
    </target>
  </targets>
  <rules>
    <logger name="*" minlevel="Debug" writeTo="Database" />
  </rules>
</nlog>

The most important component of the solution is the source code for the PostSharp aspect. Before letting you loose, I’ve highlighted some of the features of the source code to avoid cluttering it with comments:

• You need to have PostSharp (the DLLs and the necessary build/compilation configuration) set up on your machine for the aspects to work correctly. Specifically, my code works against PostSharp 2.0
• For those of you not familiar with Log4Net or the original implementations of the NDC (NestedDiagnosticContext) and MDC (MappedDiagnosticContext), the original documentation from the Log4J project provides good background.
• The NDC is used to push GUID’s on the stack which can then be used as correlation ID’s to trace calls through the stack for methods annotated with the [LogMethodCall] attribute that this code implements.
• The MDC map stores timing information in all cases and exception information in the case of an Exception in one of the calling methods annotated with the [LogMethodCall] attribute.
• To use the attribute, just decorate the method you wish to instrument with the [LogMethodCall] attribute. Then sit back and enjoy detailed instrumentation for free.

using System;
using System.Diagnostics;
using NLog;
using NLog.Targets;
using PostSharp;
using PostSharp.Aspects;

namespace MvcApp.Web.Aspects
{
    [Serializable]
    public class LogMethodCallAttribute : MethodInterceptionAspect
    {
        public override void OnInvoke(MethodInterceptionArgs eventArgs){
            var methodName = eventArgs.Method.Name.Replace("~", String.Empty);
            var className = eventArgs.Method.DeclaringType.ToString();
            className = className.Substring(className.LastIndexOf(".")+1, (className.Length - className.LastIndexOf(".")-1));
            var log = LogManager.GetCurrentClassLogger();
            var stopWatch = new Stopwatch();

            var contextId = Guid.NewGuid().ToString();
            NLog.NDC.Push(contextId);

            log.Info("{0}() called", methodName);
            stopWatch.Start();
            NLog.NDC.Pop();

            try
            {
                eventArgs.Proceed();
            }
            catch (Exception ex)
            {
                var innermostException = GetInnermostException(ex);
                MDC.Set("exception", innermostException.ToString().Substring(0, Math.Min(innermostException.ToString().Length, 2000)));
                log.Error("{0}() failed with error: {1}", methodName, innermostException.Message);
                MDC.Remove("exception");
                throw innermostException;
           }

           NLog.NDC.Push(contextId);
           stopWatch.Stop();
           NLog. MDC.Set("DurationInMs", stopWatch.ElapsedMilliseconds.ToString());
           log.Info("{0}() completed", methodName);
           NLog.MDC.Remove("DurationInMs");
           stopWatch = null;
           NLog.NDC.Pop();
        }

        private static Exception GetInnermostException(Exception ex)
        {
            var exception = ex;
            while (null != exception.InnerException)
            {
                exception = exception.InnerException;
            }
            return exception;
        }
    }
}

Comments 4 Comments »