ASP.NETCore-Logging(二)_全局异常+Nlog_Net7
1、安装NuGet包(Nlog与Nlog.Web.AspNetCore)
2、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"
autoReload="true"
throwConfigExceptions="true"
internalLogLevel="info"
internalLogFile="${basedir}/logs/nlog/internal-nlog.txt">
<!-- 启用asp.net核心布局渲染器 -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!--autoReload:修改后自动加载,可能会有延迟-->
<!--throwConfigExceptions:NLog日志系统抛出异常-->
<!--internalLogLevel:内部日志的级别-->
<!--internalLogFile:内部日志保存路径,日志的内容大概就是NLog的版本信息,配置文件的地址等等-->
<!--输出日志的配置,用于rules读取-->
<targets>
<!--将日志写入文件中,fileName可以指定日志生成的路径-->
<target xsi:type="File" name="allfile" fileName="${basedir}/logs/nlog/all/nlog-all-${shortdate}.log"
layout="${longdate}|${event-properties:item=EventId_Id:whenEmpty=0}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />
<!-- 没用到;同样是将文件写入日志中,写入的内容有所差别,差别在layout属性中体现。写入日志的数量有差别,差别在路由逻辑中体现-->
<target xsi:type="File" name="ownFile-web" fileName="${basedir}/logs/nlog/my/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}|" />
<!-- 没用到;控制台目标,用于托管生存期消息以改进Docker/Visual Studio启动检测-->
<target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
<!-- 保留APIs到指定独立目录;最大保存大小10MB,保存时长9天;按天保存; -->
<target xsi:type="File" name="InterFaceFile" fileName="${basedir}/logs_Interface/${date:format=yyyyMMdd}.log" layout="${longdate} ${uppercase:${level}} ${message}" archiveEvery="Day" maxArchiveDays="9" archiveAboveSize="1024000" />
<!-- 保存APIs到DB的配置示例;包含数据库连接字符串等敏感信息 -->
<!--<target xsi:type="Database" name="InLnProcessDBLog">
-->
<!-- SQL command to be executed for each entry -->
<!--
<commandText>
INSERT INTO [SYS_LOG_InterFace]([LogSource]
,[SN]
,[machCode]
,[InterFaceId]
,[InterFaceName]
,[CallStartTime]
,[CallParameter]
,[CallEndTime]
,[TakeUpTime]
,[ReturnCode]
,[ReturnMsg]
,[UserID]
,[UserIP])
VALUES(@LogSource,@SN,@machCode,@InterFaceId,@InterFaceName,@CallStartTime,@CallParameter,@CallEndTime,@TakeUpTime,@ReturnCode,@ReturnMsg,@UserID,@UserIP)
</commandText>
-->
<!-- parameters for the command -->
<!--
<parameter name="@LogSource" layout="${event-properties:item=LogSource}" />
<parameter name="@SN" layout="${event-properties:item=SN}" />
<parameter name="@machCode" layout=" ${event-properties:item=machCode}" />
<parameter name="@InterFaceId" layout="${event-properties:item=InterFaceId}" />
<parameter name="@InterFaceName" layout="${event-properties:item=InterFaceName}" />
<parameter name="@CallStartTime" layout="${event-properties:item=CallStartTime}" />
<parameter name="@CallParameter" layout="${event-properties:item=CallParameter}" />
<parameter name="@CallEndTime" layout="${event-properties:item=CallEndTime}" />
<parameter name="@TakeUpTime" layout="${event-properties:item=TakeUpTime}" />
<parameter name="@ReturnCode" layout="${event-properties:item=ReturnCode}" />
<parameter name="@ReturnMsg" layout="${event-properties:item=ReturnMsg}" />
<parameter name="@UserID" layout="${event-properties:item=UserID}" />
<parameter name="@UserIP" layout="${event-properties:item=UserIP}" />
<dbProvider>System.Data.SqlClient</dbProvider>
<connectionString>Server=localhost;Database=;Uid=;Pwd=;</connectionString>
</target>-->
</targets>
<!-- 从记录器名称映射到目标的规则,路由匹配逻辑为顺序匹配。 -->
<rules>
<!--所有日志,包括来自Microsoft的日志-->
<logger name="*" minlevel="Error" writeTo="allfile" />
<!--以Microsoft打头的日志将进入此路由,由于此路由没有writeTo属性,所有会被忽略-->
<logger name="Microsoft.*" maxlevel="Info" final="true" />
<!--保留APIs到指定独立目录-->
<logger name="InterFace" minlevel="Debug" maxlevel="Error" writeTo="InterFaceFile" />
<!-- 保存APIs到DB的配置示例 -->
<!--<logger name="InterFaceDBLog" minlevel="Trace" writeTo="InLnProcessDBLog" final="true" />-->
<!--上方已经过滤了所有Microsoft.*的日志,所以此处的日志只会打印除Microsoft.*外的日志-->
<logger name="*" minlevel="Error" writeTo="ownFile-web" />
</rules>
</nlog>
3、Program.cs中使用Serilog
public class Program
{
public static void Main(string[] args)
{
// try前也可能报错,但是错误是可控的。实际项目中使用时可以再加个try,只记录日志到文件中。
var configuration = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory()) // 设置“configuration”的查找目录为程序目录
.AddJsonFile("appsettings.json") // 设置“configuration”的读取文件
.Build(); // 获取配置
#region 日志配置
#region 设置NLog配置
var logger = LogManager
.Setup()
.LoadConfigurationFromAppSettings()
.GetCurrentClassLogger();
#endregion 设置NLog配置
#endregion 日志配置
try
{
var builder = WebApplication.CreateBuilder(args);
#region 日志中间件Logging + Nlog
builder.Host.UseNLog(); // 启用第三方日志UseNLog记录日志;将Logging重定向到UseNLog
logger.Debug("init main"); // NLog
// ② 自定义保存APIs的NLog节点
var logger_API = LogManager.GetLogger("APIsLog");
logger_API.Error("自定义接口的保存目录");
// ③ 重写存有数据库连接的节点-略,详细见博客
#endregion 日志中间件Logging + Nlog
#region 容器Services
builder.Services.AddControllers(); // 添加Controller
...
#endregion 容器Services
var app = builder.Build();
...
app.UseAuthorization();
app.MapControllers();
app.Run();
}
catch (Exception ex)
{
logger.Error(ex, "Web应用程序意外终止"); // NLog
}
finally
{
LogManager.Shutdown(); // NLog
}
}
}
4、使用InterFaceDBLog(保存APIs到DB的配置示例)
var InprocessLogger = LogManager.GetLogger("InterFaceDBLog");
LogEventInfo theEvent = new LogEventInfo();
switch (LogLevel2)
{
case "Info":
theEvent.Level = LogLevel.Info;
break;
case "Erro":
theEvent.Level = LogLevel.Error;
break;
case "Warn":
theEvent.Level = LogLevel.Warn;
break;
default:
theEvent.Level = LogLevel.Trace;
break;
}
theEvent.Message = $"{InterFaceName}:{message}";
theEvent.Properties["LogSource"] = LogSource;
theEvent.Properties["SN"] = SN;
theEvent.Properties["machCode"] = machCode;
theEvent.Properties["InterFaceId"] = InterFaceId;
theEvent.Properties["InterFaceName"] = InterFaceName;
theEvent.Properties["CallStartTime"] = starttime;
theEvent.Properties["CallParameter"] = message;
theEvent.Properties["CallEndTime"] = endtime;
theEvent.Properties["TakeUpTime"] = TakeUpTime;
theEvent.Properties["ReturnCode"] = ReturnCode;
theEvent.Properties["ReturnMsg"] = ReturnMsg;
theEvent.Properties["UserID"] = UserID;
theEvent.Properties["UserIP"] = UserIP;
InprocessLogger.Log(theEvent);
补充:Nlog-动态修改DatabaseTarget,对数据库字符串进行加密
本文来自博客园,作者:꧁执笔小白꧂,转载请注明原文链接:https://www.cnblogs.com/qq2806933146xiaobai/articles/17432965.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· 一文读懂知识蒸馏
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下