P S
P S

Reputation: 23

How to configure nlog.config to include asp.net core 2 web api request custom header information?

I have a simple asp.net core web api application (using the default web api template in Visual Studio 2017) using nlog for logging message to console in JSON format.

Here is the NLog configuration file:

 <!-- the targets to write to -->
 <targets>
    <target xsi:type="Console" name="console_log" >
      <layout xsi:type="JsonLayout">
        <attribute name="ts" layout="${date}" />
        <attribute name="level" layout="${level:upperCase=true}"/>
        **<attribute name="all-events" layout="${all-event-properties}"/>
        <attribute name="tid" layout="${aspnet-request:header=tid}"/>**
        <attribute name="cn" layout="${callsite}"/>
        <attribute name="msg" layout="${message}" />
      </layout>
    </target>
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="Debug" writeTo="console_log" />
  </rules>
</nlog>

In Startup.cs, the Configure method contains the following two lines:

        env.ConfigureNLog("nlog.config");
        loggerFactory.AddNLog();

I got the JSON format log message output to console. However, I was not able to receive the tid which is a custom header in the HTTP request header.

How can I extract the HTTP request header and output it to the console?

I appreciate your comments/answers/guidance. Thank you.

Upvotes: 1

Views: 3862

Answers (2)

Rolf Kristensen
Rolf Kristensen

Reputation: 19867

${aspnet-request} depends on HttpContextAccessor. Please update your code to use UseNLog on IWebHostBuilder (See program.cs in this example)

https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2#4-update-programcs

UseNLog will automatically register HttpContextAccessor (Remember to remove any usage of ConfigureNLog or AddNLog, but only use UseNLog and LogManager.LoadConfiguration as shown in above example)

Upvotes: 2

Lu&#237;s Antunes
Lu&#237;s Antunes

Reputation: 346

you could use an ActionFilterAttribute like this:

public class HttpHeadersLogger : ActionFilterAttribute
{
    private readonly Logger _log = LogManager.GetCurrentClassLogger();

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var request = filterContext.HttpContext.Request;
        var builder = new StringBuilder();

        builder.Append(request.RequestType + " " + request.Url + "\n");

        var logEventInfo = new LogEventInfo(LogLevel.Info, null, null);
        var parsed = HttpUtility.ParseQueryString(request.Headers.ToString());

        foreach (string key in parsed)
        {
            // Search for 'tid' header here to only log these one
            logEventInfo.Properties.Add(key, parsed[key]);
        }

        _log.Log(logEventInfo);

        base.OnActionExecuting(filterContext);
    }
}

In this example, all the headers are being logged, you should filter that if you only want the 'tid' one. This will use the NLog layout expression, by using the object LogEventInfo to perform the logging operation.

Upvotes: 0

Related Questions