web-dev-qa-db-ja.com

ELMAHを使用して手動でエラーを記録する方法

ELMAHを使用して次のことを実行できますか?

logger.Log(" something");

私はこのようなことをしています:

try 
{
    // Code that might throw an exception 
}
catch(Exception ex)
{
    // I need to log error here...
}

この例外は、処理されたため、ELMAHによって自動的にログに記録されません。

256
Omu

ELMAH 1.0以降で機能する直接ログ書き込み方法:

try 
{
    some code 
}
catch(Exception ex)
{
    Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
}

ELMAH 1.2は、より柔軟なAPIを導入しています。

try 
{
    some code 
}
catch(Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}

2つのソリューションには違いがあります。

  • Raiseメソッドは、例外にELMAHフィルタリングルールを適用します。 Logメソッドはサポートしていません。
  • Raiseはサブスクリプションベースであり、1つの例外を複数のロガーに記録できます。
405
Andrey Kamaev

Elmahへの呼び出しを、独自の単純なラッパークラスでラップすることをお勧めします。

using Elmah;

public static class ErrorLog
{
    /// <summary>
    /// Log error to Elmah
    /// </summary>
    public static void LogError(Exception ex, string contextualMessage=null)
    {
        try
        {
            // log error to Elmah
            if (contextualMessage != null) 
            {
                // log exception with contextual information that's visible when 
                // clicking on the error in the Elmah log
                var annotatedException = new Exception(contextualMessage, ex); 
                ErrorSignal.FromCurrentContext().Raise(annotatedException, HttpContext.Current);
            }
            else 
            {
                ErrorSignal.FromCurrentContext().Raise(ex, HttpContext.Current);
            }

            // send errors to ErrorWS (my own legacy service)
            // using (ErrorWSSoapClient client = new ErrorWSSoapClient())
            // {
            //    client.LogErrors(...);
            // }
        }
        catch (Exception)
        {
            // uh oh! just keep going
        }
    }
}

その後、エラーをログに記録する必要があるときに呼び出します。

try {
   ...
} 
catch (Exception ex) 
{
    // log this and continue
    ErrorLog.LogError(ex, "Error sending email for order " + orderID);
}

これには次の利点があります。

  • Elmah呼び出しのこのわずかに古風な構文を覚えておく必要はありません。
  • 多くのDLLがある場合は、すべてのDLLからElmah Coreを参照する必要はありません-これを独自の「システム」DLLに入れるだけです。
  • 特別な処理を行う必要がある場合、またはエラーをデバッグするためにブレークポイントを配置するだけの場合は、すべて1か所で行うことができます。
  • エルマから離れた場合は、1か所だけ変更できます。
  • 保持したいレガシーエラーログがある場合(いくつかのUIに関連付けられている単純なエラーログメカニズムがあり、すぐに削除する時間はありません)。

注:コンテキスト情報用に「contextualMessage」プロパティを追加しました。必要に応じてこれを省略できますが、非常に便利です。 Elmahは例外を自動的にアンラップするため、基になる例外は引き続きログに報告されますが、クリックするとcontextualMessageが表示されます。

90
Simon_Weaver

Elmah.ErrorSignal()メソッドを使用して、例外を発生させることなく問題を記録できます。

try
{
    // Some code
}
catch(Exception ex)
{
    // Log error
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

    // Continue
}
29
bigtv
catch(Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
19
Darin Dimitrov

はい、可能です。 ELMAHは、未処理の例外をインターセプトするように設計されました。ただし、ErrorSignalクラスを介してELMAHに例外を通知できます。これらの例外はスローされず(バブルアップしないで)、ELMAH(およびErrorSignalクラスのRaiseイベントのサブスクライバー)にのみ送信されます。

小さな例:

protected void ThrowExceptionAndSignalElmah()
{
    ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}
14

例外が発生したときにHttpContextが利用できなかったため、MVC4アプリケーション内からメールをキューに入れ始めたスレッドで同じことをしようとしていました。これを行うために、私はこの質問とここにある別の答えに基づいて次のようになりました: elmah:exceptions without HttpContext?

構成ファイルで、アプリケーション名を指定しました:

<elmah>
    <security allowRemoteAccess="false" />
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="myApplication"/>   
</elmah>

次に、上記の回答のように(HttpContextを使用しない)コードで、HttpContextの代わりにnullを渡すことができます。

ThreadPool.QueueUserWorkItem(t => {
     try {
         ...
         mySmtpClient.Send(message);
     } catch (SomeException e) {
         Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(e));
     }
 });
13
Matthew

CurrentHttpContextが使用できない場合があります。

定義

public class ElmahLogger : ILogger
{
    public void LogError(Exception ex, string contextualMessage = null, bool withinHttpContext = true)
    {
        try
        {
            var exc = contextualMessage == null 
                      ? ex 
                      : new ContextualElmahException(contextualMessage, ex);
            if (withinHttpContext)
                ErrorSignal.FromCurrentContext().Raise(exc);
            else
                ErrorLog.GetDefault(null).Log(new Error(exc));
        }
        catch { }
    }
}

使用

public class MyClass
{
    readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public void MethodOne()
    {
        try
        {

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, withinHttpContext: false);
        }
    }
}
3
tchelidze

私はASP.NETコアを使用しており、ElmahCoreを使用しています。

エラーを手動でログに記録するには、HttpContextを使用(コントローラー内)を単に記述します。

using ElmahCore;
...
HttpContext.RiseError(new Exception("Your Exception"));

アプリケーションの別の部分HttpContextなし

using ElmahCore;
...
ElmahExtensions.RiseError(new Exception("Your Exception"));
1
A. Morel

Signal.FromCurrentContext()。Raise(ex);を使用してelmahログにカスタムメッセージを書き込もうとしていました。そして、これらの例外がバブルアップしていることがわかりました、例えば:

try
{
    ...
}
catch (Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    // this will write to the log AND throw the exception
}

加えて、elmahがさまざまなレベルのロギングをサポートする方法がわかりません-web.config設定によって詳細なロギングをオフにすることは可能ですか?

0
Valery Gavrilov