Getting Started
Architecture
NServiceBus
Transports
Persistence
ServiceInsight
ServicePulse
ServiceControl
Monitoring
Samples

Using ServiceControl Events

NuGet Package: ServiceControl.Contracts (1.x)

ServiceControl events enable the construction of custom notifications and integration that will alert when something goes wrong in the system. In addition to monitoring the error queue, ServiceControl receives information from the NServiceBus.Heartbeat and NServiceBus.CustomChecks packages. When messages fail, heartbeats fail to arrive, or custom checks are reported, events published by ServiceControl enable a subscribing endpoint to notify operations personnel however the developer wishes.

See Monitor with ServiceControl events for a sample.

External notification events are sent in batches. If a problem is encountered part way through a batch, the entire batch will be re-sent. This can result in receiving multiple events for a single notification.

Alerting on FailedMessages events

Once a message ends up in the error queue, ServiceControl will publish a MessageFailed event. The message contains:

  • the endpoint that sent and received the message
  • the failure cause (i.e. the exception type and message)
  • the message headers
  • the message body (if it is non-binary, smaller than 85 KB and full-text body indexing is enabled)

Subscribing to ServiceControl events

ServiceControl publishes a MessageFailed event when a message arrives at the error queue. It is possible to subscribe to these events and act on them (e.g. send an email, trigger a text message, etc.).

To subscribe to the MessageFailed event:

  • Create an NServiceBus endpoint.
  • Install the ServiceControl.Contracts NuGet package.
  • Customize the endpoint configuration to use JsonSerializer as the message published by ServiceControl uses JSON serialization.
  • Customize the endpoint configuration so that the following conventions are used, as the events published by ServiceControl do not derive from IEvent.

This code sample illustrates how to do this customization:

endpointConfiguration.UseSerialization<JsonSerializer>();
var conventions = endpointConfiguration.Conventions();
conventions.DefiningEventsAs(
    type =>
    {
        return typeof(IEvent).IsAssignableFrom(type) ||
               // include ServiceControl events
               type.Namespace != null &&
               type.Namespace.StartsWith("ServiceControl.Contracts");
    });
  • The endpoint will also need a message handler that handles the MessageFailed event. In the following example, there is a simple HTTP call to HipChat's API to show how to integrate with a third-party system to provide notification of the error.
class MessageFailedHandler :
    IHandleMessages<MessageFailed>
{
    public Task Handle(MessageFailed message, IMessageHandlerContext context)
    {
        var failedMessageId = message.FailedMessageId;
        var exceptionMessage = message.FailureDetails.Exception.Message;

        var chatMessage = $@"Message with id: {failedMessageId} failed.
Reason: '{exceptionMessage}'.
Open in ServiceInsight: {GetServiceInsightUri(failedMessageId)}";

        using (var client = new HipchatClient())
        {
            client.PostChatMessage(chatMessage);
        }
        return Task.CompletedTask;
    }
Endpoints that subscribe to ServiceControl events should not use the same error and audit queues as other endpoints. Using the same error queue could cause an infinite feedback loop if processing a MessageFailed message failed. Using the same audit queue will cause the processing of the MessageFailed messages to be included in the ServiceInsight search results. This could confuse users searching for a given failure since both the failure and the failure notification will be shown. See also: Recoverability and Audit Queue Settings.

Registering the publisher for message-driven publish/subscribe

Transports that use message-driven publish-subscribe must have the ServiceControl instance registered as the publisher of the MessageFailed event.

For NServiceBus version 6 and higher, the routing config code API can be used:

var routing = transport.Routing();
routing.RegisterPublisher(typeof(ServiceControl.Contracts.MessageFailed).Assembly, "Particular.ServiceControl");

For NServiceBus version 5 and below, add the message mapping in the UnicastBusConfig section of the endpoint's app.config :

<UnicastBusConfig>
  <MessageEndpointMappings >
    <add Assembly="ServiceControl.Contracts"
         Endpoint="Particular.ServiceControl" />
  </MessageEndpointMappings>
</UnicastBusConfig>
Transports that natively support publish and subscribe do not require any additional configuration.

Monitoring events

ServiceControl will also publish events based on collected monitoring data.

See Heartbeat Notification Events and Custom Check Notification Events for a description of these events.

Other events

Events described in this section are published by ServiceControl starting with version 4.17.

ServiceControl will also publish events related to archiving and retrying messages:

  • FailedMessagesArchived: Event emitted for failed messages that were archived
  • FailedMessagesUnArchived: Event emitted for failed messages that were un-archived
  • MessageFailureResolvedByRetry: Event emitted by ServiceControl for each failed message that was resolved by retry
  • MessageFailureResolvedManually: Event emitted by ServiceControl for each failed message that was resolved manually

Decommissioning subscribers to ServiceControl events

ServiceControl uses event publishing to expose information to subscribers. When using a persistence-based transport an internal reference will be kept to each subscriber. If a subscriber for an event cannot be contacted then a log entry will be written with the following error:

Failed dispatching external integration event

An event will also be published and displayed in the ServicePulse dashboard with the following text:

'EVENTTYPE' failed to be published to other integration points. Reason for failure: REASON.

To avoid this situation it is important to properly decommission an endpoint that subscribes to ServiceControl events. To do this, disable auto-subscription and then unsubscribe from all events.

Samples

Related Articles