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);
}
두 솔루션 간에는 차이점이 있습니다.
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);
}
다음과 같은 이점이 있습니다.
- Elmah 호출의 약간 구식 구문을 기억할 필요는 없습니다.
- 많은 DLL이있는 경우 모든 단일 DLL에서 Elmah Core를 참조 할 필요가 없으며이를 자신의 ‘시스템’DLL에 넣으십시오.
- 특별한 처리가 필요하거나 오류를 디버그하기 위해 중단 점을 두려는 경우 한곳에 모두 있습니다.
- Elmah에서 멀어지면 한 곳만 변경할 수 있습니다.
- 레거시 오류 로깅이있는 경우 유지하려고합니다 (단순히 제거 할 시간이없는 일부 UI에 묶여있는 간단한 오류 로깅 메커니즘이 생겼습니다).
참고 : 컨텍스트 정보를 위해 ‘contextualMessage’속성을 추가했습니다. 원하는 경우 이것을 생략 할 수 있지만 매우 유용합니다. Elmah는 예외를 자동으로 풀기 때문에 기본 예외는 여전히 로그에보고되지만이를 클릭하면 contextualMessage가 표시됩니다.
답변
Elmah.ErrorSignal () 메서드를 사용하면 예외를 발생시키지 않고 문제를 기록 할 수 있습니다.
try
{
// Some code
}
catch(Exception ex)
{
// Log error
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
// Continue
}
답변
catch(Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
답변
네 가능합니다. ELMAH는 처리되지 않은 예외를 차단하도록 설계되었습니다. 그러나 ErrorSignal 클래스를 통해 ELMAH에 예외 신호를 보낼 수 있습니다. 이러한 예외는 발생하지 않으며 (버블 링하지 않음) ELMAH (및 ErrorSignal 클래스의 Raise 이벤트 구독자)에게만 전송됩니다.
작은 예 :
protected void ThrowExceptionAndSignalElmah()
{
ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}
답변
MVC4 응용 프로그램 내에서 메일을 대기열에 넣기 시작한 스레드에서 이와 동일한 작업을 수행하려고했습니다. 예외가 발생할 때 HttpContext를 사용할 수 없었습니다. 이렇게하려면이 질문과 여기에있는 다른 대답을 기반으로 다음과 같은 결과를 얻었 습니다. elmah : HttpContext without exceptions?
구성 파일에서 응용 프로그램 이름을 지정했습니다.
<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));
}
});
답변
때로는 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);
}
}
}