How to use ELMAH to manually log errors

柔情痞子 提交于 2019-11-26 05:56:57

问题


Is it possible to do the following using ELMAH?

logger.Log(\" something\");

I\'m doing something like this:

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

This exception will not be automatically logged by ELMAH, because it was handled.


回答1:


Direct log writing method, working since ELMAH 1.0:

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

ELMAH 1.2 introduces a more flexible API:

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

There is a difference between the two solutions:

  • Raise method applies ELMAH filtering rules to the exception. Log method does not.
  • Raise is subscription based and is able to log one exception into the several loggers.



回答2:


I'd recommend wrapping the call to Elmah in a simple wrapper class of your own.

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
        }
    }
}

Then just call it whenever you need to log an error.

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

This has the following benefits:

  • You don't need to remember this slightly archaic syntax of the Elmah call
  • If you have many DLLs you don't need to reference Elmah Core from every single one - and just put this in your own 'System' DLL.
  • If you ever need to do any special handling or just want to put in a breakpoint to debug errors you have it all one place.
  • If you ever move away from Elmah you can just change one place.
  • If you have legacy error logging you want to retain (I just happen to have a simple error logging mechanism that's tied into some UIs that I dont immediately have time to remove).

Note: I've added a 'contextualMessage' property for contextual information. You can omit this if you prefer but I find it very useful. Elmah automatically unwraps exceptions so the underlying exception will still be reported in the log but the contextualMessage will be visible when you click on it.




回答3:


You can use the Elmah.ErrorSignal() method to log an issue without raising an exception.

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

    // Continue
}



回答4:


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



回答5:


Yes, it is possible. ELMAH was designed to intercept unhandled exceptions. However you can signal an exception to ELMAH via the ErrorSignal class. Those exceptions are not thrown (don't bubble up), but are only sent out to ELMAH (and to subscribers of the Raise event of the ErrorSignal class).

A small example:

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



回答6:


I was looking to do this same thing in a thread I had started to queue mail from within my MVC4 application, as such I did not have the HttpContext available when an exception was raised. To do this I ended up with the following based on this question and another answer found on here: elmah: exceptions without HttpContext?

In the config file I specified an application name:

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

Then in code (like the answer provided above, but without the HttpContext) you can pass null instead of an HttpContext:

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



回答7:


Sometimes CurrentHttpContext may not be available.

Define

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 { }
    }
}

Use

public class MyClass
{
    readonly ILogger _logger;

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

    public void MethodOne()
    {
        try
        {

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



回答8:


I am on ASP.NET core and I use ElmahCore.

To manually log errors with HttpContext (in controller) simply write:

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

In another part of your application without HttpContext:

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



回答9:


I was trying to write custom messages into elmah logs using Signal.FromCurrentContext().Raise(ex); and found that these exceptions are bubbled up, eg:

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

Besides I don't see how elmah supports different levels of logging - is it possible to switch off verbose logging by a web.config setting?




回答10:


Used this line and it works perfectly fine.

 try{
            //Code which may throw an error
    }
    catch(Exception ex){
            ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
    }


来源:https://stackoverflow.com/questions/7441062/how-to-use-elmah-to-manually-log-errors

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!