Archive

NDC Oslo 2014 is almost there. As every year, software developers will converge to Oslo. If you haven’t done it yet, watch David Appenborough’s fun documentary about this surprising seasonal migration.

PostSharp will have a strong presence with three team members, one workshop and one presentation!

NDC is connected with a few “firsts” for us: NDC 2011 was the finish line of the first PostSharp road tour ever. And this year will be the very first time we’ll have a booth! Well, this was quite an experience to get prepared to a conference of this size. We got new brochures, video loops and t-shirts, and you don’t want to miss this opportunity to meet Gael and the PostSharp team:

  • Pre-Conference Workshop on Monday, June 2nd: a deep dive from the horse’s mouth. Disclaimer: attendees may change the way they look at software development. It’s still time to register for your workshops if you haven’t done it yet.
  • Taking Design Patterns to the Next Level on Thursday, June 4th challenges popular dogmas about design patterns and shows how design pattern automation is possible today in .NET.
    The presentation starts at 9:00AM in Room 5.
  • You can meet us at our booth! We’d love to hear how we can improve what we’re doing and you'll get a chance to win some nice PostSharp gifts!

As every year, the 2014 speaker alignment is awesome; we hope to see you there!

-Iveta

We’re sorry to announce that a critical defect affects all builds of PostSharp versions 3.1.0-3.1.40 and 3.2.0-3.2.20. We strongly recommend all projects using PostSharp 3.1 to be upgraded to PostSharp 3.1.42.

Which projects are affected?

It is important to understand that the defect acts as a “time bomb”. You will be affected by the project even if (a) you did not modify its source code, (b) you did not upgrade PostSharp and (c) you did not install any Windows update.

Projects that (a) are bound to PostSharp 3.1.0-3.1.33 AND (b) that don’t cause PostSharp to emit an error or warning message are not affected.

Does the issue affect run-time behavior of applications built with PostSharp?

No. The defect only affects build-time behavior.

What are the symptoms of the error?

You may see one of the following symptoms, according to the kind of host:

  • With PostSharpHost=PipeServer (typically on developer workstations): “connection unexpectly closed by the server” followed by “Retrying to execute the pipe server” followed by “Error connecting to the pipe server. See previous warnings for details”

  • With PostShatpHost=Native (typically on build servers):

    • error MSB6006: "postsharp.4.0-x64.exe" exited with code -199

    • error MSB6006: "postsharp.4.0-x86.exe" exited with code -199.

    • error MSB6006: "postsharp.4.0-x64-cil.exe" exited with code -199

    • error MSB6006: "postsharp.4.0-x86-cil.exe" exited with code -199.

  • With PostSharpHost=Managed: The license dialog of Nove.CodeDOM appears.

ACTION REQUIRED

Upgrade all projects using PostSharp 3.1.0-3.1.40 using NuGet Package Managers:

  1. Open the solution in Visual Studio

  2. Click on menu item Tools / NuGet Package Manager / Manage NuGet Packages for Solutions…

  3. Go to the Update tab.

  4. Update all PostSharp packages to version 3.1.42 or higher.

  5. Deploy the new source code to build server and team members.

Note: Updating the PostSharp Visual Studio Extension (VSiX) is not required and does not solve the issue.

What happens if I don’t upgrade the projects?

If you don’t upgrade the project, the issue may appear later, and your team may lose productivity in diagnosing it.

What is I don’t have an active maintenance subscription?

We “tricked” the 3.1.42 build so it is available to anyone who was properly licensed for PostSharp 3.1 RTM, even with an expired license subscription. You should then specifically upload to build 3.1.42. Other builds don’t have the license “trick”.

What is the cause of the defect?

The error is caused by the license enforcement component of Nova.CodeDOM, a library that we lawfully sourced from Inevitable Software. PostSharp uses this library to provide file and line number information of error messages.

Previously to 3.1.33, PostSharp initialized Nova.CodeDOM lazily, when the first error message needed to be resolved. Starting 3.1.33, PostSharp initialized Nova.CodeDOM unconditionally. This is why projects built with PostSharp 3.1.33 and later are more likely to be affected by the issue.

Why was this issue not anticipated?

We anticipated issues in the Nova.CodeDOM library and implemented a fail-safe behavior, so that a failure in the library would just cause a failure to locate the file and line number of error messages, but except of having no file and line information, the build would work as usually. However, we did assumed that all failures would be in the form of a managed exceptions. We did not anticipate that the library would terminate the process.

When did the symptoms first occur?

The issue first hit our support line on May 20th at 16:00, Central Europe Time. We became aware of the severity of the issue on May 21st at 10:00 when more support tickets were filed.

When was a fix released?

We uploaded the build 3.1.41 fixing this issue on May 21st at 14:00, Central Europe Time.

Completed in a rush, this build contained two non-blocking issues, which were fixed in 3.1.42 and uploaded on May 23rd.

How was the issue solved?

As we lost trust in Nova.CodeDOM, we decided to immediately remove the library from our product. As from version 3.1.41, we will no longer ship Nova.CodeDOM with our products.

Therefore, we unfortunately had to surrender the feature that was using Nova.CodeDOM. Namely, current versions of PostSharp no longer resolve the file and line number of error messages. We will restore the feature with Roslyn as soon as the license will allow for redistribution.

Summary

At PostSharp, we are taking our customers’ productivity extremely seriously. We are aware that this issue prevented whole teams of developers from working during several hours, and that the potential impact of the issue may account for dozens of thousands of dollars of combined productivity losses.

Although the defect was caused by a third-party component, we are ultimately responsible for the overall quality of our product, and this includes selection of suppliers.

Therefore, on behalf of PostSharp Technologies, I would like to profoundly apologize for the inconveniences caused by the issue.

Gael Fraiteur
CEO

UPDATE: Edited the article to mention our build 3.1.42 fixing minor issue and licensing friction.

Microsoft is rarely the first to jump on a train, but when they do jump, they make sure it is very simple for everybody to get on their wagon. And they did it again with Application Insights, a feature of Visual Studio Online that monitors the performance of web sites, web services, and mobile apps.  They are perhaps not as feature-complete as early players (special thoughts to our friends and partners at Gibraltar Software), but their simplicity is stunning.

Adding Application Insights to Your App

Judge by yourself. You need just two simple steps to add monitoring to your app:

  1. Install the Visual Studio extension “Application Insights Tools for Visual Studio”.
  2. Open your project and click on menu Tools / Add Application Insights.

You’re done. No joke.

Application Insights provides several monitors right out of the box, among which page load time and Windows performance counters. It also has a (still modest) API that allows you to push your own data. Perhaps the top use case you would like to implement is to measure the execution time of a method, and perhaps include the method arguments in the trace data.

Measuring Method Execution Time

Wouldn’t it be nice if you could add your own metric to Application Insights using a custom attribute? This is almost trivial with PostSharp. And since it’s so trivial, it’s also possible with the free PostSharp Express. Let’s see how.

  1. Add the Visual Studio extension “PostSharp”.
  2. Right-click on your project and select “Add PostSharp to project”.
  3. Add a class ApplicationInsightsTimedEventAttribute to the project. For now, just copy the code from this file. I’ll explain what it does in a minute.
  4. Go to the method you want to instrument and add the [ApplicationInsightsTimedEvent] custom attribute.

You’re done.

Run your application and cause the instrumented to execute. Then go back to Visual Studio, and click on menu Tools / Open Application Insights Portal. You’ll see custom timed events triggered by the execution of the method.

A Closer Look At the Aspect

Let’s now have a look at the ApplicationInsightsTimedEventAttribute class itself.

[PSerializable] // Use [Serializable] with the free PostSharp Express.
public class ApplicationInsightsTimedEventAttribute : OnMethodBoundaryAspect
{
    // Fields and properties will be serialized at build-time and deserialized at run-time.

    string eventPath;
    string[] parameterNames;

    public bool IncludeArguments { get; private set; }

    public ApplicationInsightsTimedEventAttribute(bool includeArguments = true)
    {
        this.IncludeArguments = includeArguments;

        // Make sure it works as expected with async methods.
        this.ApplyToStateMachine = true;
    }

    public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
    {
        // Computing the event name at build time since it won't change.
        this.eventPath = method.DeclaringType.FullName
                            .Replace('.', '/').Replace('+', '/')
                            + "/" + method.Name;

        // Collecting parameter names at build time prevents from using Reflection at runtime.
        if (this.IncludeArguments)
        {
            this.parameterNames = method.GetParameters().Select(p => p.Name).ToArray();
        }
    }

    // This code will be executed BEFORE the method to which the custom attribute is applied.
    public override void OnEntry(MethodExecutionArgs args)
    {
        IAnalyticsRequest request = ServerAnalytics.CurrentRequest;

        if (request != null)
        {
            ITimedAnalyticsEvent timedEvent;

            if (this.IncludeArguments)
            {
                // Build a list of properties based on method arguments.
                List<KeyValuePair<string, object>> arguments = new List<KeyValuePair<string, object>>();
                for (int i = 0; i < this.parameterNames.Length; i++)
                {
                    arguments.Add(new KeyValuePair<string,object>( this.parameterNames[i], args.Arguments[i]));
                }

                // Start the event with arguments.
                timedEvent = request.StartTimedEvent(this.eventPath, arguments);
            }
            else
            {
                // Start the event without arguments.
                timedEvent = request.StartTimedEvent(this.eventPath);
            }

            // Store the event in MethodExecutionTag so we can retrieve it in OnExit.
            args.MethodExecutionTag = timedEvent;
        }
    }

    // This code will be executed AFTER the method to which the custom attribute is applied,
    // both upon failure or success.
    public override void OnExit(MethodExecutionArgs args)
    {
        // Retrieve the event. It's possible that there's no event if there was no current request.
        ITimedAnalyticsEvent timedEvent = (ITimedAnalyticsEvent) args.MethodExecutionTag;

        if ( timedEvent != null )
        {
            // End the event.
            timedEvent.End();
        }
    }

}

A specificity of PostSharp is that the aspect is instantiated at build time. This allows for some performance optimizations. Since the event name is fully determined by metadata, it is a good idea to compute it at build time. This is why we have the CompileTimeInitialize method. After the aspect has been initialized, it is serialized and stored as a managed resource in the assembly. At run-time, the aspect is deserialized and is ready to be executed. (Note that the performance optimizations are more significant with a commercial edition of PostSharp; the free edition generates un-optimized instructions).

The OnEntry method is executed at the beginning of any method to which the custom attribute is added. The OnExit method is executed in a finally block after the target method. Their argument MethodExectionArgs contains information about the current context. Here, we’re interested by the method arguments.

Adding the Aspect to Code

Since ApplicationInsightsTimedEventAttribute is a custom attribute, you can add it to any method you want to instrument. Now, what if you want to instrument really a lot of them? You may not want to annotate all of them individually. There are many ways you can do that with PostSharp, but to avoid making this article a PostSharp tutorial, I will just gently send you to the documentation for this point.

Even More Logging

So far, I’ve shown how to add timed events to Application Insights using a very simple custom aspect.

You may want more features for real production-ready logging. For instance, it is important to be able to enable or disable logging dynamically or through a configuration file. Otherwise, the log would just be too huge, so you may want to prepare logging to your complete codebase but disable it by default. Would a problem occur in your app, the operation team would just update the configuration file and enable tracing for a specific class or namespace.

PostSharp has a solution for this: the Diagnostics Pattern Library. It includes a production-ready logging aspect. The bad news is that Application Insights is not directly supported as a back-end. The good news is that we can emit data to NLog, Log4Net or TraceListener, and Application Insights is able to read from all of these frameworks. So, the gap is easily bridged.

 

Feature Tracking

Nobody said that the concept of “event” must just map to the concept of “logging”. You can use events to model feature tracking too. You could build your own aspect, starting from the code aspect, to implement your own definition of feature tracking and encapsulate it as a custom attribute.

Summary

Microsoft Application Insights is stunningly simple to use, but it lacks some features of its competitors. One of them is the ability to instrument your application “from the inside” without requiring you to modify your source code. Fortunately, the feature is very easy to implement with PostSharp.

In the future, we at PostSharp may think of supporting Application Insights directly from the Diagnostics Pattern Library. But before, we’d love to hear your opinion. How do you think we should integrate with Application Insights? What are the top use cases you would like to be solved with the highest level of quality and performance? We’re looking forward to your feedback.

Happy PostSharping!

-gael