当前位置: 首页 > 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 多平台发布

相关文章:

.NET 使用NLog增强日志输出

引言 不管你是开发单体应用还是微服务应用&#xff0c;在实际的软件的开发、测试和运行阶段&#xff0c;开发者都需要借助日志来定位问题。因此一款好的日志组件将至关重要&#xff0c;在.NET 的开源生态中&#xff0c;目前主要有Serilog、Log4Net和NLog三款优秀的日志组件&…...

一道阿里类的初始化顺序笔试题

问题很简单&#xff0c;就是下面的代码打印出什么&#xff1f; public class InitializeDemo {private static int k 1;private static InitializeDemo t1 new InitializeDemo("t1" );private static InitializeDemo t2 new InitializeDemo("t2");priv…...

cuda找不到路径报错

编译C文件时出现&#xff1a;error: [Errno 2] No such file or directory: :/usr/local/cuda:/usr/local/cuda/bin/nvcc 在终端输入&#xff1a; export CUDA_HOME/usr/local/cuda...

Elasticsearch进阶之(核心概念、系统架构、路由计算、倒排索引、分词、Kibana)

Elasticsearch进阶之&#xff08;核心概念、系统架构、路由计算、倒排索引、分词、Kibana&#xff09; 1、核心概念&#xff1a; 1.1、索引&#xff08;Index&#xff09; 一个索引就是一个拥有几分相似特征的文档的集合。比如说&#xff0c;你可以有一个客户数据的索引&…...

Android包体积缩减

关于减小包体积的方案&#xff1a; 一、所有的图片压缩&#xff0c;采用webp 格式。 &#xff08;当然有些图片采用webp格式反而变大了&#xff0c;可以仍采用png格式&#xff09; 二、语音资源过滤 只保留中文 resConfigs "zh-rCN", "zh” 可以减少resourc…...

【华为OD机试】 网上商城优惠活动(C++ Java Javascript Python)

文章目录 题目描述输入描述输出描述备注用例题目解析C++JavaScriptJavaPython题目描述 某网上商场举办优惠活动,发布了满减、打折、无门槛3种优惠券,分别为: 每满100元优惠10元,无使用数限制,如100199元可以使用1张减10元,200299可使用2张减20元,以此类推;92折券,1次…...

GWT安装过程

1:安装前准备 &#xff08;可以问我要&#xff09; appengine-java-sdk-1.9.8 com.google.gdt.eclipse.suite.4.3.update.site_3.8.0 gwt-2.5.1 eclipse-jee-kepler-SR2-win32-x86_64.zip 2&#xff1a;安装环境上 打开eclipse Help –Install New Software… 选择Add –…...

代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素

Leetcode 704 二分查找题目链接&#xff1a;704二分查找介绍给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&#xff0c;否则返回 -1。思路先看看一个…...

office@word@ppt启用mathtype组件方法整理

文章目录将mathtype添加到word中ref查看office安装路径文件操作法Note附PPT中使用mathtype将mathtype添加到word中 先安装office,再安装mathtype,那么这个过程是自动的如果是先安装mathtype,再安装office,那么有以下选择: 重新安装一遍mathtype(比较简单,不需要说明)执行文件操…...

计算机大小端

我们先假定内存结构为上下型的&#xff0c;上代表内存高地址&#xff0c;下代表内存低地址。 电脑读取内存数据时&#xff0c;是从低位地址到高位地址进行读取&#xff08;从下到上&#xff09;。 1、何为大小端 大端&#xff1a;数据的高位字节存放在低地址&#xff0c;数据…...

Matplotlib绘图从零入门到实践(含各类用法详解)

一、引入 Matplotlib 是一个Python的综合库&#xff0c;用于在 Python 中创建静态、动画和交互式可视化。 本教程包含笔者在使用Matplotlib库过程中遇到的各类完整实例与用法还有遇到的库理论问题&#xff0c;可以根据自己的需要在目录中查询对应的用法、实例以及第四部分关于…...

C语言 入门教程||C语言 指针||C语言 字符串

C语言 指针 学习 C 语言的指针既简单又有趣。通过指针&#xff0c;可以简化一些 C 编程任务的执行&#xff0c;还有一些任务&#xff0c;如动态内存分配&#xff0c;没有指针是无法执行的。所以&#xff0c;想要成为一名优秀的 C 程序员&#xff0c;学习指针是很有必要的。 …...

Nacos2.x+Nginx集群配置

一、配置 nacos 集群 注意&#xff1a;需要先配置好 nacos 连接本地数据库 1、拷贝三份 nacos 2、修改配置文件&#xff08;cluster.conf&#xff09; 修改启动端口&#xff1a; nacos1&#xff1a;8818 nacos2&#xff1a;8828 nacos3&#xff1a;8838 当nacos客户端升级为…...

Android源码分析 - InputManagerService与触摸事件

0. 前言 有人问到&#xff1a;“通过TouchEvent&#xff0c;你可以获得到当前的触点&#xff0c;它更新的频率和屏幕刷新的频率一样吗&#xff1f;”。听到这个问题的时候我感到很诧异&#xff0c;我们知道Android是事件驱动机制的设计&#xff0c;可以从多种服务中通过IPC通信…...

python库--urllib

目录 一.urllib导入 二.urllib爬取网页 三.Headers属性 1.使用build_opener()修改报头 2.使用add_header()添加报头 四.超时设置 五.get和post请求 1.get请求 2.post请求 urllib库和request库作用差不多&#xff0c;但比较起来request库更加容易上手&#xff0c;但该了…...

美团前端二面常考react面试题及答案

什么原因会促使你脱离 create-react-app 的依赖 当你想去配置 webpack 或 babel presets。 React 16中新生命周期有哪些 关于 React16 开始应用的新生命周期&#xff1a; 可以看出&#xff0c;React16 自上而下地对生命周期做了另一种维度的解读&#xff1a; Render 阶段&a…...

环境搭建04-Ubuntu16.04更改conda,pip的镜像源

我常用的pipy国内镜像源&#xff1a; https://pypi.tuna.tsinghua.edu.cn/simple # 清华 http://mirrors.aliyun.com/pypi/simple/ # 阿里云 https://pypi.mirrors.ustc.edu.cn/simple/ #中国科技大学1、将conda的镜像源修改为国内的镜像源 先查看conda安装的信息…...

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

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

JavaSE学习进阶 day1_01 static关键字和静态代码块的使用

好的现在我们进入进阶部分的学习&#xff0c;看一张版图&#xff1a; 前面我们已经学习完基础班的内容了&#xff0c;现在我们已经来到了第二板块——基础进阶&#xff0c;这部分内容就不是那么容易了。学完第二板块&#xff0c;慢慢就在向java程序员靠拢了。 面向对象进阶部分…...

苹果笔可以不买原装吗?开学必备性价比电容笔

在当今的时代&#xff0c;电容笔日益普及&#xff0c;而且相关的功能也逐渐完善。因此&#xff0c;在使用过程中&#xff0c;怎样挑选一款性价比比较高的电容笔成为大家关心的焦点。随着电容笔的普及&#xff0c;更好更便宜的电容笔成为了一种趋势。那么&#xff0c;哪个品牌的…...

数据库连接与properties文件

管理properties数据库&#xff1a; 现在pom文件中加入Druid的坐标&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version></dependency>配置文件中添加相应的数据&…...

Linux上的校验和验证

校验和&#xff08;checksum&#xff09;程序用来从文件中生成相对较小的唯一密钥。我们可以重新计算该密钥&#xff0c;用以检查文件是否发生改变。修改文件可能是有意为之&#xff08;添加新用户会改变密码文件&#xff09;&#xff0c;也可能是无意而为&#xff08;从CD-ROM…...

杂记——14.git在idea上的使用及其实际开发介绍

这篇文章我们来讲一下git在idea上的使用&#xff0c;以及在实际开发过程中各个分支的使用及其具体的流程 目录 1.git在idea上的使用 1.1 idea上的git提交 1.2 idea上的分支切换 2.git在实际运用时的分支及其流程 2.1分支介绍 2.2具体流程 3.小结 1.git在idea上的使用 …...

记一次Nodejs减低npm版本的踩坑日记

使用了npm install -g npm6.4.1指令之后&#xff0c;把npm版本减低了&#xff0c;让后悲催的就来了。 由于npm 6.4.1 已经过时&#xff0c;导致运行npm时出现 npm does not support Node.js v18.14.2 版本不兼容问题 升级npm版本&#xff0c;npm install -g npmlatest 没用还是…...

【iOS】—— 初识RAC响应式编程

RAC&#xff08;ReactiveCocoa&#xff09; 文章目录RAC&#xff08;ReactiveCocoa&#xff09;响应式编程和函数式编程的区别函数式编程响应式编程响应式编程的优点RAC操作1.利用button点击实现点击事件和传值2.RACSignal用法RACSignal总结&#xff1a;3.对于label的TapGestur…...

Java——面向对象

目录 前言 一、什么是面向对象&#xff1f; 面向过程 & 面向对象 面向对象 二、回顾方法的定义和调用 方法的定义 方法的调用 三、类与对象的创建 类和对象的关系 创建与初始化对象 四、构造器详解 五、创建对象内存分析 六、封装详解 七、什么是继承&#x…...

电影《毒舌律师》观后感

上周看了《毒蛇律师》这部电影&#xff0c;讲述一位’大律师’在法庭为己方辩护&#xff0c;最终赢得辩护的故事。 &#xff08;1&#xff09;人之常情 说起法律相关&#xff0c;不禁会让人联想到讲法律相关知识的罗翔老师&#xff0c;平时也会看他相关视频&#xff0c;无论是亲…...

【活学活用掌握trap命令】

trap 命令用于指定在接收到信号后将要采取的动作&#xff0c;常见的用途是在脚本程序被中断时完成清理工作。当 shell 接收到 sigspec 指定的信号时&#xff0c; arg 参数(通常是执行命令)会被读取&#xff0c;并被执行。 1. 命令介绍 开始掌握基本的使用方式和方法 [1] 语法…...

计算机组成原理4小时速成6:输入输出系统,io设备与cpu的链接方式,控制方式,io设备,io接口,并行串行总线

计算机组成原理4小时速成6&#xff1a;输入输出系统&#xff0c;io设备与cpu的链接方式&#xff0c;控制方式&#xff0c;io设备&#xff0c;io接口&#xff0c;并行串行总线 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c…...

MyBatis源码分析(三)SqlSession的执行主流程

文章目录一、熟悉主要接口二、SqlSession的获取1、通过数据源获取SqlSession三、Mapper的获取与代理1、从SqlSession获取Mapper2、执行Mapper方法前准备逻辑3、SqlCommand的创建4、构造MethodSignature四、执行Mapper的核心方法1、执行Mapper的方法逻辑五、简单SELECT处理过程1…...

我爱做衣服网站/佛山seo联系方式

多用户&#xff0c;同时——二个因素缺一不可 并发的两种情况 一种是严格意义上的并发&#xff0c;即所有的用户在同一时刻做同一件事或操作&#xff0c;这种操作一般指做同一类型的业务。比如&#xff0c;所有用户同一时刻做并发登陆&#xff0c;同一时刻做表单提交。 另外一种…...

想注册一个做网站的公司/seo博客推广

(跃迁之路)专栏 实验说明 从2017.10.6起&#xff0c;开启这个系列&#xff0c;目标只有一个&#xff1a;探索新的学习方法&#xff0c;实现跃迁式成长实验期2年&#xff08;2017.10.06 - 2019.10.06&#xff09;我将以自己为实验对象。我将开源我的学习方法&#xff0c;方法不断…...

wordpress 不能自定义主题/自己如何建立网站

android8.1启动过程(七) SystemServer_we1less的博客-CSDN博客 这篇文章说道SystemServer进程主要用于创建系统服务&#xff0c;同时初始化Zygote 调用gCurRuntime->onZygoteInit();本文从这继续解析binder的启动过程。 onZygoteInit AOSP/frameworks/base/cmds/app_pr…...

c 能用来做网站吗/百度地图广告投放

2010年7月份&#xff0c;NASA和Rackspace公司将Openstack开源。到今天&#xff0c;Openstack马上六周岁了。而6周岁正是孩子上小学一年级的时候&#xff0c;Openstack是否也准备好上小学了呢&#xff1f; Openstack在刚开始的3年受到了整个市场的热捧&#xff0c;很多国际大牌不…...

成都行业网站/怎么创建个人网站

**作者&#xff1a;张华 发表于&#xff1a;2016-12-07 版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 ( http://blog.csdn.net/quqi99 )** python3中的默认编码unicode(UCS-2编码&#xff09;采用2个字节表…...

企业网站开发费是固定资产吗/网站友情链接自动上链

近日&#xff0c;不少《王者荣耀》玩家反映&#xff0c;收到人脸识别验证弹窗提醒。据了解&#xff0c;腾讯已经开始在包括《王者荣耀》《和平精英》在内的100多款手机游戏产品中进行人脸识别验证&#xff0c;旨在解决“孩子冒用家长身份信息绕过监管”的问题。登录过程中拒绝或…...