NLog - qidot/YunstpNetCore GitHub Wiki

NET Core使用Nlog记录日志

本文主要讲述在netcore中如何使用logging和NLog

1.引入Nuget包

  • Nlog

  • Nlog.Web.AspNetCore

2.添加nlog配置文件

<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     autoReload="true"
       internalLogLevel="Warn"
       internalLogFile="internal-nlog.txt">
     <!--define various log targets-->
     <targets>
        <!--write logs to file-->
         <target xsi:type="File" name="allfile" fileName="nlog-all-${shortdate}.log"
                  layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
    
         <target xsi:type="File" name="ownFile-web" fileName="nlog-my-${shortdate}.log"
                  layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
        <target xsi:type="Null" name="blackhole" />
  </targets>
     <rules>
         <!--All logs, including from Microsoft-->
         <logger name="*" minlevel="Trace" writeTo="allfile" />
    
       <!--Skip Microsoft logs and so log only own logs-->
         <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" />
         <logger name="*" minlevel="Trace" writeTo="ownFile-web" />
  </rules>
</nlog>

注意: 需要把文件复制到bin目录,勾选属性中的"始终复制"

3.在StartUp.cs中配置nlog

//方法中增加ILoggerFactory loggerFactory的参数
public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory)
{
    app.UseStaticFiles();
    //使用NLog作为日志记录工具
    loggerFactory.AddNLog();
    //引入Nlog配置文件(区分不同的开发环境)
    env.ConfigureNLog($"nlog.{env.EnvironmentName}.config");
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    } 
    app.UseMvc();
}

4.在程序中中使用nlog写日志

下面是注入到控制器中的示例

public class ValuesController : Controller
{ 
    //DI(依赖注入)的日志输出
    private ILogger<ValuesController> _logger;
    public ValuesController(ILogger<ValuesController> logger)
    {
        _logger = logger;
    }
    
    // POST api/values/log
    [HttpPost("log")]
    public IActionResult Get([FromBody]string message)
    {
        _logger.LogError($"DI的日志输出======>{message}");
        this.GetLogger().Error($"NLog自定义输出====>{message}");
        return Ok("ok");
    }

5.日志文件生成在指定目录下

<targets>
        <!--write logs to file-->
         <target xsi:type="File" name="allfile" fileName="logs/all/nlog-all-${shortdate}.log"
                  layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
    
         <target xsi:type="File" name="ownFile-web" fileName="logs/my/nlog-my-${shortdate}.log"
                  layout="${longdate}|${logger}|${uppercase:${level}}|${message} ${exception}" />
        <target xsi:type="Null" name="blackhole" />
  </targets>

6.输出信息比较

image-20190904092734320

可以看到上方图片中,相同的日志(DI部分的,红线标注)输出了2次,看着会很烦的,程序调用了2次吗?

显然不是,那是为什么呢???

那是因为netcore中有默认的日志行为,so怎么处理呢?我们需要放弃默认行为

//修改program.cs中
public static IWebHostBuilder CreateWebHostBuilder(
  string[] args) =>
  WebHost.CreateDefaultBuilder(args)
         .UseStartup<Startup>()
         .ConfigureLogging(
             logging=> logging.ClearProviders()
         )  //放弃默认日志行为(仅使用Nlog)
      ;

再来看看,默认的输出信息,就没有了!!!

image-20190904093400543

7.在非控制器下使用

控制器中可以DI,那么service,mapper中如果要输出日志,把DI到的传入进来吗?

显然这么做是可以的,但是太烦了。so,扩展一下吧,用于获取当前日志类

/// <summary>
/// 日志扩展
/// </summary>
public static class MyLogExtensions {
    /// <summary>
    /// 获取当前的日志信息
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    public static Logger GetLogger(this object value)
    {
        return LogManager.GetCurrentClassLogger(value.GetType());
    }
}     

注: 用法,可以参见第4小点中的使用

8.其他的日志组件,如:log4net

后续整理

⚠️ **GitHub.com Fallback** ⚠️