Learning Windows Server 2003

9.8. Diagnostics

The .NET Framework includes a wide variety of options for diagnosing different aspects of a running application. You can use diagnostics for many functions including auditing, logging, profiling, and debugging . You can use them to identify performance problems, resource usage, and security issues. Like many other management tasks, diagnostic work requires full cooperation between developers and the system management staff. This section will cover the diagnostics management and give you tips on what the development side of the house should do to keep their end of the bargain.

9.8.1. Debugging and Tracing

The debug and trace features allow an application to produce simple diagnostic information without interfering with the user interface. Developers can include statements within the application code to write information and failures to virtually any source, including the Windows Event Log.

Although the debug and trace features are exactly the same internally, they have different intended uses:

  • Debug is used during the development and testing stages of an application. Debug statements are usually stripped out by the compiler in release builds of assemblies.

  • Trace is used during the full life cycle of development, including production. Compilers typically leave TRace statements in release builds.

If you're not a code monkey, you can safely skip the remainder of this section and move on to the next. I'll simply provide more detail for those interested in .NET Framework debugging and tracing features.

Example 9-5 shows a section of a configuration settings file that configures the debug and trace features. Most of the settings are self-explanatory, but a few of them are quite obscure. First, the <assert> element is actually the configuration for the DefaultTraceListener. If the DefaultTraceListener is removed, these settings have no effect. The other confusion within this section is the naming of the <trace> element. Despite the name of the element, all parameters and listeners defined also apply to the debug feature. You can see the first thing I did within the listeners was to remove the DefaultTraceListener. On the next line, I define a TextWriterTraceListener and in the initializeData, I define the name of the log file.

Example 9-5. Debug and Trace information in configuration settings

<configuration> <system.diagnostics> <assert assertuienabled="true" logfilename="test.log" /> <switches> <add name="AuditSwitch" value="1" /> <add name="ErrorSwitch" value="4" /> </switches> <trace autoflush="false" indentsize="0"> <listeners> <remove name="Default" /> <add name="Text" type="System.Diagnostics.TextWriterTraceListener, ..." initializeData="realTest.log" /> </listeners> </trace> </system.diagnostics> </configuration>

Keep in mind that, if necessary, you can override in the application code the listeners specified in the configuration file. This can provide additional levels of detail, such as sending the output of a TextWriterTraceListener through an encryption algorithm or over a network. It also can confuse administrators, so if you hear your developers around the corner snickering, that might explain why the trace output is being sent to the CEO's Inbox.

ASP.NET offers an additional form of tracing within web applications. Keep in mind that it is entirely different from the tracing functionality discussed earlier in that it isn't designed to be persistent. This form of tracing is designed to give real-time feedback on web page execution performance . Figure 9-6 is just a small sample of the information exposed through the trace request details.

Figure 9-6. Details of a trace request

You can configure this information to be included at the end of every page, or store it in web server memory browsed with the trace.axd virtual page in your web application root. An example of the web.config configuration of tracing is shown here:

<system.web> <trace enabled="true" localOnly="false" pageOutput="false" requestLimit="50" /> </system.web>

The localOnly parameter defines whether the trace.axd page can be accessed from a machine other than the web server. The requestLimit parameter behaves a little oddly, as when it reaches this limit, all tracing stops. You must clear the trace or restart the application to begin tracing after the limit is reached.

9.8.2. Performance Counters

Performance counters provide an excellent interface to monitor activity within a Windows environment. The .NET Framework uses the performance counter infrastructure to report on its own performance and to allow applications to report on their custom performance characteristics.

9.8.2.1. Framework counters

The .NET Framework provides two categories of performance counters, CLR and ASP.NET. In these two categories are numerous different subcategories with counters within. You can apply the CLR counters on a per-process basis or on a global basis. These counters monitor the activity within the various services that the runtime provides. Although there is tremendous value in the outputs from these counters, they are very difficult to dissect without expert knowledge of the CLR. ASP.NET defines two subcategories for counters. The first category, ASP.NET, contains counters that aggregate all applications and system-level counters. The other category, ASP.NET Applications, contains counters that serve to report on individual web applications. Figure 9-7 illustrates the selection of .NET performance counters.

Figure 9-7. .NET performance counters

I won't cover all the counters here, as there are more than 100 in total, but I'd like to mention a few that provide easy-to-interpret results and can indicate bottlenecks:

  • # of Exceps Thrown and # of Exceps Thrown / sec under the .NET CLR Exceptions subcategory can manifest problems within any application. Exceptions are errors that are not always propagated to the user interface. Exceptions are quite expensive for the runtime to create. This number should be low.

  • Current Queue Length under the .NET CLR LocksAndThreads subcategory is useful in applications that are making a lot of long-running parallel calls. This number should be low.

  • Application Restarts and Worker Process Restarts under ASP.NET can indicate memory usage problems or timeouts. Applications and Worker Processes restart periodically based on either of these two problems. This number should be low.

  • Requests Queued under ASP.NET counts the number of requests waiting to be processed. This number should be low.

  • Cache API Hit Ratio, Cache Total Hit Ratio, and Output Cache Hit Ratio under ASP.NET Applications are useful in determining the efficiency of cache usage. The caching features of ASP.NET allow applications to avoid invoking expensive operations every time data is needed. A low cache hit ratio indicates the cache is not being used efficiently.

The standard Windows performance counters grouped under the categories System and Processor also can be very important in monitoring .NET applications, but might not give the granularity that the .NET Framework counters provide.

9.8.2.2. Custom counters

Applications in need of specific performance monitoring can take advantage of custom performance counters. The .NET Framework provides a very simple set of libraries for developers to develop custom performance counters. Although the .NET Framework counters can indicate what type of performance problem exists, you can use custom counters to show what part of the application is causing the problems.

You also can use the counters to present business-related information. For example, a company could track the number of orders or shipments in real time.

9.8.3. Event Logs

The .NET Framework extends the integration into Windows management with event logging capability. Event logs provide a centralized store for reporting all types of application information.

Windows provides three default logs that applications can write to:

Application

Applications report information and error messages here.

Security

Audit records from system-level and application-level events are reported here.

System

Like the Application log, this also is poorly described as "system error records." This log is used to report all system-level events.

In addition to the default logs, you can create an unlimited number of custom logs for any application. This is useful for events that do not fit into the other categories, or when the information needs to be segregated for management.

Use and configuration of event logs typically occur within the application code. .NET provides rich libraries to allow granular manipulation of many event parameters including the log name, the source, the type of entry, the event ID, the category, the raw data, and of course, the description. You can pass control of some of these parameters to system administrators in the form of parameters within the appSettings section in the configuration file, but developers would have to specifically code for this.

In the spirit of configuration-based applications, .NET does provide a method for administrators to enable event logging for an application. You can utilize this if the application implements tracing or debugging. You can configure the EventLogTraceListener within the application configuration file to send all trace and debug messages into the event log. However, the options are quite limited. The following XML placed within the <listeners> tag of the <trace> tag will register an EventLogTraceListener:

<add name="Event" type="System.Diagnostics.EventLogTraceListener, System, ..." initializeData="Hello Application" />

As the preceding XML shows, you can supply only one parameter, initializeData. This parameter sets the Source of the log entries. Figure 9-8 shows an actual log entry created using tracing. The Application log is used with an entry type of Information.

Категории