How to set parameters like URL, Status Codes and Version in elmah.io using log4net.elmah.io package in asp.net web api application?

281 views Asked by At

I am using log4net.elmah.io for logging purpose.

This is my lo4net.config file

<configuration>
 <configSections>
    <section name="log4net" type ="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
 </configSections>
 <log4net>
    <appender name="ElmahIoAppender" type="elmah.io.log4net.ElmahIoAppender, elmah.io.log4net">
      <logId value="LOG_ID" />
      <apiKey value="API_KEY" />
    </appender>
    <root>
      <level value="debug"/>
      <appender-ref ref="RollingFileAppender"/>
      <appender-ref ref="ElmahIoAppender" />
    </root>
  </log4net>
</configuration>

I have created a class for the logging purpose called MyFilterAttribute

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;

namespace Resume
{
    public class MyFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            if (actionContext.Request.Method == HttpMethod.Get)
            {
                var log = log4net.LogManager.GetLogger(typeof(ApiController));
                log.Info("This is log meassage for GET method");
            }

        }
    }
}

MyFilterAttribute is mentioned before the action methods in the controller as follows:

[Route("api/employees/{id}")]
[HttpGet]
[MyFilterAttribute]
public HttpResponseMessage GetEmployee(int id)
 {
    var employee = _unitOfWork.Employee.Get(id);

    return employee != null? Request.CreateResponse(HttpStatusCode.OK, employee) : Request.CreateErrorResponse(HttpStatusCode.NotFound, "Employee with Id " + id + " does not exist");
}

When a request was made I was able to the response and the log message.

The output image in the elmah.io is as follows: https://ibb.co/QrFBQdx

please see the URL of the image for the output of the elmah.io

There you can the URL and status code was not getting logged.

Someone, please help in solving the issue.

1

There are 1 answers

3
ThomasArdal On BEST ANSWER

You could put the following code in the Application_Start method in Global.asax.cs:

public class WebApiApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {
        ...

        Hierarchy hier = log4net.LogManager.GetRepository() as Hierarchy;
        var elmahIoAppender = (ElmahIoAppender)(hier?.GetAppenders())
            .FirstOrDefault(appender => appender.Name
                .Equals("ElmahIoAppender", StringComparison.InvariantCultureIgnoreCase));

        elmahIoAppender.ActivateOptions();
        elmahIoAppender.Client.Messages.OnMessage += (sender, a) =>
        {
            var ctx = HttpContext.Current;
            if (ctx == null) return;
            a.Message.Url = ctx.Request?.Path;
            a.Message.StatusCode = ctx.Response?.StatusCode;
        };
    }
}

This will cause the OnMessage callback to be triggered for each log message. If there's an HTTP context on the time of logging, the Url and StatusCode fields will be filled in on the message logged to elmah.io.