一、使用 Visual Studio 2022 创建新项目
二、使用“工具”菜单中的“NuGet 包管理器”引用 NLog.Web.AspNetCore
三、在项目根目录创建配制文件 nlog.config
图3-1
<?xml version="1.0" encoding="utf-8" ?>
<!-- 全局配置
autoReload 修改配置文件后是否允许自动加载无须重启程序。
throwExceptions 内部日志系统抛出异常:建议throwExceptions的值设为“false(默认值)”,这样由于日志引发的问题不至于导致应用程序的崩溃。
throwConfigExceptions 属性开启初始化配置时的异常捕获功能,以验证配置文件的有效性。
internalLogLevel 可选 Trace|Debug|Info|Warn|Error|Fatal|Off ,决定内部日志的级别(0级-6级), Off 最高表示关闭。
internalLogFile 把内部的调试和异常信息都写入指定文件里。-->
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
throwExceptions="false"
throwConfigExceptions="true"
autoReload="true"
internalLogLevel="Off"
internalLogFile="${basedir}/logs/internal-nlog-AspNetCore.txt">
<!--根元素:在配置文件的根元素中,我们可以指定如下的子元素。其中前两个是必须设定的,其余三个为可选设定。
targets:定义日志的输出目标
rules:定义对日志信息的路由规则
extensions:定义从其他dll文件中加载的NLog扩展模块
include:引入外部的配置文件
variable:定义配置文件中用到的变量-->
<!--targets根元素:定义日志的输出目标-->
<targets>
<!--输出目标示例。
Nlog允许用户配置单个文件大小, 放置在内容过长效率过慢,配置了大小之后, Nlog会自动创建一个新的文件副本,插入新的日志输出。
maxArchiveFiles:允许生成的副本文件最大数量
archiveAboveSize:允许单个文件得最大容量
archiveEvery:按天生成
<target name="targetName" 输出目标名称,用于 rules 中路由规则 writeTo 指定
xsi:type="File" 输出类型:Console、File、Database、......
fileName="${basedir}/logs/${shortdate}.log" 输出文件路径和名称:程序根目录中logs文件夹中,以日期作为生成log文件名称
layout="${longdate} ${uppercase:${level}} ${message}" 输出内容的格式模板,“${属性}” 可以把上下文信息插入到日志中
archiveAboveSize="10240"
archiveEvery="Day"
maxArchiveFiles="5"
/>-->
<!-- File Target for all log messages with basic details -->
<target xsi:type="File" name="logFile" fileName="${basedir}/logs/${shortdate}.log" archiveAboveSize="102400"
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
<!--输出到csv文件-->
<target name="csvFile" xsi:type="File" fileName="${basedir}/logs/${shortdate}.csv" archiveAboveSize="102400">
<layout xsi:type="CSVLayout">
<column name="time" layout="${longdate}" />
<column name="message" layout="${message}" />
<column name="logger" layout="${logger}"/>
<column name="level" layout="${level}"/>
</layout>
</target>
<!-- File Target for own log messages with extra web details using some ASP.NET core renderers -->
<target xsi:type="File" name="ownLogWithWeb" fileName="${basedir}/logs/${shortdate}ownLogWithWeb.log"
layout="${longdate}|${event-properties:item=EventId:whenEmpty=0}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
<!--Console Target for hosting lifetime messages to improve Docker / Visual Studio startup detection -->
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
</targets>
<!--rules根元素:定义对日志信息的路由规则,“路由摆放先后顺序”会对日志打印产生影响,路由匹配逻辑为顺序匹配。
name:记录者的名字。
minlevel :最低日志级别。
maxlevel:最高日志级别。
level:单一日志级别。
levels:一系列日志级别,由逗号分隔。
final:是否是最后的匹配路由,true表示匹配到了就结束(被匹配到了不会再继续往下匹配,未匹配到的会继续匹配下一个路由)。
writeTo:输出目标 targetName,规则匹配时日志应该被写入的一系列目标,由逗号分隔。就是 targets 中对应的 name。-->
<rules>
<!--Output hosting lifetime messages to console target for faster startup detection
以 Microsoft.Hosting.Lifetime 打头的日志将进入此路由,输出到 lifetimeConsole-->
<logger name="Microsoft.Hosting.Lifetime" minlevel="Info" writeTo="lifetimeConsole" final="true" />
<!--Skip non-critical Microsoft logs and so log only own logs (BlackHole)
以 Microsoft、System.Net.Http 打头的日志将进入此路由,由于此路由没有 writeTo 属性,所有会被忽略-->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="System.Net.Http.*" maxlevel="Info" final="true" />
<!--从 Info 级别开始记录,低于 Info 级别的不记录。-->
<logger name="*" minlevel="Info" writeTo="logFile,csvFile,lifetimeConsole" final="true" />
</rules>
<!-- enable asp.net core layout renderers
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>-->
</nlog>
代码3-1:nlog.config 包含说明、示例
<?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" >
<targets>
<target xsi:type="File" name="logFile" fileName="${basedir}/logs/${shortdate}.log" archiveAboveSize="102400"
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
<target xsi:type="File" name="csvFile" fileName="${basedir}/logs/${shortdate}.csv" archiveAboveSize="102400">
<layout xsi:type="CSVLayout">
<column name="time" layout="${longdate}" />
<column name="message" layout="${message}" />
<column name="logger" layout="${logger}"/>
<column name="level" layout="${level}"/>
</layout>
</target>
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
</targets>
<rules>
<logger name="Microsoft.Hosting.Lifetime" minlevel="Trace" writeTo="lifetimeConsole" final="true" />
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<logger name="System.Net.Http.*" maxlevel="Info" final="true" />
<logger name="*" minlevel="Info" writeTo="logFile,csvFile,lifetimeConsole" final="true" />
</rules>
</nlog>
代码3-2:nlog.config 简化代码
四、在 program.cs 中注册 NLog
using NLog.Web;
...
builder.Logging.ClearProviders(); //删除所有其他的关于日志记录的配置
builder.Host.UseNLog();
...
var app = builder.Build();
五、在 xxx.razor 文件中注入、记录日志
1. 使用方法1
(1)在页首使用 @inject 注入 NLog
(2)在 @code{ } 中使用代码记录记录
@page "/counter"
@rendermode InteractiveServer
@inject ILogger<Counter> logger;
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
logger.LogInformation("注入方式记录日志信息:Click me 按钮单击了...");
}
}
2. 使用方法2
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
// 新建 NLog.Logger 对象消耗一定的开销,例如需要获取锁或者分配对象。因此推荐以下方式创建NLog.Logger
private static NLog.Logger staticLogger = NLog.LogManager.GetCurrentClassLogger();
private void IncrementCount()
{
currentCount++;
/* NLog 使用方法2:2/2
尽量避免直接使用字符串进行格式化(var message = "Hello" + "Earch";),
NLog.Logger 对象可以推迟执行格式化操作的时机,从而减少开销。*/
staticLogger.Info("static方式记录日志信息:Click me 按钮单击了...{0}", currentCount);
// 将异常对象传递给 NLog.Logger:避免将异常作为字符串格式化的参数,而是显示的将异常作为参数传递给函数。
try {} catch (Exception ex) {staticLogger.Error(ex, "Something bad happened");}
}
}
3. 使用方法3
@page "/counter"
@rendermode InteractiveServer
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
NLog.LogManager.GetCurrentClassLogger().Info("非注入方式直接记录日志信息...");
}
}
六、日志文件位置
在 target 中由 fileName 指定,示例:fileName="${basedir}/logs/${shortdate}-all.log"
七、官网使用说明
https://github.com/NLog/NLog/wiki/Getting-started-with-ASP.NET-Core-6