3

システム上のユーザーのアクションをログに記録し、データベースに保存する関数を C# で作成しています。具体的には、ビジネスロジックの特定の機能が呼び出されたときにログに記録したいと考えています。私は次のようなロギング方法を考え出しました:

public static LogMethod(string user, string methodName, object[] parameters, string message)

メソッド内ではToString()、各パラメーターに対して適切な関数が呼び出されます。たとえば、メソッド Foo の場合、次のように呼び出されます。

void Foo(int a, SomeObject b)
{
     Logger.LogMethod(username, "Foo", new object[]{a,b}, "Beginning Foo");
     //etc
}

関数呼び出しをログに記録するのは良い方法ですか? この目的を実現するためのベスト プラクティスは何ですか? パフォーマンスに悪い影響を与えますか?

4

4 に答える 4

3

はい、リフレクションを使用して MethodInfo を取得してから呼び出す必要があるため、パフォーマンスに影響します。それに加えて、メソッド名をリファクタリングできないため、保守性が損なわれます。

代替手段については、次の以前の Q&A を参照してください: C# でメソッド呼び出しをインターセプトするにはどうすればよいですか?

于 2012-05-07T16:14:52.763 に答える
3

美しいビジネス ロジックにロギング ロジックを散らかさないでください。これは分野横断的な懸念事項です。ログに記録するメソッドをインターセプトするには、メソッド インターセプトのような手法を使用する必要があります。

関数呼び出しをログに記録するのは良い方法ですか?

いいえ、そうではありません。コードは、ビジネス ロジックの実行とロギングに関係するようになりました。それは、書くのもテストするのも保守するのも非常に難しいコードです。

この目的を実現するためのベスト プラクティスは何ですか?

この問題を解決する方法を見つけることをお勧めします. これに対する標準的な解決策は、メソッド インターセプトやアスペクト指向プログラミングなどを使用することです。これを実現するには多くの方法があります (多くのフレームワークの 1 つを使用して設定できますが、私はウィンザー城に傾倒しています)。

パフォーマンスに悪い影響を与えますか?

その質問に答えられるのはあなただけです。ユーザーが何をしているかなどをログに記録している場合は、そうではありません。ユーザーは遅くて頭が悪く、遅いディスクやデータベースなどを使用するため、何かをログに記録するのに数ミリ秒余分にかかっても気にしない可能性があります。ここではクリティカル ループについて話しているわけではありません。しかし、それが容認できないほど遅いかどうかを判断できるのはあなただけです。また、ロギングの有無にかかわらず独自のアプリケーションを測定して、容認できないほど遅いかどうかを確認できるのはあなただけです。

于 2012-05-07T16:15:01.617 に答える
2

すべてがパフォーマンスに影響しますが、効果が「悪い」かどうかは主観的です。また、メソッドを呼び出す頻度にも完全に依存します。

引数を再設定してparamsキーワードを使用すると、呼び出しを簡略化できます。

public static LogMethod(string user, string methodName, string message, params object[] parameters)

これで、呼び出しが簡単になります。

Logger.LogMethod(username, "Foo", "Beginning Foo", a, b);

オブジェクト配列を宣言する必要はありません。コンパイラがこれを処理します。paramsを参照してください。

また、スタックから呼び出し元のメソッド名を取得することで、呼び出しをさらに簡素化できます。

public static LogMethod(string user, string message, params object[] parameters)
{
    string methodName = new StackFrame(1).GetMethod().Name;
    ...      
}

これで、methodNameパラメーターは必要ありません。(.Net 4.5では、 CallerMemberNameAttributeを使用して同じことを実現できます。)

リフレクションを使用すると、さらに先に進むことができます。たとえば、呼び出し元のメソッドに渡されたパラメーターの名前、クラスの名前などを取得できます。

于 2012-05-07T16:21:33.087 に答える
2

他の人がすでに指摘しているように、AOP フレームワークはおそらく進むべき道です。


それでもこの方法を使用したい場合は、少し改善することができます。パラメータを最後に置く場合は、paramsキーワードを使用できます。

public static LogMethod(string user, string methodName, string message,
                        params object[] parameters)

これにより、メソッドの呼び出しが幾分簡単になります。

void Foo(int a, SomeObject b)
{
    Logger.LogMethod(username, "Foo", "Beginning Foo", a, b);
    //etc  
}  
于 2012-05-07T16:15:32.210 に答える