当前位置: 首页 > news >正文

.NET 使用NLog增强日志输出

引言

不管你是开发单体应用还是微服务应用,在实际的软件的开发、测试和运行阶段,开发者都需要借助日志来定位问题。因此一款好的日志组件将至关重要,在.NET 的开源生态中,目前主要有Serilog、Log4Net和NLog三款优秀的日志组件,但相较而言,NLog功能更加强大且扩展性强,允许开发者在仅修改配置文件的方式来丰富日志输出内容,支持多种日志格式,包括XML、JSON、YAML等,支持多种输出目标,包括文件、数据库、控制台、Loki、ElasticSearch等,支持自定义日志格式,支持日志级别,支持异步写入等功能。

NLog 日志组件的使用

那在实际使用中如何集成呢?接下来以ASP.NET Core 应用为例进行详细讲解。

  1. 创建示例项目:控制台执行dotnet new mvc -n NLog.Demo创建示例应用。
  2. 安装NLog 日志组件:进入项目内部,控制台执行dotnet add package NLog.Web.AspNetCore添加NLog.Web.AspNetCoreNuGet 包。
  3. 添加NLog 配置文件:官方提供两种方式用来添加配置,一种是添加nlog.config文件使用xml格式进行配置,一种是直接在appsettings.json文件中使用json格式进行配置,这里推荐使用json格式配置,以便和ASP.NET Core现有的配置体系对齐。在appsettings.json中添加NLog配置节点,如下所示,该配置将Info及以上级别的日志输出到控制台,将Debug及以上级别的日志输出到App_Data/Logs目录。
{
  "Logging": {
    "LogLevel": {
      "Default""Information",
      "Microsoft.AspNetCore""Warning"
    }
  },
  "AllowedHosts""*",
  "NLog": {
    "throwConfigExceptions"true,
    "variables": {
      "logDirectory""${basedir}/App_Data/Logs"
    },
    "extensions": [
      {
        "assembly""NLog.Web.AspNetCore"
      }
    ],
    "targets": {
      "async"true,
      "logfile": {
        "type""File",
        "encoding""utf-8",
        "fileName""${logDirectory}/${shortdate}/${logger}.${level}.log"
      },
      "logconsole": {
        "type""Console"
      }
    },
    "rules": [
      {
        "logger""*",
        "minLevel""Info",
        "writeTo""logconsole"
      },
      {
        "logger""*",
        "minLevel""Debug",
        "writeTo""logfile"
      }
    ]
  }
}

  1. 配置NLog 日志组件:修改Program.cs如下:
using NLog.Extensions.Logging;
using NLog.Web;

var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();

//配置从配置文件的`NLog` 节点读取配置
var nlogConfig = builder.Configuration.GetSection("NLog");
NLog.LogManager.Configuration = new NLogLoggingConfiguration(nlogConfig);
//清空其他日志Providers
builder.Logging.ClearProviders();
//该配置用来指定使用ASP.NET Core 默认的日志过滤器
var nlogOptions = new NLogAspNetCoreOptions() { RemoveLoggerFactoryFilter = false };
builder.Host.UseNLog(nlogOptions); //启用NLog

var app = builder.Build();
// 省略其他代码
  1. 打印日志:修改HomeController中的IndexAction,添加日志:
using System.Diagnostics;
using Microsoft.AspNetCore.Mvc;
using NLog.Demo.Models;

namespace NLog.Demo.Controllers;
public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    public HomeController(ILogger<HomeController> logger)
    {
        _logger = logger;
    }
    public IActionResult Index()
    {
        _logger.LogInformation("Hello {user}, this is NLog.", new { id = 1, name = "Shengjie" });
        return View();
    }
}
  1. 运行项目:日志将按照上方配置输出到控制台和指定目录。
alt

如果此时想按环境控制日志输出等级,仅需修改对应环境的配置文件即可,比如修改appsettings.Development.json中的Logging节点配置如下,即可输出所有以Microsoft.AspNetCore为前缀Information以上级别的日志:

"Logging": {
    "LogLevel": {
      "Default""Information",
      "Microsoft.AspNetCore""Information"
    }
  }

修改后,即可输出前缀为Microsoft.AspNetCore的日志,如下所示,从中可以看出该日志是使用|分割,使用的是默认的日志布局TextLayout,配置为:${longdate}|${level:uppercase=true}|${logger}|${message:withexception=true}

2023-03-01 10:00:38.7022|INFO|Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker|Executed action NLog.Demo.Controllers.HomeController.Index (NLog.Demo) in 94.5297ms 

这种日志的好处是开发环境查看比较直观,但是因为缺失了字段信息,收集后不便分析,那如何调整为结构化的日志结构呢?简单,使用JsonLayout即可,修改NLog:targets:logconsole节点添加layout节点配置即可,如下所示:

    "targets": {
      "async"true,
      "logconsole": {
        "type""Console",
        "layout": {
          "type""JsonLayout",
          "attributes": [
            {
              "name""@timestamp",
              "layout""${date}"
            },
            {
              "name""app",
              "layout""${processname}"
            },
            {
              "name""env",
              "layout""${environment:ASPNETCORE_ENVIRONMENT}"
            },
            {
              "name""level",
              "layout""${level}"
            },
            {
              "name""logger",
              "layout""${logger}"
            },
            {
              "name""message",
              "layout""${message}"
            },
            {
              "name""exception",
              "layout""${exception:format=toString}"
            },
            {
              "name""aspnet-request-method",
              "layout""${aspnet-request-method}"
            },
            {
              "name""aspnet-request-url",
              "layout""${aspnet-request-url}"
            },
            {
              "name""aspnet-mvc-controller",
              "layout""${aspnet-mvc-controller}"
            },
            {
              "name""aspnet-mvc-action",
              "layout""${aspnet-mvc-action}"
            }
          ]
        }
      }
    }

重新运行就可以得到Json结构化的日志结构,日志输出举例如下:

{
    "@timestamp""2023/03/01 13:25:11.912",
    "app""NLog.Demo",
    "env""Development",
    "level""Info",
    "logger""NLog.Demo.Controllers.HomeController",
    "message""Hello { id = 1, name = Shengjie }, this is NLog.",
    "aspnet-request-method""GET",
    "aspnet-request-url""https://localhost/",
    "aspnet-mvc-controller""Home",
    "aspnet-mvc-action""Index"
}

其中app字段,是通过NLog预置的${processname}字段获取,env字段是通过${environment}从指定的环境变量获取,以aspnet-为前缀的字段则是通过NLog.Web.AspNetCore中预置的字段中获取,因此,在配置NLog时,要在NLog节点下加入extensions配置。

"NLog": {
  "throwConfigExceptions"true,
  "variables": {
    "logDirectory""${basedir}/App_Data/Logs"
  },
  "extensions": [
    {
      "assembly""NLog.Web.AspNetCore"
    }
  ]
}

NLog除了以上预置的字段外,还有很多其他字段,比如从配置文件读取字段,从应用读取身份信息,提取请求数据包,读取请求头,截取QueryString中的指定字段。而正是是因为这些开箱即用的预置字段,保证开发者随时按需调整日志输出的字段、格式和目标。

总结

通过以上介绍,相信你发现了NLog日志组件的强大之处,允许开发者在仅修改配置文件的方式来丰富日志输出字段、格式,可以有效地帮助开发者记录和分析应用程序的运行情况。

本文由 mdnice 多平台发布

http://www.lryc.cn/news/25432.html

相关文章:

  • 一道阿里类的初始化顺序笔试题
  • cuda找不到路径报错
  • Elasticsearch进阶之(核心概念、系统架构、路由计算、倒排索引、分词、Kibana)
  • Android包体积缩减
  • 【华为OD机试】 网上商城优惠活动(C++ Java Javascript Python)
  • GWT安装过程
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素
  • office@word@ppt启用mathtype组件方法整理
  • 计算机大小端
  • Matplotlib绘图从零入门到实践(含各类用法详解)
  • C语言 入门教程||C语言 指针||C语言 字符串
  • Nacos2.x+Nginx集群配置
  • Android源码分析 - InputManagerService与触摸事件
  • python库--urllib
  • 美团前端二面常考react面试题及答案
  • 环境搭建04-Ubuntu16.04更改conda,pip的镜像源
  • 【C++进阶】四、STL---set和map的介绍和使用
  • JavaSE学习进阶 day1_01 static关键字和静态代码块的使用
  • 苹果笔可以不买原装吗?开学必备性价比电容笔
  • 数据库连接与properties文件
  • Linux上的校验和验证
  • 杂记——14.git在idea上的使用及其实际开发介绍
  • 记一次Nodejs减低npm版本的踩坑日记
  • 【iOS】—— 初识RAC响应式编程
  • Java——面向对象
  • 电影《毒舌律师》观后感
  • 【活学活用掌握trap命令】
  • 计算机组成原理4小时速成6:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线
  • MyBatis源码分析(三)SqlSession的执行主流程
  • 环境搭建01-Ubuntu16.04如何查看显卡信息及安装NVDIA显卡驱动