项目中日志是比较常见的一个功能模块,在开发阶段和运维阶段我们可以根据日志排查项目出现的问题,同时可以为项目运营阶段提供业务数据分析。所以日志是项目中不可或缺的功能模块,项目中一般会根据项目需要开发偏向业务的日志模块,而本博客主要介绍第三方日志框架NLog。通过引入NLog日志框架,项目中可以快速的实现基本的日志模块,大大的提高了开发效率。

NLog的Github地址:https://github.com/NLog/NLog, 官网地址:https://nlog-project.org/

本博客主要介绍使用VS开发项目,引入NLog日志框架。

引入NLog包

首先在项目中通过Nuget引入NLog的相关包NLog和NLog.Web.AspNetCore,在VS中的程序包管理控制台依次输入Install-Package NLog -Version 4.6.6 和 Install-Package NLog.Web.AspNetCore -Version 4.8.4命令完成包的安装。如果官方包有更新可以更改版本号,安装最新版本的包。

创建NLog对应的nlog.config配置文件

在项目的根目录下创建nlog.config配置文件,通过属性并将该文件设置为“始终复制”或者“较新复制”,文件的内容可以参考如下设置,项目设置参考官方文档https://github.com/NLog/NLog/wiki/Configuration-file

<?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="Info"
      internalLogFile="c:\temp\internal-nlog.txt">

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

  <targets>
    <!-- write logs to file  -->
    <target name="defaultlog" xsi:type="File" keepFileOpen="false" encoding="utf-8"
        fileName="${basedir}/logs/${level}/${shortdate}.log"
        layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />

    <!-- another file log, only own logs. Uses some ASP.NET core renderers -->
    <target xsi:type="File" name="ownFile-web" fileName="${basedir}/logs/${level}/nlog-own-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--All logs, including from Microsoft-->
    <logger name="*" minlevel="trace" writeTo="defaultlog" />
    
    <!--Skip non-critical Microsoft logs and so log only own logs-->
    <logger name="Microsoft.*" maxlevel="Info" final="true" />
    <!-- BlackHole without writeTo -->
    <logger name="*" minlevel="Trace" writeTo="ownFile-web" />
  </rules>

</nlog>

program.cs文件完成初始化配置

    public class Program
    {
        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");
                CreateWebHostBuilder(args).Build().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 IWebHostBuilder CreateWebHostBuilder(string[] args) =>
            WebHost.CreateDefaultBuilder(args)
                .UseStartup<Startup>()
            .ConfigureLogging(logging => {
                logging.ClearProviders();
                logging.SetMinimumLevel(LogLevel.Information);
            }).UseNLog();
    }

appsettings.json文件中配置

在根目录的appsettings.json文件中增加日志等级配置,其中Default配置会覆盖program.cs中初始化方法SetMininumLevel,需要注意Default的配置。

{
    "Logging": {
        "LogLevel": {
            "Default": "Trace",
            "Microsoft": "Information"
        }
    }
}

调用方法写入日志

在program.cs文件初始化中调用了UseNLog()方法将NLog添加进项目的依赖注入中,项目中调用的时候可以通过依赖注入的方式调用NLog写入日志。如下是Controller中和其他类中通过依赖注入获取logger并写入日志的示例:

using Microsoft.Extensions.Logging;

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;

    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }

    public IActionResult Index()
    {
        _logger.LogInformation("Index page says hello");
        return View();
    }
            //通过IServiceProvider依赖注入获取logger,Aplication封装了IServiceProvider
            var logger = Application.Resolve<ILogger<TaskItem>>();

            try
            {
                if(logger != null)
                    logger.LogInformation($"计划任务 {Key} 开始运行");

                ExecuteTask();

                if (logger != null)
                    logger.LogInformation($"计划任务 {Key} 结束运行");
            }
            catch (Exception exc)
            {
                ScheduleTask.Enabled = !ScheduleTask.StopOnError;
                ScheduleTask.LastEndUtc = DateTime.UtcNow;
                RedisHelper.Set(Key, ScheduleTask);

                if (logger != null)
                    logger.LogError(exc, $"计划任务 {Key} 运行异常");
                if (throwException)
                    throw;
            }

日志示例

运行项目之后,会在对应的日志文件中记录日志:

总结

通过熟悉NLog的文档,项目中引入了NLog框架补充了日志模块,NLog上手还是较快,社区文档也较多。但是对于NLog的一些高级用法以及配置没做进一步的研究,以后有机会再研究。希望本博客可以为其他开发人员提供一些帮助,如果文中表述不对,欢迎大家反馈。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐