0

私のコード ベースには、問題が発生したときに通知を受けたい場所がたくさんあります。かなり一般的だと思います。次のコードを見て、このメソッドをリファクタリングして、電子メール/ログの詳細を抽象化するにはどうすればよいでしょうか? 現在、約100箇所に散らばっており、何とかしたいです!

public bool MethodOne() {
    string message;
    bool success = new Task().Execute();

    message = string.Format( "MethodOne was {0} successful.", 
        success ? "" : "not");

    if( !success )
        SMTP.send( to, from, message );

    System.Diagnostic.EventLog.WriteEntry( executingAssembly, message);

    return success; 
};

私の現在の考えは、次のようなことをすることです:

public class Log
{
    string to = "me@me.com",
        from = "system@me.com",
        subject = "Error occured";

    public void Write( string executingAssembly, string message, bool sendEmail )
    {
        System.Diagnostic.EventLog.WriteEntry( executingAssembly, message);

        if( sendEmail )
            SendEmail( to, from, subject, message );
    }

    private void SendEmail( to, from, subject, message )
    {
        // Details to send email.
    }
}

質問: アプリケーション内でエラーのログ記録と通知の送信の保守性を向上させるにはどうすればよいですか?

4

5 に答える 5

6

NLogなどの Logging and Log Manager プログラムの使用を検討してください。次に、ログに記録するさまざまな場所 (ターゲット) を指定する nlog.config (または application.config) ファイルにログを記録するための一連のビジネス ルールを記述し、それぞれについてログに記録する内容を指定できます (重大度とクラスに応じて)。 .

NLog Web サイトから取得

一部の NLog がサポートするターゲット

  • ファイル – 単一のファイルまたは複数のファイル、自動ファイル命名およびアーカイブ
  • イベント ログ – ローカルまたはリモート
  • データベース – .NET でサポートされているデータベースにログを保存します
  • ネットワーク – TCP、UDP、SOAP、MSMQ プロトコルを使用
  • コマンドライン コンソール – メッセージの色分けを含む
  • 電子メール – アプリケーション エラーが発生するたびに電子メールを受信できます
  • ASP.NET トレース

NLog を使用する主な機能

  • 構成ファイルとプログラムの両方で構成が非常に簡単
  • log4xxx から知られている使いやすいロガー パターン
  • バッファリング、非同期ロギング、負荷分散、フェイルオーバーなどを使用した高度なルーティング
  • クロスプラットフォームのサポート: .NET Framework、.NET Compact Framework、Mono (Windows および Unix)
于 2012-07-14T15:49:43.747 に答える
0

Microsoft Enterprise Library には、Logging Application BlockException Handling Application Blockという 2 つの非常に優れたブロックがあります。

これは、.config ファイルでさまざまなポリシーを定義できるポリシー ベースのシステムです。ポリシーといくつかの例外ハンドラーを用意したら、次のように catch ブロックを記述できます。

catch(Exception ex)
{
  if(HandleException("My Datalayer Policy", ex)) throw;
} 

例外ポリシーは、イベントをバブリングするかどうかを構成できます。とても素敵な図書館。

Logging ブロックは、カテゴリと呼ばれる .config の「ポリシー」も使用します。たとえば、いくつかのメッセージを記録したいが、他のメッセージは電子メールで送信したい場合、2 つのカテゴリと 2 つのリスナーを使用します。1 つはイベントのログ記録用で、もう 1 つはイベントの詳細を電子メールで送信するためです。Sucess が true の場合など、電子メール カテゴリが指定されていない場合は、ロギング イベントのみが発生します。success が false の場合、"Email" カテゴリが適用され、両方のリスナーが起動します。

于 2012-07-14T15:59:34.150 に答える
0

ここで他の人が提案したロギングの抽象化を抽象化したい場合は、Commons Loggingを使用できます。はい、これは間接的な 2 つのレイヤーですが、これが役立つ状況もあります。

NuGet パッケージをインストールして、次のようにコードで使用できます。

// obtain logger instance
ILog log = LogManager.GetCurrentClassLogger();

// log something
log.Info("Some Debug Log Output");

次に、次のように NLog を使用するようにコモンズ ロギング ライブラリを構成します。

<common>
  <logging>
    <factoryAdapter type="Common.Logging.NLog.NLogLoggerFactoryAdapter, Common.Logging.NLog20">
      <arg key="configType" value="INLINE" />
    </factoryAdapter>
  </logging>
</common>

次に、NLog を構成できます。@Sergey Berezovskiyの回答には、この例があります。

つまり、Commons Loggingライブラリでは、NLog、log4net、Logging Application Block などのいずれかを選択する必要はありません。バックエンドを好きなように切り替えることができます。これは、さまざまな種類のプロジェクトでホストされる可能性のある dll または何かを作成している場合に役立ちます。もちろん、それは無用な間接的な余分なレイヤーになることもあります。それはあなたが何をしているかにかかっています。

于 2014-12-11T17:49:45.360 に答える
0

タスクの実行が成功しないことは例外的なことだと思います (そうしないと、誰かに大量のメールを送信することになります)。したがって、タスクが失敗したときに例外をスローします (タスクが失敗した理由に関する追加の詳細を提供することもできます)。NLogを使用したコードを次に示します。

private static Logger _logger = LogManager.GetCurrentClassLogger();

public bool MethodFoo() 
{
   try
   {
       new Task().Execute();
       _logger.Info("Task executed successfully");
       return true;           
   }
   catch(YourCustomException ex)
   {
       _logger.ErrorException("Cannot execute task", ex);
       return false;
   }
}

残っているのは NLog の設定だけです:

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <targets>
        <target name="eventLog" xsi:type="EventLog" 
                log="Application" source="Your Source" machineName="."
                layout="${longdate}|${level}|${callsite:methodName=true}${message}" />
        <target name="email" xsi:type="Mail" 
                subject="Error occured"
                to="me@me.com"
                from="system@me.com"
                smtpServer="127.0.0.1"
                smtpPort="25"
                body="${longdate}|${message}" />  
    </targets> 
    <rules>
        <logger name="*" minlevel="Info" writeTo="eventLog" />
        <logger name="*" minlevel="Error" writeTo="email" />
    </rules>
</nlog>

2 つのターゲットが必要です。1 つは情報メッセージとエラー メッセージをイベント ログに書き込むため、もう 1 つは電子メールでエラー通知を送信するためです。また、2 つのルールを作成しました。Info レベル以上のすべてのメッセージは Event Log に送信されますが、Error および Fatal メッセージは電子メールで送信されます。

Callsite レイアウト レンダラー${callsite:methodName=true}メソッド名を持つ BTW がログ メッセージに挿入されます。したがって、コードで指定する必要はありません。

于 2012-07-14T17:14:43.143 に答える
0

いくつかのコメント:

ログ クラスは静的クラスである必要があります。
エラー管理で最後に行うべきことは...エラーを発生させることなので、すべてのエラー処理コードを試してキャッチする必要があります。
列挙型を使用して主要なエラーの種類を一覧表示したり、重大度を表す別の種類を一覧表示したりできます / ...
アプリと同じフォルダーにある小さなテキスト ファイルにエラーを記録することをお勧めします。扱いやすく、顧客はメールで送信できます (メールでデータを送信するアプリケーションのアイデアは好きではありません。顧客/ユーザーがこれで問題ないことを確認する必要があります)。
Reflection から実行中のアセンブリやその他の情報を取得できます。
また、StackTrace から他の貴重な情報を取得することもできます (エラー ログに Stacktrace を書き込むことで、かなりの時間を節約できました)。
アプリケーションレベルで未処理の例外もキャッチする必要があります。より具体的な回答のために、さらにいくつかのエラーについて説明してください。

于 2012-07-14T16:01:29.650 に答える