2

我正在使用 NServiceBus 4.6 和 Serilog。我已经将 NServiceBus 配置为通过以下方式使用 Serilog:

global::NServiceBus.SetLoggingLibrary.Custom(new SeriLoggerFactory());

工厂本身也很简单:

public class SeriLoggerFactory : ILoggerFactory
{
    public ILog GetLogger(Type type)
    {
        return new SeriLoggerAdapter(Log.ForContext(type));
    }

    public ILog GetLogger(string name)
    {
        var contextLogger = Log.ForContext("SourceContext", name);
        return new SeriLoggerAdapter(contextLogger);
    }
}

我肯定会收到与 NServiceBus 相关的日志条目,但缺少的一件事是处理消息但引发异常时的异常详细信息。我可以在 NServiceBus 消息头中看到异常信息(直接通过查看错误队列中的消息或通过 Service Insight),但 NServiceBus 记录的消息缺少最相关的信息:

ID 为“0d255d19-85f9-4915-a27c-a41000da12ed”的消息 FLR 失败,将移交给 SLR 进行重试尝试 1

或者

SLR 未能解决消息 0d255d19-85f9-4915-a27c-a41000da12ed 的问题,并将被转发到 MYERRORQUEUE 的错误队列

没有关于根异常的任何详细信息会使调试有点困难。它需要开发人员打开 Service Insight,或者打开一个工具来查看队列本身中的消息。两者都很麻烦,并且都缺乏任何可扩展性。

例如,Serilog 允许您创建 ILogEventEnricher 类,这些类可以记录有关异常的特殊详细信息 - 异常的简单 .ToString 未记录的内容。如果没有 NServiceBus 实际记录我的异常,我就无法提取这些详细信息。

我在这里想念什么?

4

1 回答 1

1

NServiceBus 有一个名为 NServiceBus.Faults.ErrorsNotifications 的类,其中包含以下可观察对象:

  • MessageSentToErrorQueue
  • MessageHasFailedAFirstLevelRetryAttempt
  • MessageHasBeenSentToSecondLevelRetries

您可以在端点启动时订阅这些 observables,如下例所示,该示例记录了错误消息被发送到第一级重试:

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.MessageHasFailedAFirstLevelRetryAttempt.Subscribe(LogWhenMessageSentToFirstLevelRetry));
    }

    public void Stop()
    {
        foreach (var subscription in _notificationSubscriptions)
        {
            subscription.Dispose();
        }
    }

    private void LogWhenMessageSentToFirstLevelRetry(FirstLevelRetry 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 first level retry. " + properties, message.Exception);
    }
}

observable 是通过使用 Reactive Extensions 实现的,因此您必须安装 NuGet 包 Rx-Core 才能使其工作。

于 2015-05-21T09:11:47.200 回答