8

当社の WF4 ワークフロー サービスでは、可能な限り堅牢になるように努めています。私たちが行うことの 1 つは、HandleError および ProvideFault ( IErrorhandler ) 内のエラーをログに記録することです。ドキュメントには、HandleError がログを記録するのに適切な場所であることが明確に記載されていますが、いくつかの奇妙なことが起こることがわかります。

  1. ProvideFaultのみをトリガーし、HandleErrorをトリガーしないいくつかのエラーが表示されます。1 つの例は次のとおりです。

    System.NullReferenceException: オブジェクト参照がオブジェクトのインスタンスに設定されていません。System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult.GetInstance() で System.ServiceModel.Activities.Dispatcher.DurableInstanceManager.GetInstanceAsyncResult..ctor で

  2. HandleErrorのみをトリガーし、ProvideFault をトリガーしないエラーもいくつかあります。1 つの例は次のとおりです。

    System.ServiceModel.CommunicationException: パイプからの読み取り中にエラーが発生しました: パイプは終了しました。(109、0x6d)。System.ServiceModel.Channels.PipeConnection.Read (Byte[] バッファー、Int32 オフセット、Int32 サイズ、TimeSpan タイムアウト) で System.ServiceModel.Channels.SessionConnectionReader.Receive (TimeSpan タイムアウト) で

  3. 最後に、最初に ProvideFault と次に HandleError (バックグラウンド スレッドで) の両方をトリガーするエラーがあります。

  4. 可能であれば、対応する着信メッセージもログに記録したいと考えています。私はOperationContext.Current.RequestContext.RequestMessage.ToString()でこれを行います。これは通常、ProvideFault でのみ機能します。HandleError では、RequestContext はもうありません。

したがって、私の結論は、すべてのエラーをログに記録するには、両方の方法でログインする必要があるということでした。しかし、それは 3.. が原因で、多くの重複したログ エントリにつながります。

私の現在の回避策は、ProvideFault から最後にログに記録された例外を「記憶」し、同じ例外が HandleError に入った場合は無視することでした。私にはあまりきれいに見えません。

WF サービス内で発生する可能性のあるすべてのエラーをログに記録するための、より優れた信頼できる方法はありますか?

また、HandleError または ProvideFault 内で IErrorHandler を使用して WCF で例外をログに記録することを指摘しないでください。それは何の助けにもならないからです。

4

1 に答える 1

0

シナリオ 2 が別のコンテキスト (BizTalk アダプター) で発生するのを見てきましたHandleErrorが、アダプターで例外が発生したために呼び出されたようですが、実際に返すメッセージがProvideFaultないため呼び出されませんでした。アダプターがメッセージを実際に生成/読み取り/変換してパイプラインに渡すのを防ぐ方法。これにより、障害メッセージが生成されることさえ妨げられているようです。パイプからの読み取りに失敗すると、これを構成しているように見えます-サービスは、接続さえしなかったために失敗したのか、リモートサーバーが失敗したために失敗したのかわかりません。のようなものTransactionAbortedExceptionもこれを引き起こす可能性があり、(私の特定のケースでは) aSqlExceptionが原因になる可能性があります。

これは、私が見たことも再現したこともないケース #1 の手がかりになるはずです。これは、メッセージング チェーンのどこかで不適切な例外処理が原因です。この場合、障害メッセージが生成されましたが、チェーンの上位にある何かが、HandleError呼び出し可能な方法で例外を処理できませんでした。ここでANullReferenceExceptionは理にかなっています。null チェックを適切に処理しないと、この種のケースで他に何が起こるかを言うのは困難です。

これを解決する限り、ログがどこから来たのかを説明する追加情報とともに、おそらく両方の場所にログインしようとします。ロギングが重複していても、それはフェイルセーフです。一方、これらのシナリオのいずれかまたは両方を生成する例外のリストがある場合は、ロジックを実装して、例外の種類 (または発生した場所) を確認することができます。別の方法で処理される可能性があります。

于 2016-01-26T23:36:44.330 に答える