zoukankan      html  css  js  c++  java
  • .NET Core中使用NLog按等级过滤写入控制台、文件、数据库记录日志

    项目中日志是比较常见的一个功能模块,在开发阶段和运维阶段我们可以根据日志排查项目出现的问题,同时可以为项目运营阶段提供业务数据分析。所以日志是项目中不可或缺的功能模块,项目中一般会根据项目需要开发偏向业务的日志模块,而本博客主要介绍第三方日志框架NLog。通过引入NLog日志框架,项目中可以快速的实现基本的日志模块,大大的提高了开发效率。

    NuGet引入安装包

    添加NLog和NLog.Web.AspNetCore安装包

    Install-Package NLog -Version 4.7.4 

    Install-Package NLog.Web.AspNetCore -Version 4.9.3

    NLog.config

    网站根目录下新建NLog.config配置文件,记得右击该文件“属性”,复制到输出目录:“始终复制”

     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" throwExceptions="false" internalLogLevel="Off" internalLogFile="NlogRecords.log">
      <!--Nlog内部日志记录为Off关闭。除非纠错,不可以设为Trace否则速度很慢,起码Debug以上-->
      <extensions>
        <add assembly="NLog.Web.AspNetCore" />
      </extensions>
      <targets>
        <!--通过数据库记录日志 配置
        dbProvider请选择mysql或是sqlserver,同时注意连接字符串,需要安装对应的sql数据提供程序
        MYSQL:
        dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"
        connectionString="server=localhost;database=BaseMIS;user=root;password=123456"
        MSSQL:
        dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient"
        connectionString="Server=127.0.0.1;Database=BaseMIS;User ID=sa;Password=123456"
        -->
        <target name="log_database" xsi:type="Database" dbProvider="MySql.Data.MySqlClient.MySqlConnection, MySql.Data" connectionString="server=localhost;port=3306;User Id=root;password=wuzhd123456!;Database=testnlog;pooling=true;character set=utf8;Connection Timeout=160">
          <commandText>
            INSERT INTO TblLogrecords 
            (LogDate,LogLevel,LogType,Logger,Message,MachineName,MachineIp,NetRequestMethod
            ,NetRequestUrl,NetUserIsauthenticated,NetUserAuthtype,NetUserIdentity,Exception)
            VALUES
            (@LogDate,@LogLevel,@LogType,@Logger,@Message,@MachineName,@MachineIp,@NetRequestMethod
            ,@NetRequestUrl,@NetUserIsauthenticated,@NetUserAuthtype,@NetUserIdentity,@Exception);
          </commandText>
          <parameter name="@LogDate" layout="${date}" />
          <parameter name="@LogLevel" layout="${level}" />
          <parameter name="@LogType" layout="${event-properties:item=LogType}" />
          <parameter name="@Logger" layout="${logger}" />
          <parameter name="@Message" layout="${message}" />
          <parameter name="@MachineName" layout="${machinename}" />
          <parameter name="@MachineIp" layout="${aspnet-request-ip}" />
          <parameter name="@NetRequestMethod" layout="${aspnet-request-method}" />
          <parameter name="@NetRequestUrl" layout="${aspnet-request-url}" />
          <parameter name="@NetUserIsauthenticated" layout="${aspnet-user-isauthenticated}" />
          <parameter name="@NetUserAuthtype" layout="${aspnet-user-authtype}" />
          <parameter name="@NetUserIdentity" layout="${aspnet-user-identity}" />
          <parameter name="@Exception" layout="${exception:tostring}" />
        </target>
        <target name="log_file" xsi:type="File" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} | ${level:uppercase=false} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
        <!--ColoredConsole彩色控制台 xsi:type="Console"是指定输出到普通控制台-->
        <target name="log_console" xsi:type="ColoredConsole" useDefaultRowHighlightingRules="true" layout="${longdate}|${level}|${logger}|${message} ${exception}">
          <highlight-row condition="level == LogLevel.Trace" foregroundColor="DarkGray" />
          <highlight-row condition="level == LogLevel.Debug" foregroundColor="Gray" />
          <highlight-row condition="level == LogLevel.Info" foregroundColor="White" />
          <highlight-row condition="level == LogLevel.Warn" foregroundColor="Yellow" />
          <highlight-row condition="level == LogLevel.Error" foregroundColor="Red" />
          <highlight-row condition="level == LogLevel.Fatal" foregroundColor="Magenta" backgroundColor="White" />
        </target>
      </targets>
      <rules>
        <!--跳过所有级别的Microsoft组件的日志记录-->
        <!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
        <!-- BlackHole without writeTo -->
        <!--只通过数据库记录日志,这里的*,如果给了name名字,代码里用日志记录的时候,取logger需要把name当做参数-->
        <logger name="*" minlevel="Info" writeTo="log_database" />
        <logger name="*" minlevel="Trace" writeTo="log_console" />
        <logger name="*" minlevel="Warn" writeTo="log_file" />
      </rules>
    </nlog>

    说明

    • nlog根节点:
      • autoReload属性,true时,如果NLog.config文件有变动,会自动应用新配置(但是会有延迟,过几秒才会应用起来)
      • internalLogLevel属性,设定后,输出的是NLog内部自己的日志记录,如果遇到NLog异常/配置文件没配好,可以把Off改为Trace或Debug来查看NlogRecords.log里的内容
      • internalLogFile属性,可以设定路径,例如默认的c: emp log-internal.log
    • 新增了extensions节点,因为引用了NLog.Web.AspNetCore
    • targets节点中是各种记录方式的配置
    • 第一个target节点,可以看到name是log_database,这里的name和下方logger中writeTo属性对应
      • xsi:type="Database",就是写入数据库了
      • dbProvider属性是数据库适配器,MySQL是MySql.Data.MySqlClient.MySqlConnection, MySql.Data
      • connectionString即连接字符串了
      • commandText子节点是插入数据库时insert语句,可以看到我这里是写入到TblLogrecords表,表结构下文会展示出来
      • parameter子节点是insert语句的各个参数:
        • 有个name="@LogType"参数,layout="${event-properties:item=LogType}",表示@LogType参数的值从event-properties中的LogType中取
        • 其余参数均是NLog自带的内容,aspnet-开头的是NLog.Web.AspNetCore包中提供的方法
    • 第二个target节点,可以看到name是log_file,这里的name和下方logger中writeTo属性对应
      • xsi:type="File",即写入到文件
      • fileName属性是文件名,这里是写入到当前目录下的logs文件夹,并且按日期归档
      • layout属性是写入日志的格式
      • rules应用规则,给三种target限定了三种等级:
        • 首先写入控制台最小等级为Trace,这样我们在调试时,任何日志我们都能在控制台看到
        • 写入数据库的最小等级为Info,这样并不是所以日志都写入数据库,仅当日志等级大于等于Info时才写入
        • 当发生一些警告、致命错误时,必须以文件形式记录下来,所以写入文件的最小等级为Warn
        • 以上是我自己的配置,可以自行配置等级

    网站项目应用NLog服务

     在CreateHostBuilder方法内,追加使用NLog服务以及配置

    .ConfigureLogging(logging =>
                    {
                        logging.ClearProviders();
                        logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
                    }).UseNLog();  // NLog: 依赖注入Nlog;

    在Main方法中初始化配置

    var host = CreateWebHostBuilder(args).Build();
                Logger logger = LogManager.GetCurrentClassLogger();
                try
                {
                    logger.Trace("网站启动中...");
                    using (IServiceScope scope = host.Services.CreateScope())
                    {
                        IConfiguration configuration = scope.ServiceProvider.GetRequiredService<IConfiguration>();
                        //获取到appsettings.json中的连接字符串
                        string sqlString = configuration.GetSection("Connection:MySql").Value;
                        //确保NLog.config中连接字符串与appsettings.json中同步
                        NLogUtil.EnsureNlogConfig("NLog.config", sqlString);
                        logger.Trace("初始化数据库");
                        //用于查看彩色控制台样式,以及日志等级过滤
                        logger.Trace("Test For Trace");
                        logger.Debug("Test For Debug");
                        logger.Info("Test For Info");
                        logger.Warn("Test For Warn");
                        logger.Error("Test For Error");
                        logger.Fatal("Test For Fatal");
                    }
                    //throw new Exception("测试异常");//for test
    
                    //其他项目启动时需要做的事情
                    //code
                    logger.Trace("网站启动完成");
                    host.Run();
                }
                catch (Exception ex)
                {
                    logger.Fatal(ex, "网站启动失败");
                    throw;
                }

    NLogUtil类 EnsureNlogConfig 验证是否与appsettings.json同步

    /// <summary>
            /// 确保NLog配置文件sql连接字符串正确
            /// </summary>
            /// <param name="nlogPath"></param>
            /// <param name="sqlConnectionStr"></param>
            public static void EnsureNlogConfig(string nlogPath, string sqlConnectionStr)
            {
                XDocument xd = XDocument.Load(nlogPath);
                if (xd.Root.Elements().FirstOrDefault(a => a.Name.LocalName == "targets")
                    is XElement targetsNode && targetsNode != null &&
                    targetsNode.Elements().FirstOrDefault(a => a.Name.LocalName == "target" && a.Attribute("name").Value == "log_database")
                    is XElement targetNode && targetNode != null)
                {
                    if (!targetNode.Attribute("connectionString").Value.Equals(sqlConnectionStr))//不一致则修改
                    {
                        //这里暂时没有考虑dbProvider的变动
                        targetNode.Attribute("connectionString").Value = sqlConnectionStr;
                        xd.Save(nlogPath);
                        //编辑后重新载入配置文件(不依靠NLog自己的autoReload,有延迟)
                        LogManager.Configuration = new XmlLoggingConfiguration(nlogPath);
                    }
                }
            }

    测试查看效果

    控制台:

     文件:

     数据库:

  • 相关阅读:
    web-框架
    jQurey
    JavaScript
    css
    mysql:视图、触发器、事务、存储、函数、流程控制
    mysql-备份及关联python
    [原创]wireshark&xterm安装、配置和使用
    [原创]mininet安装
    [原创]OpenvSwitch安装
    [原创]Floodlight安装
  • 原文地址:https://www.cnblogs.com/ZhengHengWU/p/13614730.html
Copyright © 2011-2022 走看看