﻿# Windows Performance Counters


> [!NOTE]
> The NServiceBus.Metrics.PerformanceCounters package is only available for Windows. Newer projects may benefit more from monitoring via [OpenTelemetry](/nservicebus/operations/opentelemetry.md).

The Windows Performance Counters package provides additional performance counters to better understand how long it takes for messages to flow through queues, not just the number of messages in the queue.

Since all performance counters in Windows are exposed via Windows Management Instrumentation (WMI), it is very straightforward to pull this information into the existing monitoring infrastructure.

## Counters

All counters are defined in the NuGet package dependency [NServiceBus.Metrics](https://www.nuget.org/packages/NServiceBus.Metrics/). The dependency is automatically pulled in.

For more information about the metrics defined, consult the [Metrics](index.md) documentation page.


### Configuration

The counters can be enabled using the the following code:

<!-- snippet: enable-criticaltime -->

```cs
var performanceCounters = endpointConfiguration.EnableWindowsPerformanceCounters();
```

<!-- endsnippet -->

In the NServiceBus host, the counters are enabled by default.

Setting up an SLA value can be done using the following code:

<!-- snippet: enable-sla -->

```cs
var performanceCounters = endpointConfiguration.EnableWindowsPerformanceCounters();
performanceCounters.EnableSLAPerformanceCounters(TimeSpan.FromMinutes(3));
```

<!-- endsnippet -->


## Installing counters

The `NServiceBus.Metrics.PerformanceCounter` package installs itself into the MSBuild pipeline and generates all performance counter installation scripts at compile time. It does this by interrogating types (in the target assembly) to infer what scripts to create. It is required for any project where performance counter installation scripts are needed.

### Script creation

Scripts are created in the directory format of `[CurrentProjectDebugDir]\[.NET Version]\NServiceBus.Metrics.PerformanceCounters`.

For example, a project named `ClassLibrary` built in Debug mode will have the following directories created:

 * `ClassLibrary\bin\Debug\[.NET Version]\NServiceBus.Metrics.PerformanceCounters`

Scripts are also included in the list of project output files. The files that are produced will be copied to the output directory of any project that references it. If a script needs to be copied to a directory for inclusion in source control repository, use a [post-build event](https://learn.microsoft.com/en-us/cpp/build/how-to-use-build-events-in-msbuild-projects) to copy the output outside the build directory.

### Force category recreation

The descriptions of some of the performance counters have been changed in the PowerShell script from previous versions for more clarity when viewing counters in the Performance Monitor UI.

By default, the PowerShell script will not recreate counters just to change the descriptions. To force it to recreate the counters, the `-ForceRecreate` switch can be used:

```ps
PS> .\CreateNSBPerfCounters.ps1 -ForceRecreate
```

### Script usage

To use the Powershell script to create performance counters, use the following call with elevated permissions:

```ps
./CreateNSBPerfCounters.ps1
```

To list the installed counters:

```ps
Get-Counter -ListSet NServiceBus | Select-Object -ExpandProperty Counter
```

> [!NOTE]
> Metrics are defined in the `NServiceBus.Metrics` NuGet package and will be dynamically turned into performance counters. When the `NServiceBus.Metrics` dependency is updated, new counters might be available in the installation script. Make sure the scripts are executed with elevated permissions on required machines when the scripts have been updated.

## Performance Monitor Users local security group

When [running installers](/nservicebus/operations/installers.md), the service account will be automatically added to the local Performance Monitor Users group if executed with elevated privileges.


## System.InvalidOperationException

If the endpoint instance throws one of the following exceptions at startup, then [the performance counters need to be reinstalled](#installing-counters)

 * `InvalidOperationException: The requested Performance Counter is not a custom counter, it has to be initialized as ReadOnly.`
 * `InvalidOperationException: NServiceBus performance counter for 'Critical Time' is not set up correctly.`


## Corrupted Counters

Corrupted performance counters can cause the endpoint to either hang completely during startup or fail with the following error:

`NServiceBus performance counter for '{counterName}' is not set up correctly`

Should this happen, try rebuilding the performance counter library using the following steps:

 1. Open an elevated command prompt
 1. Execute the following command to rebuild the performance counter library: `lodctr /r`


### More information

 * [KB2554336: How to manually rebuild Performance Counters for Windows Server 2008 64bit or Windows Server 2008 R2 systems](https://support.microsoft.com/en-us/kb/2554336)
 * [KB300956: How to manually rebuild Performance Counter Library values](https://support.microsoft.com/kb/300956)
 * [LODCTR at TechNet](https://technet.microsoft.com/en-us/library/bb490926.aspx)



> [!NOTE]
> [Send-only endpoints](/nservicebus/endpoints/index.md#send-only) are currently not supported since they don't receive messages.
