来自 NetCore 库项目的 Nlog 日志 IP 地址

Nlog Log IP Address from NetCore Library Project

我有一个包含多个项目的 VS 2017 解决方案,我有一个带有 NLog 方法的独立项目,以便从其他项目中使用它,因为不在所有项目中包含 NLog。

如果已登录,我想记录客户端 IP 地址和用户。我已经看到我必须在 NLog.config 中使用模板,但它不起作用并且日志 IPAddress 字段为空。

正确的做法是什么?

NLog.Config

<extensions>    
  <add assembly="NLog.Web.AspNetCore"/>
</extensions>

<targets>
  <target name="Database" xsi:type="Database">
    <commandText>
      INSERT INTO T_LOG
        (DATE_, APP, IPADDRESS, USER_, CENTRE, LEVEL_, LOGGER,
        METHOD, MESSAGE, EXCEPTION,
        SOURCE_FILE_PATH, LINE_NUMBER)
      VALUES(
        @Date, @App, @IPAddr, @User, @Centre, @Level, @Logger,
        @Method, @Message, @Exception,
        @SourceFilePath, @LineNumber);
    </commandText>

    <parameter name="@App" layout="${AppName}" />
    <parameter name="@IPAddr" layout="${aspnet-request-ip}" />
    <parameter name="@User" layout="" />
    <parameter name="@Centre" layout="" />
    <parameter name="@Date" layout="${longdate}" />
    <parameter name="@Level" layout="${level:upperCase=true}"/>
    <parameter name="@Logger" layout="${logger:shortName=false}"/>
    <parameter name="@Method" layout="${event-context:item=callermember}"/>
    <parameter name="@Message" layout="${message}" />
    <parameter name="@Exception" layout="${exception:format=ToString}"/>
    <parameter name="@SourceFilePath" layout="${event-context:item=callerpath}" />
    <parameter name="@LineNumber" layout="${event-context:item=callerline}" />

</target>

记录器Class

using Microsoft.AspNetCore.Http;
using NLog;
using System;
using System.Runtime.CompilerServices;

namespace Project.Log
{
    public class CustomLogger
    {
        private readonly Logger logger;
        private Type type;

        public RhesusLog(Type type)
        {
            this.type = type;
            this.logger = LogManager.GetLogger(type.FullName);
        }

        public void Debug(string msg, Exception ex = null,
            [CallerFilePath] string CallerPath = "",
            [CallerMemberName] string CallerMember = "",
            [CallerLineNumber] int CallerLine = 0, params object[] args)
        {
            this.Log(LogLevel.Debug, msg, ex, CallerPath, CallerMember, CallerLine);
        }

        public void Info(string msg, Exception ex = null,
            [CallerFilePath] string CallerPath = "",
            [CallerMemberName] string CallerMember = "",
            [CallerLineNumber] int CallerLine = 0)
        {
            this.Log(LogLevel.Info, msg, ex, CallerPath, CallerMember, CallerLine);
        }

        // Other Levels logs ....

        private void Log(LogLevel Level, string msg,
            Exception Exception = null, string CallerPath = "",
            string CallerMember = "", int CallerLine = 0, params object[] parameters)
        {
            LogEventInfo LogEvent = new LogEventInfo(Level, this.type.FullName, msg);
            LogEvent.Parameters = parameters;
            LogEvent.Exception = Exception;
            LogEvent.Properties.Add("callerpath", CallerPath);
            LogEvent.Properties.Add("callermember", CallerMember);
            LogEvent.Properties.Add("callerline", CallerLine);

            this.logger.Log(LogEvent);
        }
    }
}

我用过NLog日志,我可以在日志上看到这条消息

2018-09-06 23:31:44.6183 Debug Setting 'DatabaseParameterInfo.layout' to '${aspnet-request-ip}'
2018-09-06 23:31:44.6183 Debug Missing serviceProvider, so no HttpContext

如果 NLog 记录 "Missing serviceProvider, so no HttpContext",则 serviceProvider 未正确注册到 NLog。

IWebHostBuilder 上的 UseNLog() 将注册 ServiceProvider 并将 HttpContextAccessor 添加到 DI 系统。

所以你应该仔细检查你是否在正确的时间调用了 UseNLog() ,参见这个例子 program.cs:

public static void Main(string[] args)
{
    // NLog: setup the logger first to catch all errors
    var logger = NLog.Web.NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
    try
    {
        logger.Debug("init main");
        BuildWebHost(args).Run(); 
    }
    catch (Exception ex)
    {
        //NLog: catch setup errors
        logger.Error(ex, "Stopped program because of exception");
        throw;
    }
    finally
    {
        // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
        NLog.LogManager.Shutdown();
    }
}

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureLogging(logging =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
        })
        .UseNLog()  // NLog: setup NLog for Dependency injection
        .Build();

另见 https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2