Come accennato nel post originale soluzione proposta è quella di utilizzare ServicePulse per il monitoraggio degli errori. Il client al quale lavoro attualmente utilizza un logger centralizzato personalizzato e vogliamo che NServiceBus esegua il log in questo log store quando i messaggi vengono inoltrati alla coda degli errori.
Avremmo potuto ottenere ciò semplicemente modificando la configurazione di log4net se l'eccezione di NServiceBus includeva l'eccezione originale, attualmente NServiceBus registra solo un messaggio di errore generico senza dettagli su cosa ha causato l'errore.
NServiceBus ha una classe denominata NServiceBus.Faults.ErrorsNotifications che contiene i seguenti osservabili:
- MessageSentToErrorQueue
- MessageHasFailedAFirstLevelRetryAttempt
- MessageHasBeenSentToSecondLevelRetries
È possibile iscriversi a questi osservabili quando il punto finale inizia, come nell'esempio seguente che registra un errore quando i messaggi sono sicuri nt alla coda di errore:
public class GlobalErrorHandler : IWantToRunWhenBusStartsAndStops
{
private readonly ILogger _logger;
private readonly BusNotifications _busNotifications;
readonly List<IDisposable> _notificationSubscriptions = new List<IDisposable>();
public GlobalErrorHandler(ILogger logger, BusNotifications busNotifications)
{
_logger = logger;
_busNotifications = busNotifications;
}
public void Start()
{
_notificationSubscriptions.Add(_busNotifications.Errors.MessageSentToErrorQueue.Subscribe(LogWhenMessageSentToErrorQueue));
}
public void Stop()
{
foreach (var subscription in _notificationSubscriptions)
{
subscription.Dispose();
}
}
private void LogWhenMessageSentToErrorQueue(FailedMessage message)
{
var properties = new
{
MessageType = message.Headers["NServiceBus.EnclosedMessageTypes"],
MessageId = message.Headers["NServiceBus.MessageId"],
OriginatingMachine = message.Headers["NServiceBus.OriginatingMachine"],
OriginatingEndpoint = message.Headers["NServiceBus.OriginatingEndpoint"],
ExceptionType = message.Headers["NServiceBus.ExceptionInfo.ExceptionType"],
ExceptionMessage = message.Headers["NServiceBus.ExceptionInfo.Message"],
ExceptionSource = message.Headers["NServiceBus.ExceptionInfo.Source"],
TimeSent = message.Headers["NServiceBus.TimeSent"]
};
_logger.Error("Message sent to error queue. " + properties, message.Exception);
}
}
Il osservabile è implementato utilizzando reattivi Extensions, quindi si dovrà installare il pacchetto NuGet Rx-Core per questo lavoro.
Questo fa davvero schifo se non puoi usarlo con tentativi di secondo livello. Grazie comunque! –