.NET 使用NLog增强日志输出

news2024/11/16 7:24:28

引言

不管你是开发单体应用还是微服务应用,在实际的软件的开发、测试和运行阶段,开发者都需要借助日志来定位问题。因此一款好的日志组件将至关重要,在.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.coloradmin.cn/o/381431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

少儿编程 电子学会图形化编程等级考试Scratch一级真题解析(判断题)2022年12月

2022年12月scratch编程等级考试一级真题 判断题(共10题,每题2分,共20分) 26、可以通过四种方式添加新角色(不包括复制已有角色):选择一个角色、绘制、随机、上传角色 答案:对 考点分析:考查角色添加的方式,角色添加四种方式分别为题目给出的四种,所以正确 27、角…

分布式事务总结

1. 分布式事务产生的背景 1.1 数据库水平拆分 对于大部分的业务而言&#xff0c;在起步阶段&#xff0c;为了快速上线&#xff0c;一般都是单库单表的。但是随着业务的扩张&#xff0c;数据量也随着扩增&#xff0c;单库的性能逐渐变差&#xff0c;就会有数据库的单点压力。因…

大数据常见术语

大数据常见术语一览 主要内容包含以下&#xff08;收藏&#xff0c;转发给你身边的朋友&#xff09; 雪花模型、星型模型和星座模型 事实表 维度表 上钻与下钻 维度退化 数据湖 UV与PV 画像 ETL 机器学习 大数据杀熟 SKU与SPU 即席查询 数据湖 数据中台 ODS&#xff0c;DWD&…

过滤器的创建和执行顺序

过滤器的创建和执行顺序 8.1.1创建并配置过滤器 P143 重点是如何创建并配置&#xff08;xml&#xff09; 1.创建 public class EncodingFilter implements Filter {Overridepublic void init(FilterConfig filterConfig) throws ServletException {}Overridepublic void doFil…

Linux进程间通信:信号量(一)

前提知识 在介绍信号量之前&#xff0c;先来看看一些概念和一些简单的前提知识&#xff1a; 进程间通信的前提是让不同的进程看到同一份资源。于是&#xff0c;就有提出让这种资源成为一种公共资源的方法&#xff0c;方法的提出&#xff0c;导致了一种新的问题的出现&#xf…

MyBatis源码分析(二)SqlSessionFactory的构建及配置文件读取过程

文章目录一、MyBatis配置文件二、SqlSessionFactory的获取1、初始化XML配置的Document以及其他对象2、解析配置文件&#xff08;1&#xff09;配置Environment&#xff08;2&#xff09;存放Mapper&#xff08;3&#xff09;解析Mapper3、构造SqlSessionFactory4、总结未完待续…

测试2年,当初一起入行的朋友很多月薪20k了,自己却还没过万,到底差在了哪里?

说来奇怪&#xff0c;不管是读书还是工作&#xff0c;都存在一个现象&#xff0c;那就是人比人&#xff0c;比死人。读书的时候&#xff0c;不管是老师还是家长口中&#xff0c;总会有一个“别人家的孩子”。同样&#xff0c;到工作中&#xff0c;领导口中总会有一个“别人的员…

Doxygen 详细使用

doxygen的安装和基本使用可参考&#xff1a;Doxygen的安装和基本使用常用选项doxygen的所有选项的参考文档&#xff1a;doxygen官网文档2、样式说明doxygen可以自己自定义样式。手写 .css文件 &#xff08;可以查看doxygen的源码&#xff0c;进行相对应修改&#xff09;在Exper…

推荐一个.Net Core开发的蜘蛛爬虫开源项目

更多开源项目请查看&#xff1a;一个专注推荐.Net开源项目的榜单 如果我们需要抓取网络上的数据&#xff0c;这时候我们就要写爬虫&#xff0c;这里面就涉及到网页的抓取、以及网页分析与数据提取、抓取的性能等知识&#xff0c;今天就给大家推荐一个开源项目&#xff0c;它可以…

java基础复习(练习写博客)

文章目录Java特性和优势java三大版本JDK、JRE、JVM(从前到后包含)Java开发环境搭建步骤Java程序运行机制IDEJava基础语法一、注释、标识符、关键字二、数据类型&#xff08;shift双击问题&#xff09;三、变量、常量、作用域四、运算符五、包机制、JavaDocJava进阶语法一、Scan…

【Java】代码中的安全漏洞解决合集(更新中)

汝之观览&#xff0c;吾之幸也&#xff01;本文主要讲解Java的一些安全漏洞&#xff0c;并且给出浅知的解决方案。 具体国内的风险可查看网址工业和信息化部网络安全威胁和漏洞信息共享平台 1、Spring Framework反射型文件下载漏洞&#xff08;CVE-2020-5421&#xff09; 漏洞…

Linux 进程:fork()与vfork()的对比

目录一、fork函数二、vfork函数1.函数的原理2.函数的隐患3.解决函数隐患的方法在Linux的进程学习中&#xff0c;常使用fork函数来创建子进程&#xff0c;但其实还有一个vfork函数也可以创建子进程。但是这两个函数的实现机制不同&#xff0c;fork函数使用了写实拷贝技术&#x…

Ubuntu 20搭建srs3.0

SRS官网&#xff0c;v3Home介绍&#xff0c;部署帮助。 1.创建一个srs项目文件夹 2.进入后用git命令拉取3.0release版本&#xff1a;git clone -b 3.0release https://gitee.com/ossrs/srs.git 3.进入srs/trunk目录打开终端输入命令&#xff1a;./configure 4.继续输入命令&a…

Python+tkinter添加滚动条

大家好&#xff0c;我是IKUN的真爱粉&#xff0c;有时候我们需要在tkinter上加滚动条&#xff0c;那么怎么制作呢&#xff0c;我们先看下面的视频展示效果&#xff0c;是不是你想要的 展示 感觉制作的略微粗糙&#xff0c;各位可以后期自己慢慢调整 创建滚动条重要的步骤是&a…

【C++进阶】四、STL---set和map的介绍和使用

目录 一、关联式容器 二、键值对 三、树形结构的关联式容器 四、set的介绍及使用 4.1 set的介绍 4.2 set的使用 五、multiset的介绍及使用 六、map的介绍和使用 6.1 map的介绍 6.2 map的使用 七、multimap的介绍和使用 一、关联式容器 前面已经接触过 STL 中的部分…

SAP 详解ST02

问&#xff1a;在st02中看到&#xff0c;Program和Export/Import的Swap出现红的了&#xff0c;这个是什么原因啊&#xff0c;是不是对系统的性能有影响啊&#xff0c;是否应该调整一些参数啊。要怎么调整呢&#xff1f; 复1&#xff1a;双击红色的部分就可以看到相应的参数修改…

【2023/图对比/无负样本】基于无负样本损失和自适应增强的图对比学习

如果觉得我的分享有一定帮助&#xff0c;欢迎关注我的微信公众号 “码农的科研笔记”&#xff0c;了解更多我的算法和代码学习总结记录。或者点击链接扫码关注【2023/图对比/无负样本】基于无负样本损失和自适应增强的图对比学习 周天琪,杨艳,张继杰等.基于无负样本损失和自适应…

CCNP350-401学习笔记(601-650题)

601、What is a characteristic of Cisco StackWise technology? A. It supports devices that are geographically separated. B. It is supported on the Cisco 4500 series. C. It combines exactly two devices.D. It uses proprietary cabling 602、Refer to the exhibi…

低代码开发平台真的靠谱吗?

低代码开发平台真的靠谱吗&#xff1f;这么跟你说吧&#xff1a; 你想用美图秀秀实现PS的修图效果但失败了&#xff0c;转头就说美图秀秀垃圾&#xff0c;是不是无理取闹你想用剪映实现PR的视频剪辑效果但失败了&#xff0c;转头就说剪映啥也不是&#xff0c;是不是在无理取闹…

操作指南:如何高效使用Facebook Messenger销售(一)

在销售方面&#xff0c; Facebook Messenger 是许多各种规模的企业的首选渠道。这篇文章将向您介绍使用 Messenger 作为销售渠道。我们还将指导您完成用智能客服工具SaleSmartly(ss客服)将您的 Facebook Messenger 销售更上一层楼。配图来源&#xff1a;SaleSmartly&#xff08…