ELMAHを使用して次のことを行うことはできますか?
logger.Log(" something");
私はこのようなことをしています:
try
{
// Code that might throw an exception
}
catch(Exception ex)
{
// I need to log error here...
}
この例外は処理されたため、ELMAHによって自動的にログに記録されません。
ELMAHを使用して次のことを行うことはできますか?
logger.Log(" something");
私はこのようなことをしています:
try
{
// Code that might throw an exception
}
catch(Exception ex)
{
// I need to log error here...
}
この例外は処理されたため、ELMAHによって自動的にログに記録されません。
回答:
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つの例外を複数のロガーに記録できます。Elmah.ErrorLog.Log()
:ログの呼び出し自体が失敗した場合にスローされ、Webアプリ全体がダウンする可能性があります。Raise()
静かに失敗します。たとえば、サーバー側で構成の問題がある場合(たとえば、Elmahはエラーをディスクに保存するように構成されているが、ログフォルダーへの正しいアクセス権がない場合)、.Log()
メソッドはスローします。(ただし、これはデバッグに適しています。たとえば、.Raise()
何もログに記録しないのはなぜですか?)
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);
}
これには次の利点があります。
注:コンテキスト情報の「contextualMessage」プロパティを追加しました。必要に応じてこれを省略できますが、非常に便利です。Elmahは自動的に例外をアンラップするため、基になる例外は引き続きログに報告されますが、contextualMessageはクリックすると表示されます。
// uh oh! just keep going
です。エラー処理が失敗した場合、知りたいです。音を立てて欲しい。
catch(Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
はい、可能です。ELMAHは、未処理の例外をインターセプトするように設計されています。ただし、ErrorSignalクラスを介してELMAHに例外を通知できます。これらの例外はスローされません(バブルアップしません)が、ELMAH(およびErrorSignalクラスのRaiseイベントのサブスクライバー)にのみ送信されます。
小さな例:
protected void ThrowExceptionAndSignalElmah()
{
ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}
例外が発生したときにHttpContextを使用できなかったため、MVC4アプリケーション内からメールをキューに入れ始めたスレッドでこれと同じことを実行しようとしていました。これを行うために、私はこの質問とここにある別の答えに基づいて次のようになりました:elmah: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));
}
});
packages.config
どのように見えますか?次のようなものが表示され<package id="elmah" version="1.2.2" targetFramework="net45" />
<package id="elmah.corelibrary" version="1.2.2" targetFramework="net45" />
<package id="elmah.sqlserver" version="1.2" targetFramework="net45" />'
ますか?NuGETでインストールしましたか?
packages.config
時々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);
}
}
}
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設定によって詳細なロギングをオフにすることは可能ですか?