locked
Unable to delete custom performance counter category RRS feed

  • Question

  • Hi, 

    I have created a performance counter category and I am not able to delete it. Running this:

    $categoryName = "NServiceBus"
    [System.Diagnostics.PerformanceCounterCategory]::Exists($categoryName)
    [System.Diagnostics.PerformanceCounterCategory]::delete($categoryName)

    Returns this

    True
    Exception calling "Delete" with "1" argument(s): "Cannot create file mapping."
    At line:6 char:1
    + [System.Diagnostics.PerformanceCounterCategory]::delete($categoryName ...
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : InvalidOperationException
    

    I have followed the instructions in this knowledgebase article (https://support.microsoft.com/en-au/help/2554336/how-to-manually-rebuild-performance-counters-for-windows-server-2008-6) to rebuild the counters in 32-bit and 64-bit, as well as resync-ing WMI. I have restarted the computer. I have verified that the counter details are present in the registry and that the DisablePerformanceCounters key is not present.

    I dug up the code that is throwing the exception (https://github.com/microsoft/referencesource/blob/4.6.2/System/services/monitoring/system/diagnosticts/SharedPerformanceCounter.cs#L1614) to try and better understand what is going on. I do not believe I am somehow exhausting the 14 retry attempts as the exception is thrown immediately.

    The documentation for the Delete(...) call (https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.performancecountercategory.delete?view=netframework-4.6.1) suggests that it will throw InvalidOperationException if this is not a custom category but I know that it is because I created it with a call to Create(...) (https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.performancecountercategory.create?view=netframework-4.6.1)

    I am trying to delete the custom performance counter category from an elevated command prompt so I do not think this is permissions-related. It does seem that the system is not able to create (or open) the memory mapped file with the specified name but I don't know what conditions can cause that.

    This is .NET 4.6.1 running on Windows 2008 R2. I now have several servers somehow stuck in this state.

    Thanks,
    Mike

    P.S. This is the script that creates the category in the first place

    [CmdletBinding()]
    param(
      [switch]$ForceRecreate
    )
    
    #requires -RunAsAdministrator
    
    $category = @{Name="NServiceBus"; Description="NServiceBus statistics"}
    $counters = New-Object System.Diagnostics.CounterCreationDataCollection
    $counters.AddRange(@(
    	New-Object System.Diagnostics.CounterCreationData "SLA violation countdown", "Duration in seconds until the configured Service Level Agreement (SLA) for this endpoint is breached. This is an instantaneous snapshot, not an average over the time interval.",  NumberOfItems32
    	New-Object System.Diagnostics.CounterCreationData "Critical Time Average", "Average duration in seconds for sending and processing of all messages during the sample interval. Useful to understand how long a new message added to the queue right now will take to be processed.",  AverageTimer32
    	New-Object System.Diagnostics.CounterCreationData "Critical Time AverageBase", "A base counter used to calculate the Critical Time Average",  AverageBase
    	New-Object System.Diagnostics.CounterCreationData "Critical Time", "Duration in seconds for sending and processing the last processed message, useful to understand how long a new message added to the queue right now will take to be processed. This is an instantaneous snapshot, not an average over the time interval.",  NumberOfItems32
    	New-Object System.Diagnostics.CounterCreationData "Processing Time Average", "Average duration in seconds of all successfully processed messages during the sample interval.",  AverageTimer32
    	New-Object System.Diagnostics.CounterCreationData "Processing Time AverageBase", "A base counter used to calculate the Processing Time.",  AverageBase
    	New-Object System.Diagnostics.CounterCreationData "Processing Time", "Duration in seconds of the last successfully processed message. This is an instantaneous snapshot, not an average over the time interval.",  NumberOfItems32
    	New-Object System.Diagnostics.CounterCreationData "# of msgs failures / sec", "The current number of failed processed messages by the transport per second.",  RateOfCountsPerSecond32
    	New-Object System.Diagnostics.CounterCreationData "# of msgs successfully processed / sec", "The current number of messages processed successfully by the transport per second.",  RateOfCountsPerSecond32
    	New-Object System.Diagnostics.CounterCreationData "# of msgs pulled from the input queue /sec", "The current number of messages pulled from the input queue by the transport per second.",  RateOfCountsPerSecond32
    	New-Object System.Diagnostics.CounterCreationData "Retries", "A message has been scheduled for retry (FLR or SLR)",  RateOfCountsPerSecond32
    
    ))
    
    if ([System.Diagnostics.PerformanceCounterCategory]::Exists($category.Name)) {
    
    	if($ForceRecreate) {
    		Write-Host "Option -ForceRecreate was used. The performance counter category will be recreated"
    		[System.Diagnostics.PerformanceCounterCategory]::Delete($category.Name)
    	} 
    	else {
    		foreach($counter in $counters){
    			$exists = [System.Diagnostics.PerformanceCounterCategory]::CounterExists($counter.CounterName, $category.Name)
    			if (!$exists){
    				Write-Host "One or more counters are missing.The performance counter category will be recreated"
    				[System.Diagnostics.PerformanceCounterCategory]::Delete($category.Name)
    
    				break
    			}
    		}
    	}
    }
    
    if (![System.Diagnostics.PerformanceCounterCategory]::Exists($category.Name)) {
    	Write-Host "Creating the performance counter category"
    	[void] [System.Diagnostics.PerformanceCounterCategory]::Create($category.Name, $category.Description, [System.Diagnostics.PerformanceCounterCategoryType]::MultiInstance, $counters)
    	}
    else {
    	Write-Host "No performance counters have to be created"
    }
    
    [System.Diagnostics.PerformanceCounter]::CloseSharedResources()

    Friday, January 24, 2020 3:01 AM