1、安装NuGet包(Nlog与Nlog.Web.AspNetCore)

ASP.NETCore-Logging(二)_全局异常+Nlog_Net7_sed

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>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
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
            }
        }
    }
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
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);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.

作者:꧁执笔小白꧂