NuGet安装包

安装4.9版本以上
image.png
NLog.Web.AspNetCore包安装完,你会发现,它自带了NLog.Extensions.Logging,和NLog。

NLog:核心日志框架 NLog.Extensions.Logging:就是我们要使用的Nlog的扩展,这个包主要作用是将Nlog和netcore基础日志组件结合也是netcore日志组件的实现,即Nlog日志提供程序 NLog.Web.AspNetCore:是Aspnetcore使用的Nlog扩展包,和NLog.Extensions.Logging有异曲同工之妙,原理都差不多

image.png

NLog.config简单配置

在主项目的根目录下创建一个Nlog.config配置文件。

这是我简单配置的东西,输出日志到文件txt。
复杂的配置,和配置解释,看文章后面的NLog.config详细配置

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  4. <targets>
  5. <target name="logfile" xsi:type="File"
  6. fileName="./wwwroot/Log/${shortdate}.txt"
  7. archiveAboveSize="1024"
  8. maxArchiveFiles="10"
  9. keepFileOpen="true"
  10. layout="〓时间:${time} —— 等级:${level} —— 方法:${callsite} —— 信息:${message} 〓"
  11. />
  12. </targets>
  13. <rules>
  14. <logger name="*" minlevel="info" writeTo="logfile" />
  15. <logger name="*" minlevel="error" writeTo="logfile" />
  16. </rules>
  17. </nlog>

点击一下NLog.config,属性里面设置

项目运行时,编译后项目在项目里面的bin/下面。输出日志,需要输出到编译后的目录,大概就是这样,就选择下面的这个较新则复制
image.png

修改program.cs

方法1

这是直接用NLog.Web.AspNetCore包的拓展

这是官方给的用法demo:.net core 3.x NLog文档

  1. using NLog.Web;
  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. //var logger = NLog.Web.NLogBuilder.ConfigureNLog("NLog.config").GetCurrentClassLogger();
  6. CreateHostBuilder(args).Build().Run();
  7. }
  8. public static IHostBuilder CreateHostBuilder(string[] args) =>
  9. Host.CreateDefaultBuilder(args)
  10. .ConfigureWebHostDefaults(webBuilder =>
  11. {
  12. webBuilder.UseStartup<Startup>();
  13. })
  14. .UseNLog();//UseNLog()就可以使用NLog日志记录
  15. }

方法2

Microsoft.Extensions.Logging是netcore框架自带的日志组件扩展
NLog.Extensions.Logging 就是Nlog包的扩展包,这个帮助我们快速的将Nlog注入到netcore容器中

  1. using Microsoft.Extensions.Logging;
  2. using NLog.Extensions.Logging;
  1. public class Program
  2. {
  3. public static void Main(string[] args)
  4. {
  5. CreateHostBuilder(args).Build().Run();
  6. }
  7. public static IHostBuilder CreateHostBuilder(string[] args) =>
  8. Host.CreateDefaultBuilder(args)
  9. .ConfigureLogging(logconfig =>
  10. {
  11. logconfig.ClearProviders();//这玩意的作用就是清除微软官方的日志,明显效果就是运行项目控制台什么都没有
  12. logconfig.AddNLog();
  13. })
  14. .ConfigureWebHostDefaults(webBuilder =>
  15. {
  16. webBuilder.UseStartup<Startup>();
  17. });
  18. }

使用Nlog记录日志

方法1

这里是上面修改program.cs里面的方法1,方法2的后续使用。
通过依赖注入,在类的构造函数里面,注入ILogger,泛型就是当前的类名,(试过随便写个类,都可以没问题),这里的泛型类名,给微软原生的控制台输出显示的,其实这个泛型对NLog没用。
在需要记录日志的地方,就记录一下,当然需要在类里面注入这个日志对象。

  1. using Microsoft.Extensions.Logging;
  2. public class HomeController : Controller
  3. {
  4. private readonly ILogger<HomeController> _logger;
  5. public HomeController(ILogger<HomeController> logger)
  6. {
  7. _logger = logger;
  8. }
  9. public IActionResult Index()
  10. {
  11. _logger.LogInformation("Hello, this is the index!");
  12. return View();
  13. }

方法2

直接用NLog包的引用也能在.Net Core项目里面记录日志,好像还更简单

  1. using NLog;
  2. private Logger logger = LogManager.GetCurrentClassLogger();
  3. public LoginResult Login_api(LoginData data)
  4. {
  5. logger.Info("执行了登录操作");
  6. return _loginBLL.Login_bll(data);
  7. }

多个地方需要用,干脆依赖注入一下,在Startup.cs里面的ConfigureServices方法里面

LogManager.GetCurrentClassLogger()的返回结果就是Logger,所以在构造方法注入的时候,注入Logger对象

  1. using NLog;
  2. public void ConfigureServices(IServiceCollection services)
  3. {
  4. services.AddSingleton(LogManager.GetCurrentClassLogger());
  5. }

注入以后就可以写日志了。这种方法,不用写一个暂时不知道有什么用的泛型

  1. using NLog;
  2. private Logger logger;
  3. public LoginController(Logger log)
  4. {
  5. logger = log;
  6. }
  7. public LoginResult Login_api(LoginData data)
  8. {
  9. logger.Info("执行了登录操作");
  10. return _loginBLL.Login_bll(data);
  11. }

但是吧,如果多层架构,在NLog安装在顶层的,底下几层项目没有安装NLog包,就无法注入。每一层都安装一个NLog包,吃多了吧,大可不必鸭。
image.png

日志文件展示

显示的单个日志最大为1024B,最多存在10个日志归档,打印的第17个日志归档,当前日志后面没有序号,归档日志有序号。如果当前是第17个日志,前面最大的归档序号就是16。7-16号。
image.png
按照我简单配置的格式打印的样子
image.png

总结

还是用在微软的ILogger拓展的NLog日志吧,多层项目都自带了ILogger的。

NLog.config详细配置

NLog.config配置简单的结构如下

  1. <?xml version="1.0" encoding="utf-8" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. autoReload="true"
  5. throwConfigExceptions="true"
  6. internalLogLevel="info"
  7. internalLogFile="E:\log\ISP\internal-nlog.txt">
  8. <targets>
  9. <target xsi:type="File" name="allfile" fileName="E:\log\ISP\nlog-all-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
  10. <target xsi:type="File" name="ownFile-web" fileName="E:\log\ISP\nlog-own-${shortdate}.log" layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}|${callsite}" />
  11. </targets>
  12. <rules>
  13. <logger name="*" minlevel="Trace" writeTo="allfile" />
  14. <logger name="Microsoft.*" maxlevel="Info" final="true" />
  15. <logger name="*" minlevel="Trace" writeTo="ownFile-web" />
  16. </rules>
  17. </nlog>

nlog

nlog根节点里面包含了最常用的子节点 targets和 rules
关于nlog节点的属性说明:

autoReload:修改配置文件后是否允许自动加载无须重启程序 throwConfigExceptions:内部日志系统抛出异常 internalLogLevel:可选Trace|Debug|Info|Warn|Error|Fatal决定内部日志的级别 Off 关闭 internalLogFile:把内部的调试和异常信息都写入指定文件里

建议throwConfigExceptions的值设为“false”,这样由于日志引发的问题不至于导致应用程序的崩溃。

targets

targets定义了日志的目标或者说输出 ,在这里可以按需设置文件名称和格式,输出方式。
可以在targets节点里面写多个target节点。每个target节点代表一种输出方式,输出到控制台,输出到文本,输出到数据库等等。
甚至同一个输出目标,都是输出到文本,输出格式也可以大不相同。

target File属性

  1. <target xsi:type="File"
  2. name="String"
  3. layout="Layout"
  4. header="Layout"
  5. footer="Layout"
  6. encoding="Encoding"
  7. lineEnding="Enum"
  8. archiveAboveSize="Long"
  9. maxArchiveFiles="Integer"
  10. maxArchiveDays="Integer"
  11. archiveFileName="Layout"
  12. archiveNumbering="Enum"
  13. archiveDateFormat="String"
  14. archiveEvery="Enum"
  15. archiveOldFileOnStartup="Boolean"
  16. archiveOldFileOnStartupAboveSize="Long"
  17. replaceFileContentsOnEachWrite="Boolean"
  18. fileAttributes="Enum"
  19. fileName="Layout"
  20. deleteOldFileOnStartup="Boolean"
  21. enableFileDelete="Boolean"
  22. createDirs="Boolean"
  23. concurrentWrites="Boolean"
  24. openFileFlushTimeout="Integer"
  25. openFileCacheTimeout="Integer"
  26. openFileCacheSize="Integer"
  27. networkWrites="Boolean"
  28. concurrentWriteAttemptDelay="Integer"
  29. concurrentWriteAttempts="Integer"
  30. bufferSize="Integer"
  31. autoFlush="Boolean"
  32. keepFileOpen="Boolean"
  33. forceManaged="Boolean"
  34. enableArchiveFileCompression="Boolean"
  35. cleanupFileName="Boolean"
  36. writeFooterOnArchivingOnly="Boolean"
  37. writeBom="Boolean" />

name:输出配置名称,可以自己定义,随便写,供rules使用
layout:日志的格式模板 自定义,里面的变量可以参考官方文档,本文末尾也有参考
header:头部格式
footer:脚部格式
encoding:编码格式,可以是utf-8或者其他字符集
lineEnding:行结束模式

  • CR - 在每行后插入 CR 字符 (ASCII 13)。
  • CRLF - 在每行之后插入 CR LF 序列(ASCII 13、ASCII 10)
  • 默认 - 在每行之后插入依赖于平台的行尾序列。
  • LF - 在每行后插入 LF 字符 (ASCII 10)。
  • 无 - 不插入任何行尾。

这个是官方给的解释及参考值
archiveAboveSize:以字节为单位的大小,超过该大小的日志文件将被自动存档
maxArchiveFiles:应保留的最大存档文件数。如果maxArchiveFiles小于或等于 0,则不删除旧文件
maxArchiveDays: 应保留的存档文件的最长期限。当archiveNumbering为时无效Rolling。如果maxArchiveDays小于或等于 0,则不删除旧文件
archiveFileName:要用于存档的文件的名称 可以指定日志,具体参考官方文档
archiveNumbering:对文件档案进行编号的方式
archiveDateFormat:指定用于存档编号的日期格式。此选项仅在“ArchiveNumbering”参数设置为 Date 或 DateAndSequence 时有效

  • 默认: yyyyMMdd
  • ArchiveEvery = 分钟时的默认值: yyyyMMddHHmm
  • ArchiveEvery = 小时时的默认值: yyyyMMddHH
  • ArchiveEvery = Month 时的默认值: yyyyMM
  • ArchiveEvery = Year 时的默认值: yyyy

archiveEvery:指示是否在每次经过指定时间时自动归档日志文件

  • 日 - 每天存档。
  • 小时 - 每小时存档一次。
  • 分钟 - 每分钟存档一次。
  • 月 - 每月存档。
  • 无 - 不要根据时间存档。
  • 年 - 每年存档。
  • 星期日 - 每个星期日存档。在 NLog 4.4.4 中引入。
  • 星期一 - 每周一存档。在 NLog 4.4.4 中引入。
  • 星期二 - 每个星期二存档。在 NLog 4.4.4 中引入。
  • 星期三 - 每周三存档。在 NLog 4.4.4 中引入。
  • 星期四 - 每个星期四存档。在 NLog 4.4.4 中引入。
  • 星期五 - 每星期五存档。在 NLog 4.4.4 中引入。
  • 星期六 - 每星期六存档。在 NLog 4.4.4 中引入。

如果当前时间段发生变化,文件将作为写入操作的一部分移动到存档中。例如,如果当前小时从 10 点更改为 11 点,则在 11:00 或之后发生的第一次写入将触发
archiveOldFileOnStartup:在启动时存档旧日志文件
archiveOldFileOnStartupAboveSize:启动时存档旧日志文件的文件大小阈值。默认值为 0,这意味着一旦启用archiveOldFileOnStartup就会归档文件。在 NLog 4.7 中引入
replaceFileContentsOnEachWrite:指示是否在每次写入时替换文件内容,而不是在末尾附加日志消息
fileAttributes:文件属性(仅限 Windows)

  • 存档 - 文件应该被存档。
  • 压缩的- 由于 .Net 限制,压缩将不起作用。您可以使用 enableArchiveFileCompression。
  • DeleteOnClose - 关闭文件后删除文件。
  • 设备 - 设备文件。
  • 加密 - 加密文件。
  • 隐藏 - 隐藏文件。
  • NoBuffering - 系统打开一个没有系统缓存的文件。
  • 普通 - 普通文件。
  • NotContentIndexed - 内容索引服务不应为文件编制索引。
  • PosixSemantics - 根据 POSIX 规则访问文件。
  • 只读 - 只读
  • ReadOnly - 只读文件。
  • ReparsePoint - 重新解析点。
  • SparseFile - 稀疏文件。
  • 系统 - 系统文件。
  • 临时 - 文件是临时的(应该保存在缓存中,如果可能的话不要写入磁盘)。
  • WriteThrough - 系统通过任何中间缓存写入并直接进入磁盘。

fileName:要写入的文件的名称
deleteOldFileOnStartup: 指示是否在启动时删除旧日志文件,此选项仅在“FileName”参数表示单个文件时有效。
enableFileDelete:指示是否启用删除日志文件
createDirs:是否创建不存在的目录
keepFileOpen:指示是否在每次记录事件时保持日志文件打开,将此属性更改为 true 将大大提高性能,但也会保持文件句柄锁定。启用此选项时,请考虑设置openFileCacheTimeout = 30,因为它将允许存档操作并对被删除的日志文件做出反应。
concurrentWrites:当使用keepFileOpen = true时,支持同一机器主机上的多个进程优化并发写入同一日志文件。通过使用一种特殊的技术,它可以让文件从多个进程中打开。如果只有单个进程(和单个 AppDomain)应用程序正在记录日志,那么设置为concurrentWrites = False会更快。
openFileCacheTimeout:文件保持打开的最大秒数。如果此数字为负数,则文件在一段时间不活动后不会自动关闭
openFileCacheSize:要保持打开的文件数。在单个 File 目标写入多个文件(例如按级别或按记录器拆分)的情况下,将此设置为更高的值可能会提高性能
openFileFlushTimeout:显式刷新文件缓冲区之间的秒数。有助于确保文件缓冲区在autoFlush = false时最终被刷新
networkWrites:指示是否由不同网络主机上的多个进程并发写入日志文件。
concurrentWriteAttemptDelay:在尝试再次写入文件之前等待的延迟(以毫秒为单位)。整数默认值:1
实际延迟是一个介于 0 和此参数中指定的值之间的随机值。在每次失败的尝试中,延迟基数加倍为 ConcurrentWriteAttempts 次。
concurrentWriteAttempts:在 NLog 丢弃日志消息之前尝试写入文件的次数
bufferSize:以字节为单位的日志文件缓冲区大小。整数默认值:32768
autoFlush: 指示是否在每条日志消息后自动刷新文件缓冲区,禁用它会提高性能
forceManaged:指示文件目标应仅使用托管方法。这会禁用某些选项
enableArchiveFileCompression:指示是否将存档文件压缩为 zip 文件
cleanupFileName:在写入文件之前,检查文件名是否包含非法字符(取决于操作系统)。如果写入大量消息,这可能代价高昂。清理缓存为固定名称(无布局渲染器)。将此设置false为最佳性能(但要注意文件名,如果错误,则不会写入任何内容)
writeFooterOnArchivingOnly:指示是否应仅在归档文件时写入页脚
writeBom:指示是否在创建的文件中写入 BOM(字节顺序标记)

JSON/xml Log-file

Nlog不光能记录普通的log文件,还可以记录json格式的问题

  1. <?xml version="1.0" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  4. <targets>
  5. <target name="jsonfile" xsi:type="File" fileName="${basedir}/file.json">
  6. <layout xsi:type="JsonLayout">
  7. <attribute name="time" layout="${date:format=O}" />
  8. <attribute name="message" layout="${message}" />
  9. <attribute name="logger" layout="${logger}"/>
  10. <attribute name="level" layout="${level}"/>
  11. </layout>
  12. </target>
  13. </targets>
  14. <rules>
  15. <logger name="*" minlevel="Debug" writeTo="jsonfile" />
  16. </rules>
  17. </nlog>

可以记录xml格式的文件呢

  1. <?xml version="1.0" ?>
  2. <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  4. <targets>
  5. <target name="csvfile" xsi:type="File" fileName="${basedir}/file.csv">
  6. <layout xsi:type="CSVLayout">
  7. <column name="time" layout="${longdate}" />
  8. <column name="message" layout="${message}" />
  9. <column name="logger" layout="${logger}"/>
  10. <column name="level" layout="${level}"/>
  11. </layout>
  12. </target>
  13. </targets>
  14. <rules>
  15. <logger name="*" minlevel="Debug" writeTo="csvfile" />
  16. </rules>
  17. </nlog>

rules

rules里面的的子节点logger

name:记录者的名字,*全局匹配,就是都可以,都记录 writeTo:规则匹配时日志应该被写入的一系列target,和target节点的name对应,由逗号分隔。 minlevel:最低级别 maxlevel:最高级别 level:单一日志级别 levels:一系列日志级别,由逗号分隔。

  1. <logger name="*" minlevel="Trace" writeTo="allfile" />

layout属性表附录

${activityid} 将其置入日志System.Diagnostics trace
${all-event-properties} 事件日志上下文
${appdomain} 当前应用程序域
${assembly-version} 应用程序
${basedir} 应用程序域的基本目录。
${callsite} (类名称、方法名称和相关信息的源信息)。
${callsite-linenumber} 调用类的
${counter} 数值
${date} 当前日期和时间。
${document-uri} 用于Silverlight应用。
${environment} 环境变量
${event-properties}
${exception} exception信息
${file-contents} 显示指定文件的内容
${gc} 垃圾收集器
${gdc} 诊断上下文
${guid} GUID
${identity} 线程标识信息
${install-context} 安装参数
${level} 级别。
${literal}
${log4jxmlevent} XML事件描述
${logger} 记录器的名字
${longdate} 日期和时间的格式分类yyyy-MM-dd HH:mm:ss.ffff。
${machinename} 名称
${mdc} 映射诊断
${mdlc} 异步映射诊断上下文
${message} 消息,就是写日志调用方法传的那个字符串,自定义
${ndc} 线程结构
${ndlc} 异步线程
${newline} 文字换行
${nlogdir} nlog.dll目录。
${performancecounter} 述性能计数器。
${processid} 当前进程标识符
${processinfo} 运行信息
${processname} 当前进程的名称。
${processtime} 该时间过程中格式HH:MM:ss.mmm。
${qpc} 高精度定时器,基于返回的值从queryperformancecounter(任选地)转换为秒。
${registry} 从注册表中的值。
${sequenceid} ID
${shortdate} 短时间 格式YYYY-MM-DD。
${sl-appinfo} Silverlight应用。
${specialfolder} 文件夹路径
${stacktrace} 堆栈跟踪渲染器。
${tempdir} 临时目录中。
${threadid} 当前线程的标识符。
${threadname} 当前线程。
${ticks} 当前日期和时间。
${time} 24小时格式HH:MM:ss.mmm。
${var} 提供新的变量(4.1)
${windows-identity}
indows线程标识信息(用户名)