G
Guest
I am attempting to instrument several existing Windows service applications
(written in C#) using the PerformanceCounter* classes in .Net FW 1.1 SP1.
Each service must dynamically add its required counters based on
configuration metadata from SQL Server using the service name as the
Category, and to this end I have the following code snippet:
/// <summary>
/// This method exports the statistics for this process to PerfMon. This
must be called
/// at the end or process initialization so that all statistics for the
process are
/// registered.
/// If this is called multiple times the existing data structure is
replaced by an
/// updated version. This allows, if rather clumsily, counters to be
added after
/// AppManager has completed process initialization.
/// </summary>
/// <returns></returns>
public void ExportStatistics()
{
lock (this)
{
// Remove any hanging or previously-created category information
if (PerformanceCounterCategory.Exists( _perfMonCategoryName ))
{
PerformanceCounterCategory.Delete( _perfMonCategoryName );
}
.... boring details of actual counter setup omitted.
The first call to this method works OK - registry keys named "Linkage" and
"Performance" are added to
HKLM\System\CurrentControlSet\Services\<category-name>, which already exists
because that's the service which is going to publish the counters.
Now, when a revised list of counters needs to be published, the entire
category has to be discarded and recreated, per the following text in MSDN's
description of PerformanceCounterCategory.Delete:
"Remarks
You can delete only custom performance counter categories from the system.
You cannot delete a counter from a category. To do so, delete the category
and recreate the category with the counters you want to retain."
At this point the code snippet above finds .Exists=True and calls .Delete.
I walked through this in the debugger and the entire registry key at
HKLM\System\CurrentControlSet\Services\<category-name/service-name> is
deleted by this method call. This seems like a bug, because it's impossible
under this behaviour to instrument a .Net service with revised Performance
Counters without requiring a full reinstall. This is since my service (and
any other I have ever known) stores its configuration bootstrap data under a
"Parameters" subkey of this now-deleted service Registry placeholder.
Is there a fix for this available or planned? I am sure there are hacks I
could use to get around this (e.g. use a name mapping to put the Category
info in a different place in the Registry from the rest of the service
configuration), but the current behaviour seems clearly incorrect.
(written in C#) using the PerformanceCounter* classes in .Net FW 1.1 SP1.
Each service must dynamically add its required counters based on
configuration metadata from SQL Server using the service name as the
Category, and to this end I have the following code snippet:
/// <summary>
/// This method exports the statistics for this process to PerfMon. This
must be called
/// at the end or process initialization so that all statistics for the
process are
/// registered.
/// If this is called multiple times the existing data structure is
replaced by an
/// updated version. This allows, if rather clumsily, counters to be
added after
/// AppManager has completed process initialization.
/// </summary>
/// <returns></returns>
public void ExportStatistics()
{
lock (this)
{
// Remove any hanging or previously-created category information
if (PerformanceCounterCategory.Exists( _perfMonCategoryName ))
{
PerformanceCounterCategory.Delete( _perfMonCategoryName );
}
.... boring details of actual counter setup omitted.
The first call to this method works OK - registry keys named "Linkage" and
"Performance" are added to
HKLM\System\CurrentControlSet\Services\<category-name>, which already exists
because that's the service which is going to publish the counters.
Now, when a revised list of counters needs to be published, the entire
category has to be discarded and recreated, per the following text in MSDN's
description of PerformanceCounterCategory.Delete:
"Remarks
You can delete only custom performance counter categories from the system.
You cannot delete a counter from a category. To do so, delete the category
and recreate the category with the counters you want to retain."
At this point the code snippet above finds .Exists=True and calls .Delete.
I walked through this in the debugger and the entire registry key at
HKLM\System\CurrentControlSet\Services\<category-name/service-name> is
deleted by this method call. This seems like a bug, because it's impossible
under this behaviour to instrument a .Net service with revised Performance
Counters without requiring a full reinstall. This is since my service (and
any other I have ever known) stores its configuration bootstrap data under a
"Parameters" subkey of this now-deleted service Registry placeholder.
Is there a fix for this available or planned? I am sure there are hacks I
could use to get around this (e.g. use a name mapping to put the Category
info in a different place in the Registry from the rest of the service
configuration), but the current behaviour seems clearly incorrect.