# Monitor ServiceControl events with Azure Application Insights This sample shows how to monitor a running NServiceBus system with ServiceControl and ServicePulse as well as how to integrate with existing monitoring solutions. The sample uses the [learning transport](/transports/learning/index.md) and a portable version of the Particular Service Platform tools. Installing ServiceControl is **not** required. ## Connect to Application Insights Azure Monitor To connect the sample code to Application Insights, the instrumentation key must be provided. The key is set in a string variable, as shown in the snippet below. The instrumentation key can be retrieved from the Azure Portal by locating the Application Insights instance, then navigating to the Properties view. ```cs var telemetryConfiguration = TelemetryConfiguration.CreateDefault(); telemetryConfiguration.ConnectionString = appInsightsConnectionString; var telemetryClient = new TelemetryClient(telemetryConfiguration); ``` ## Running the project Running the project shows three console windows: 1. **NServiceBusEndpoint**: The endpoint that represents the system being monitored. 1. **AzureMonitorConnector**: The endpoint that subscribes to ServiceControl notification events and pushes them to Application Insights as custom telemetry events. 1. **PlatformLauncher**: Runs an in-process version of ServiceControl and ServicePulse. When the ServiceControl instance is ready, a browser window is launched displaying the ServicePulse dashboard. The samples triggers two types of events: ### Message failures A `MessageFailed` event is emitted when processing a message fails and the message is moved to the error queue. To observe this in action, press Enter in the `NServiceBusEndpoint`console window. The application will generate a new `SimpleMessage` event that fails when processed. > [!NOTE] > The exception will cause the debugger to enter a breakpoint. Detach the debugger in order to better observe what's going on. When a `MessageFailed` event is received, the `AzureMonitorConnector` prints the following message in its console window: ``` > Received ServiceControl 'MessageFailed' event for a SimpleMessage with ID 42f25e40-a673-61f3-a505-c8dee6d16f8a ``` The failed message can also be viewed in the ServicePulse browser window. Navigating to the failed message shows more details about the message failure. ### Heartbeat statuses The `HeartbeatStopped` event is published whenever an endpoint fails to send a control message within an expected interval. The `HeartbeatRestored` event is published whenever the endpoint successfully sends a control message again. > [!NOTE] > The monitor must receive at least one control message before it can observe that the endpoint stopped responding. To observe this in action, stop the `NServiceBusEndpoint` process and wait up to 30 seconds. When a `HeartbeatStopped` event is received, the `AzureMonitorConnector` prints the following message to the console window: > `Heartbeat from NServiceBusEndpoint stopped.` Next, restart the `NServiceBusEndpoint` application and wait up to 30 seconds. When a `HeartbeatRestored` event is received, the `AzureMonitorConnector` prints the following message in its console window: > `Heartbeat from EndpointsMonitoring.NServiceBusEndpoint restored.` ## Code walk-through ### NServiceBusEndpoint Retries are disabled in the sample for simplicity; messages are immediately moved to the error queue after a processing failure: ```cs var recoverability = endpointConfiguration.Recoverability(); recoverability.Delayed( customizations: retriesSettings => { retriesSettings.NumberOfRetries(0); }); recoverability.Immediate( customizations: retriesSettings => { retriesSettings.NumberOfRetries(0); }); ``` The `MessageFailed` event is published whenever ServiceControl detects a new message in the error queue. In order to receive `HeartbeatStopped` and `HeartbeatRestored` events, the endpoint must use the [heartbeats plugin](/monitoring/heartbeats/index.md). > [!NOTE] > Heartbeat control messages are sent [every 30 seconds by default](/monitoring/heartbeats/install-plugin.md#heartbeat-interval) so there will be up to a 30 second delay before ServiceControl realizes that it lost or restored connection with the endpoint. ### AzureMonitorConnector In order to get notifications when the exposed ServiceControl events occur, create an NServiceBus endpoint. Next, reference the `ServiceControl.Contracts` NuGet package and implement a handler which handles specific ServiceControl events: ```cs public class MessageFailedHandler : IHandleMessages { readonly TelemetryClient telemetryClient; static ILog log = LogManager.GetLogger(); public MessageFailedHandler(TelemetryClient telemetryClient) { this.telemetryClient = telemetryClient; } public Task Handle(MessageFailed message, IMessageHandlerContext context) { telemetryClient.TrackEvent("Message Failed", new Dictionary { {"MessageId", message.FailedMessageId}, }); log.Error($"Received ServiceControl 'MessageFailed' event for a {message.MessageType} with ID {message.FailedMessageId}."); return Task.CompletedTask; } } ``` The handler creates a custom telemetry event and pushes it to Application Insights. ## Notes on other transports This sample uses the [learning transport](/transports/learning/index.md) in order to be portable with no transport dependencies. When adjusting this sample to use the [Azure Service Bus transport](/transports/azure-service-bus/index.md), note that the subscribing endpoint must also use the same name shortening strategy as ServiceControl. See the [configuration settings](/transports/azure-service-bus/configuration.md#entity-creation). The same applies to the [Azure Storage Queues](/transports/azure-storage-queues/index.md) name [sanitization strategy](/transports/azure-storage-queues/sanitization.md#backward-compatibility-with-versions-7-and-below)