1
Visual Studio is the number one development environment for Microsoft technologies and that is especially true for .NET based applications. When developing an application - building it on top of frameworks like ASP.NET, ASP.NET MVC, WPF or SharePoint - it is always great to have the ability to debug through your code in order to find out what is actually going on at runtime.

ASP.NET Page Lifecycle methods for instance that are called in the different stages of page processing are a good example where debugging definitely helps you to understand which methods of your page are called in while ASP.NET processes the page request.

Limitations of debugging

There are however limitations with debugging that makes it a bit hard to analyze the exact workflow of an application when based on complex frameworks and optionally calling out to other (local or remote) components:

  • While debugging, you only see the current stack trace but you don’t see the complete transaction trace including ALL different execution paths
  • You can normally only debug through your own code. Its hard to figure out what is going on in the frameworks or libraries that are used
  • Calling external (local or remote) services are treated like a blackbox - unless you have the chance to install a remote debugger and as long as the remote technology can be handled by Visual Studio (Native C++, .NET)
  • Debugging changes the runtime behavior of your application and may even influence the execution paths, e.g.: running into timeouts, …

Last week at the PDC2008 in Los Angeles - Microsoft gave a preview of Visual Studio 2010 and a new feature that they call Historical Debugging. This feature will adress the first bullet item on my list but we still need to wait till the next release of Visual Studio - and - what about the other 3 points?

Transactional Tracing with dynaTrace

dynaTrace offers transactional tracing with its unique PurePath technology. It allows tracing every single transaction from where it enters your application, e.g.: ASP.NET Page Handler through all relevant methods that are executed within the same transaction context and is even able to trace the transaction across runtime and technology (Java and .NET) boundaries. Along the PurePath information like execution times, method arguments, exceptions, logging messages and database statements are captured.

How to integrate transactional tracing with Visual Studio?

As a developer I want to be able to launch my application as I am used to - from within Visual Studio by hitting Ctrl+F5 to run the app or F5 to debug it. In order to extend this capability with transactional tracing for my app I created a Visual Studio Add-In that launches the active project of the open solution with dynaTrace support. Binding the new command to the shortcut Ctrl-Shift-D now allows me to get transactional tracing support from within Visual Studio with a simple keystroke.

Launch Web Project with dynaTrace support to trace transactions

Transactional tracing now allows me to really see what is going on within my application. I can explore the PurePath to analyze how the ASP.NET Page is actually executed:

PurePath of an ASP.NET Page Request containing a Data Grid

PurePath of an ASP.NET Page Request containing a GridView

It also allows me to look at the captured data from different perspectives, like looking at all database statements that have been executed in context of a single transaction:

Database statements executed by a single ASP.NET Web Request

Database statements executed by a single ASP.NET Web Request

Or even follow a call to an external service and see what was executed within that service - no matter whether it is implemented in .NET or Java:

Transaction Trace across runtime boundaries and technologies

Transaction Trace across runtime boundaries and technologies

Conclusion

The ability to do transactional tracing triggered from within the development environment enables developers to better understand what is going on in their code, in the frameworks that they base their app on and in the services that their code relies on. Visual Studio offers these extension mechnisms and dynaTrace - with the PurePath technology - enables capturing the necessary data.

, ,

Exceptions are a great way to communicate error state back to the caller. The exception class basically defines the type of error, e.g.: AccessDenied that happened. The detailed message then explains the exact reason for the problem, e.g.: “Your user has no rights to access file xyz”.

Documentation of frameworks usually lists all types of exceptions that could potentially be thrown - allowing the caller to implement try-catch routines to handle those exceptions that make sense in order to implement program logic.

“The Good” thing about exceptions

The above described usage scenarios are a good thing about exceptions. Getting a detailed explanation in case a problem happened can make it easy for you to address the issue or even allows you to publish this error to the user interface. Using exceptions to control program logic is also a way to go (but still keep in mind the good old return values :-) )

“The Evil” thing about exceptions

In the past weeks I came across different scenarios where the above explained usage scenarios didn’t work. Here is why:

Scenario a) The Web Application returned a 403 Access Forbidden

The application used a 3rd party web control to display a questionnaire form. Some users of the web application could use it fine - others always got an UnauthorizedAccessException thrown by the Page_Load method of the 3rd party web control leading to a 403 HTTP Error. The exception had no detailed error message specified so it was impossible to find the exact root cause. 
Using dynaTrace it was possible to find the root cause. It turned out that the web control accessed a local configuration file on the web server. Opening that file threw an AccessViolationException with a detailed error message that this user just had no access rights. The original message unfortunately was never thrown up to the application itself. Knowing the original exception helped to understand and address the problem.

Scenario b) The Application allowed restricted access to an unauthorized user

The application called into an authorization framework that would throw different kinds of exceptions in case the user did not have the appropriate access rights. The application would catch all different exceptions and implement different program logic to handle the situation.
In order to implement a logging facility, a new layer was introduced that was supposed to catch the exceptions thrown from the authorization framework, log the calls, and then rethrow the exception. Due to a bug in this layer, several exceptions indicating an authorization problem never made it to the actual caller. The application therefore continued the normal application flow as if the user would have had access.

Solution

Getting visibility into your application and all its frameworks it depends on enables you to better understand how to use your 3rd party frameworks. It also allows you to diagnose errors down to the root cause in case you don’t get the detailed explanation that you need.

Analyzing Exceptions

Analyzing Exceptions in the context of a single transaction

The above image shows how dynaTrace tracks every exception that happens in your system. It also shows it in the context of a single transaction (PurePath) with all its contextual information, e.g: method parameters, …

Conclusion

Relying on frameworks is a mandatory thing these days. But not knowing what’s actually going on in those frameworks can lead to the above described side effects. With a solution like dynaTrace it is possible to analyze all exceptions that occurred within the application and not only within the custom application code.

,

When people talk about performance and scalability they very often use these two word synonymously. However they mean different things. As there is a lot of misunderstanding on that topic, I thought it makes sense to have a blog post on it.

One of the best explanations can be found here.  It is a nice explanation by Werner Vogels the CTO of amazon.  I think everybody agrees that he knows what he is talking about.

Performance refers to the capability of a system to provide a certain response time. server a defined number of users or process a certain amount of data.  So performance is a software quality metric.  Unlike to what many people think it is not vage, but can be defined in numbers.

If we realize that our performance requirements change (e.g. we have to serve more users, we have to provide lower response times) or we cannot meet our performance goals, scalability comes into play.

Scalability referes to the characteristic of a system to increase performance by adding additional ressources. Very often people think that there system are scalabable out-of-the-box. “If we need to serve more users, we just add additional server” is a typical answer for performance problems.

However this assumes that the system is scalable, meaning adding additional resources really helps to improve performance.  Whether your system is scalable or not depends on your architecture.  Software systems not having scalability as a design goal often do not provide good scalabilty.  This InfoQ interview with Cameron Purdy - VP of Development in Oracle’s Fusion Middleware group and former Tangosol CEO - provides a good example on limited scalability of a system.  There are also two nice artilces by Sun’s Wang Yu on Vertical and Horizontal Scalabilty.

So how does this relate to dynaTrace.  With Lifecycle APM we defined an approach how to ensure performance and scalability over the application lifecycle - from development to production.  We work with our customers to make performance management part of their software processes going beyond performance testing and firefighting when there are problems in production.

As scalabilty problem are in nearly all cases architectural problems, these charateristcs have to be tested already in the development phase. dynaTrace provides means to integrate and automate performance management in your Continuous Integration Environments.

When I talk to people I sometimes get the feedback “… isn’t that premature optimization” (have a look at the cool image on premature optimization in K. Scott Allen’s Blog). This is a strong misconception. Premature optimization would mean that we always try to do performance optimization whenever and wherever we can.  Lifecycle APM and Continuous Performance Management as the development part of it, targets to get all information to always know about the scalabilty and performance characteristcs of your application. This serves as a basis for deciding when and where to optimize; actually avoiding premature optimization in the wrong direction.

Concluding we can say that if we want our systems to be scalable we have to take this into consideration right from the beginning of development and also monitor throuhout the lifecycle.  If we have to ensure it, we have to monitor it. This means that performance management must then treated equally relevant than the management of functional requirements.

, , , ,