11

I develop .net core app and use NLog as logging framework.

How can I setup NLog layout to get remote IP address?

Unfortunately, ${aspnet-request.serverVariable=remote_addr} isn't supported by NLog.Web.AspNetCore.

May be I can get access to httpContext.Connection.RemoteIpAddress somehow.

Julian
  • 33,915
  • 22
  • 119
  • 174
A. Gladkiy
  • 3,134
  • 5
  • 38
  • 82

4 Answers4

18

This is supported since NLog.Web.AspNetCore 4.4.0.

  1. Install the package NLog.Web.AspNetCore
  2. Set in your config

    <!-- enable asp.net core layout renderers -->
    <extensions>
      <add assembly="NLog.Web.AspNetCore"/>
    </extensions>
    
  3. You could now use ${aspnet-request-ip} in your config.

PS: also supported for ASP.NET in NLog.Web 4.5.0

Old answer

Currently this is not supported, but you could inject it in NLog like this:

using System;
using System.Text;
using Microsoft.AspNetCore.Http;
using NLog.Config;
using NLog.LayoutRenderers;
using NLog.Web.Internal;

namespace NLog.Web.LayoutRenderers
{
    /// <summary>
    /// Render the request IP for ASP.NET Core
    /// </summary>
    /// <example>
    /// <code lang="NLog Layout Renderer">
    /// ${aspnet-request-ip}
    /// </code>
    /// </example>
    [LayoutRenderer("aspnet-request-ip")]
    public class AspNetRequestIpLayoutRenderer : AspNetLayoutRendererBase
    {

        protected override void DoAppend(StringBuilder builder, LogEventInfo logEvent)
        {
            var httpContext = HttpContextAccessor.HttpContext;
            if (httpContext == null)
            {
                return;
            }
            builder.Append(httpContext.Connection.RemoteIpAddress);
        }
    }
}

Register it (startup.cs)

ConfigurationItemFactory.Default.LayoutRenderers
    .RegisterDefinition("aspnet-request-ip", typeof(AspNetRequestIpLayoutRenderer));

See also Extending NLog

usage

${aspnet-request-ip}

Also include NLog.Web.AspNetCore!

Julian
  • 33,915
  • 22
  • 119
  • 174
  • 1
    Very helpful! There are important tib-bits in the first answer to [this question](http://stackoverflow.com/questions/34679727/use-nlog-in-asp-net-core-application/34888186) that should be looked at, too. Especially if your `HttpContextAccessor` keeps coming up `null` – Bob Kaufman May 07 '17 at 16:50
  • 1
    Updated, as this is now supported out-of-the-box – Julian Sep 28 '18 at 14:46
3

It is now easier: Introduced in NLog Web.AspNetCore 4.4.0 & NLog.Web 4.5.0

Render Client IP address

Supported in ASP.NET & ASP.NET Core.

Configuration Syntax

${aspnet-request-ip}

Nothing else is needed

0

Also it's needed to call the .NLog() before .Build().

Something like this:

public static void Main(string[] args)
{
  CreateWebHostBuilder(args).UseNLog().Build().Run();
}
Taras Pelenio
  • 73
  • 2
  • 9
-1

A simpler solution might be to use NLog's Global Diagnostics Context option.

For example, set a custom value named "IpAddress" before logging an event:

 public IActionResult AnAction()
 {
     NLog.GlobalDiagnosticsContext.Set("IpAddress", HttpContext.Connection.RemoteIpAddress);
     _logger.LogInformation("Something happened");
     return View();
 }

And in your nlog.config file, you can make use of that value in the layout like this:

<target xsi:type="File" name="allfile" fileName="c:\nlog.log" 
    layout="${longdate} | ${message} | ${gdc:item=IpAddress}" />
Julian
  • 33,915
  • 22
  • 119
  • 174
tclark333
  • 557
  • 5
  • 13
  • 1
    What happens with your global context if you have multiple users at the same time? Are you then sure that you are logging the correct IP-address. Maybe consider saving the IP-address into HttpContext.Current.Items, and then retrieve it using NLog ${aspnet-item} – Rolf Kristensen Jun 17 '17 at 16:52