Alois Kraus

blog

  Home  |   Contact  |   Syndication    |   Login
  133 Posts | 8 Stories | 368 Comments | 162 Trackbacks

News



Archives

Post Categories

Programming

The new Enterprise Library for .NET 2.0 has disabled instrumentation by default. It is very reasonable to do this because in low trust scenarios you are not able to install Performance Counters, Windows Event Logs/Sources or update WMI schemas. The previous version had "configurable" instrumentation by some #ifdefs in the source code. To change instrumentation you had to recompile the whole library every time you wanted to target a different deployment and therefore trust scenario. This time the Enterprise Library team had more time to make it really configurable. The outcome is remarkable easy to use. You can enable/disable the following instrumentation settings:
  • Error logging of all Application Blocks to the Windows Event Log.
  • Performance Counter writes.
  • Firing of WMI Events.
To configure Instrumentation you can use in the Enterprise Library Configuration Tool. Use the context menu to add a new "Application Block" which is named Instrumentation.

Enterprise Library Console - Create Instrumentation Node

You can now enable WMI, Error Event Logging or Performance Counters by editing a config file. This time no recompilation of the library is necessary. This is really great work from the Patterns & Practices Team at Microsoft.

Enterprise Library Console - Instrumentation

The following table lists the WMI events that are fired by the application blocks when WMI is enabled. All event classes are registered under the WMI namespace root/EnterpriseLibrary.

WMI Event Properties Used by Application Block
AuthorizationCheckPerformedEvent UserName, TaskName, InstanceName Security
AuthorizationCheckFailedEvent UserName, TaskName, InstanceName Security
SecurityConfigurationFailureEvent ExceptionMessage, InstanceName Security
SecurityCacheReadPerformedEvent EntityType, TokenUsed, InstanceName Security
LoggingConfigurationFailureEvent ExceptionMessage Logging
LoggingFailureLoggingErrorEvent ErrorMessage, ExceptionMessage Logging
LogEntryV20 All public properties of LogEntry object. Fired by WmiTraceListener Logging
ConnectionFailedEvent ConnectionString, ExceptionMessage, InstanceName Data
CommandFailedEvent CommandText, ConnectionString, ExceptionMessage, InstanceName Data
DataConfigurationFailureEvent ExceptionMessage, InstanceName Data
CacheFailureEvent ErrorMessage, ExceptionMessage, InstanceName Caching
CacheScavengedEvent ItemsScavenged, InstanceName Caching
CacheCallbackFailureEvent Key, ExceptionMessage, InstanceName Caching
CacheConfigurationFailureEvent ExceptionMessage, InstanceName Caching
ExceptionHandlingConfigurationFailureEvent PolicyName, ExceptionMessage Exception Handling
ExceptionHandlingFailureEvent ExceptionMessage, InstanceName Exception Handling
SymmetricOperationFailedEvent ErrorMessage, ExceptionMessage, InstanceName Cryptography
HashMismatchDetectedEvent InstanceName Cryptography
CryptographyConfigurationFailureEvent ExceptionMessage, InstanceName Cryptography


How to listen to a WMI Event

The following sample code shows how to listen to one WMI event fired by the Enterprise Library. Additonally a new WMI Event is defined and fired (not the Enterprise Library way).

using System;

using System.Management.Instrumentation;

using System.Management;

using System.ComponentModel;
using System.Configuration.Install;

 

// WMI Schema namespace (normally defined in AssemblyInfo.cs

[assembly: Instrumented("root/EnterpriseLibrary")] 

 

// You need to add the default installer to your project to be able to add your own WMI event to the system during install

[RunInstaller(true)]

public class Installer : System.Management.Instrumentation.DefaultManagementProjectInstaller

{

}

// define our own WMI Event

[InstrumentationClassAttribute(InstrumentationType.Event)]

public class EntlibStartEvent

{

    public string startMessage;

}

 

class WmiListener

{

    public static int Main(string[] args)

    {

        // you could listen to your own event by using EntlibStartEvent as input for the WqlEventQuery

        WqlEventQuery eventQuery = new WqlEventQuery("LogEntryV20"); // fired by WMI Trace Listener of Logging Block

        ManagementEventWatcher watcher = new ManagementEventWatcher(new ManagementScope(@"root\EnterpriseLibrary"), eventQuery);

 

        watcher.EventArrived += new EventArrivedEventHandler(Arrived);

        watcher.Start();

 

        // fire our own WMI event

        for (int i = 0; i < 100; i++)

        {

            EntlibStartEvent cl = new EntlibStartEvent();

            cl.startMessage = "Speeding up development";

            System.Management.Instrumentation.Instrumentation.Fire(cl);

        }

 

 

        // Wait some time to give the delegate a chance to recieve events

        System.Threading.Thread.Sleep(20000);

 

        // You must stop it every time. Otherwise you will get errors RPC not availiable

        // from the WMI service! Remember this even when you debug.

        watcher.Stop();

 

        return 0;

    }

 

    public static void Arrived(object sender, EventArrivedEventArgs e)

    {

        ManagementBaseObject ev = e.NewEvent;

        if (ev != null)

        {

            // print all properties of the WMI event

            foreach (PropertyData data in ev.Properties)

            {

                Console.WriteLine("{0}:[\"{1}\"]: {2}", data.Origin, data.Name, data.Value);

            }

        }

    }

 

}


WMI Security Issues

Unexpected Security exceptions can be really frustrating. To prevent further pain I share some of the experiences I made with WMI.
  • Only the administrator can (should be able to) update the WMI schema.
  • Before you can fire WMI events you must update the WMI schema by calling installutil <YourAssemblyName>
  • Every ManagementEventWatcher instance which has called Start must call Stop or the WMI Service will go down. This is especially bad when you debug.

To configure WMI security you need to find the WMI administration tool in the first place. It is well hidden in the Control Panel -> Administrative Tools -> Computer Management then right click on WMI and select "Properties" from the context menu. Alternatively you can start the MMC snapin from the command line with wmimgmt.msc. The WMI database is organized in logical namespaces. Here you can allow/deny access to all WMI namespaces and below or only a specific namespace. Below is a screen shot of the WMI security configuration tool.

WMI Security


Performance Counters

They can help you to find in deployment scenarios possible performance bottlenecks or if the system does function properly. Enterprise Library Caching Performance CountersTo get an overview of your current system status you can use Perfmon of Windows or one of the many free resource measurement programs. Programmatic access is possible but a little more difficult since Performance Counters are instance specific. The Enterprise Library Performance Counters have as instance name the executable name plus a postfix. You need to know what instance name your counter of interest has to read from it. Below is a small code example how to access a Windows Performance Counter from C#

            PerformanceCounter PC = new PerformanceCounter();

            PC.CategoryName = "Process";

            PC.CounterName = "Private Bytes";

            PC.InstanceName = "Explorer";

 

                                       MessageBox.Show(PC.NextValue().ToString());

posted on Wednesday, December 14, 2005 6:49 PM

Feedback

# re: Enterprise Library for .NET 2.0 - Instrumentation 2/13/2008 8:50 AM dev
thx a lot buddy, u really helped me out with this instrumentation problem

Post A Comment
Title:
Name:
Email:
Comment:
Verification: