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,对数据库字符串进行加密
posted @   ꧁执笔小白꧂  阅读(233)  评论(0编辑  收藏  举报
编辑推荐:
· 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代理 了,记录一下
点击右上角即可分享
微信分享提示