2016-04-26 7 views
0

私は、メッセージブローカー(サービスバス)を介して連携して動作する複数のサービス(プロセス)で構成される分散システムに取り組んでいます。これらのサービスの中には時間が非常に敏感なものもあるため、他のすべてのサービスの例外を順番に(データベース/ディスクに)記録するための中心点として使用されるサービスに例外を伝播するという考え方がありましたメッセージの送信がディスクへの書き込みよりも高速であることがわかっているため、サービスに遅延が発生することはありません。したがって、NLogを使用して、バス上で例外を送信するための新しいターゲットを作成し、すべてのサービス例外処理をそのバスにリダイレクトします。C#:型付き例外を別のプロセスに送信する - >基本例外に変換する?

基本的なフレームワークの例外はうまく動作しますが、いくつかの例外はかなり複雑なオブジェクトになることがあります。異なるライブラリを使用する場合、シリアル化可能でない例外(例:IronPython)だけでなく、ExceptionLoggerサービスは他のすべてのエンドポイントで使用されるすべての外部DLLを参照しないため、型付き例外をインスタンス化できません。

は、ここで私は私の問題を解決しなければならなかったいくつかのアイデアですが、どれも仕事:

  1. は他のサービスで使用されるすべてのDLLの例外ロガーサービス参照を持っています。私の意見では、これはきれいで、かなり過剰なものではなく、シリアル化されずにバスに渡されない例外のケースを扱っていません。

  2. データのみを渡すための例外を継承しないカスタムクラスを作成します(Antony Boothメソッドとしてここに:How to serialize an Exception object in C#?)。この問題は、例外ログエンドポイントでこのクラスのインスタンスを受け取り、ログをトリガーしたいときに、NLog LogEventInfoオブジェクトを作成するために、そこから新しいException()を作成できないという問題があります。

  3. バスで送信する前に、特別に型指定された例外を基本の例外型に変換します。このようにして、いくつかの情報は失われますが、私は必要なものすべてであるMessage、Stacktrace、およびInnerExceptionスタックを保持します。残念ながら、私はそれを行う方法を見つけることができず、それが可能であるとは思わない。

これは、私が全体のアイデアの関連性に疑問を抱かせると、私は単に間違った経路に入りますか?

+0

オプション3の問題点を教えてください。必要なのは基本的な 'Exception'プロパティだけですが、なぜこれはあなたのためには機能しませんでしたか? – Mikanikal

+0

例外コンストラクタはパラメータとしてMessageとInnerExceptionを取るだけで、スタックトレースのような他のプロパティはゲッターだけを持ち、設定する方法はありません。 – Dunge

+0

リモートプロセスで例外をキャッチできるようにするには、シリアライズ可能である必要があります。しかし、あなたがやってみたいことがログに記録されていれば、Exception.ToString()を呼び出して、結果の文字列をリモートプロセスに送るのはなぜですか?この文字列には、InnerExceptionおよびStackTrace情報が含まれます。 – Joe

答えて

0
[Serializable] 
public sealed class SerializableException : Exception 
{ 
    public SerializableException() 
    { 
    } 

    public SerializableException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 

    public SerializableException(Exception exception) 
     : base(exception.Message, exception.InnerException == null ? null : new SerializableException(exception.InnerException)) 
    { 
     _data = exception.Data; 
     HelpLink = exception.HelpLink; 
     HResult = exception.HResult; 
     Source = exception.Source; 
     _stackTrace = exception.StackTrace; 
    } 

    public override IDictionary Data { get { return _data; } } 
    public override string StackTrace { get { return _stackTrace; } } 

    private readonly IDictionary _data; 
    private readonly string _stackTrace; 
} 
0

オプション4. Exceptionアセンブリを作成して、組織内にすべてのカスタム例外タイプを格納し、他のすべてのサービスでそのアセンブリを参照します。これは例外の中央ストアです。

+0

私たちが使用している外部ライブラリによってスローされた例外は、ソースがない(アセンブリとして参照されている、nugetパッケージから得られた)のはどうですか?この例外集に私を含めることができないのですか? – Dunge

+0

ロギング用の場合は、元の(型付きの)例外インスタンスはもう必要ありません。例外オブジェクトの状態だけが必要です。オプションは、あなたの要件を満たす自家製ラッパークラスに、外国語/厄介な例外の種類のプロパティを反映させることです。 –

+0

これは私の質問ですが、StackTraceのような読み込み専用のプロパティは、基本型またはソースからの自作のラッパーのいずれかの例外にどのようにフィードするのですか? – Dunge

関連する問題