2

NServiceBus 4.6 と Serilog を使用しています。次の方法で Serilog を使用するように NServiceBus を構成しました。

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 によってログに記録されたメッセージには最も関連性の高い情報がありません。

「0d255d19-85f9-4915-a27c-a41000da12ed」ID のメッセージは FLR に失敗し、再試行 1 のために SLR に渡されます

また

SLR はメッセージ 0d255d19-85f9-4915-a27c-a41000da12ed の問題を解決できず、MYERRORQUEUE のエラー キューに転送されます

ルート例外に関する詳細がないため、デバッグが少し難しくなります。開発者は Service Insight を開くか、ツールを開いてキュー自体のメッセージを表示する必要があります。どちらも扱いにくく、拡張性に欠けています。

たとえば、Serilog を使用すると、問題の例外に関する特別な詳細を記録できる ILogEventEnricher クラスを作成できます。これは、例外の単純な .ToString では記録されないものです。NServiceBus が実際に例外をログに記録しない限り、これらの詳細を抽出する方法はありません。

ここで何が欠けていますか?

4

1 に答える 1

1

NServiceBus には、次のオブザーバブルを含む NServiceBus.Faults.ErrorsNotifications という名前のクラスがあります。

  • MessageSentToErrorQueue
  • MessageHasFailedAFirstLevelRetryAttempt
  • MessageHasBeenSentToSecondLevelRetries

次の例のように、エンドポイントの開始時にこれらのオブザーバブルをサブスクライブできます。この例では、エラー メッセージが最初のレベルの再試行に送信されます。

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);
    }
}

オブザーバブルは Reactive Extensions を使用して実装されるため、これを機能させるには NuGet パッケージ Rx-Core をインストールする必要があります。

于 2015-05-21T09:11:47.200 に答える