第4章 配置集成第3方log4net日志中间件

news2024/11/24 4:53:38

    在上一章中虽然已经把第3方log4net日志中间件定义到了当前程序中,但是并没有把第3方log4net日志中间件的功能配置并集到当前程序中,即当前程序还不能通过第3方log4net日志中间件把日志数据信息持久化到指定的文件或表中,本章即将实现当前程序对第3方log4net日志中间件的配置集成

1 日志实例的文件持久化集成

1.1 重构appsettings.json

  "AppSettings": {

    //"RedisCachingAOP": {

    //  "Enabled": false

    //},

    //"MemoryCachingAOP": {

    //  "Enabled": true

    //},

    "LogAOP": {

      "Enabled": "true",

      "LogToFile": {

        "Enabled": true

      },

      "LogToDB": {

        "Enabled": true

      }

    },

    "TranAOP": {

      "Enabled": true

    },

    "SqlAOP": {

      "Enabled": true,

      "LogToFile": {

        "Enabled": true

      },

      "LogToDB": {

        "Enabled": true

      },

      "LogToConsole": {

        "Enabled": true

      }

    },

    //"Date": "2018-08-28",

    "SeedDBEnabled": true, //只生成表结构

    "SeedDBDataEnabled": true, //生成表,并初始化数据

    //"Author": "Blog.Core",

   // "SvcName": "", // /svc/blog

    ///"UseLoadTest": false

  },

1.2 重构 Extensions.ServiceExtensions.SqlsugarSetup.AddSqlsugarSetup方法

if (AppSettings.app(new string[] { "AppSettings", "SqlAOP", "Enabled" }).ObjToBool())

                                {

                                    if (AppSettings.app(new string[] { "AppSettings", "SqlAOP", "LogToFile", "Enabled" }).ObjToBool())
    按F5执行程序后,会自动把日志实例持久化到启动项中的指定文件中,但是因为没有定义log4net日志中间件过滤配置,所以该文件中的信息非常的多且不必要,如下图所示:

1.3 实例化第3方“log4net”日志中间件

        //通过设定的持久化过滤规则及其配置文件(Log4net.config)中的数据实例,实例化第3方“log4net”日志中间件,最后把第3方“log4net”日志中间件依赖注入到内置容器中。

//注意:原示例代码是把把第3方“log4net”日志中间件依赖注入到内置依赖注入第3方“Autofac”容器中。

builder.Services.AddLogging(loging => {

    //第3方“log4net”日志中间件持久化过滤规则:在持久化时,过滤掉带有"System"命名空间的日志信息实例。

    loging.AddFilter("System", LogLevel.Error);

    //第3方“log4net”日志中间件持久化过滤规则:在持久化时,过滤掉带"Microsoft"命名空间的日志信息实例。

    loging.AddFilter("Microsoft", LogLevel.Error);

    loging.SetMinimumLevel(LogLevel.Error);

});

    注意:

  1. 上面的定义并不包含配置文件(Log4net.config),因为配置文件(Log4net.config)主要是针对于数据库中的日志表,所以本人会在下面的日志实例的表持久化集成中进重构。
  2. 通过第3方“log4net”日志中间件把日志实例的持久化到日志文件中只依赖于中间件:log4net,被直接引用在“Common”项目中。

    在实例化了带有持久化过滤规则定义的“log4net”日志中间件实例后,log4net日志中间件就会对日志实例中的数据进行过滤,那么日志文件中的持久化数据就会明显的减少,如下图所示:

2 日志实例的表持久化集成

    由于不能通过示例中的配置文件实现通过“log4net”日志中间件把日志实例持久化到指定的表中,本人对“Log4net.config”配置文件进行了重新的定义其定义如下

2.1 重新的定义“Log4net.config”配置文件

<?xml version="1.0" encoding="utf-8"?>

<log4net>

    <!-- Define some output appenders -->

    <appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">

        <file value="log4\log.txt" />

        <!--追加日志内容-->

        <appendToFile value="true" />

        <!--防止多线程时不能写Log,官方说线程非安全-->

        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

        <!--可以为:Once|Size|Date|Composite-->

        <!--CompositeSizeDate的组合-->

        <rollingStyle value="Composite" />

        <!--当备份文件时,为文件名加的后缀-->

        <datePattern value="yyyyMMdd.TXT" />

        <!--日志最大个数,都是最新的-->

        <!--rollingStyle节点为Size,只能有value个日志-->

        <!--rollingStyle节点为Composite,每天有value个日志-->

        <maxSizeRollBackups value="20" />

        <!--可用的单位:KB|MB|GB-->

        <maximumFileSize value="3MB" />

        <!--置为true,当前最新日志文件名永远为file节中的名字-->

        <staticLogFileName value="true" />

        <!--输出级别在INFOERROR之间的日志-->

        <filter type="log4net.Filter.LevelRangeFilter">

            <param name="LevelMin" value="ALL" />

            <param name="LevelMax" value="FATAL" />

        </filter>

        <layout type="log4net.Layout.PatternLayout">

            <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>

        </layout>

    </appender>

    <!--SqlServer形式-->

    <!--下载NuGet包:  System. Data.SqlClient-->

    <!--log4net日志配置:http://logging.apache.org/log4net/release/config-examples.html -->

    <appender name="AdoNetAppender_SqlServer" type="log4net.Appender.AdoNetAppender">

        <!--日志缓存写入条数 设置为0时只要有一条就立刻写到数据库-->

        <bufferSize value="0" />

        <connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient" />

        <connectionString value="Data Source=.;Initial Catalog=Blog;Integrated Security=True;Connect Timeout=30;Encrypt=False;TrustServerCertificate=False;ApplicationIntent=ReadWrite;MultiSubnetFailover=False;" />

        <commandText value="INSERT INTO GblLogAudit ([Date],[Thread],[Level],[Logger],[LogType],[DataType],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @logType, @dataType, @message, @exception)" />

        <parameter>

            <parameterName value="@log_date" />

            <dbType value="DateTime" />

            <layout type="log4net.Layout.RawTimeStampLayout" />

        </parameter>

        <parameter>

            <parameterName value="@thread" />

            <dbType value="String" />

            <size value="255" />

            <layout type="log4net.Layout.PatternLayout">

                <conversionPattern value="%thread" />

            </layout>

        </parameter>

        <parameter>

            <parameterName value="@log_level" />

            <dbType value="String" />

            <size value="50" />

            <layout type="log4net.Layout.PatternLayout">

                <conversionPattern value="%level" />

            </layout>

        </parameter>

        <parameter>

            <parameterName value="@logger" />

            <dbType value="String" />

            <size value="255" />

            <layout type="log4net.Layout.PatternLayout">

                <conversionPattern value="%logger" />

            </layout>

        </parameter>

        <parameter>

            <parameterName value="@logType" />

            <dbType value="String" />

            <size value="50" />

            <layout type="log4net.Layout.PatternLayout">

                <conversionPattern value="%property{LogType}" />

            </layout>

        </parameter>

        <parameter>

            <parameterName value="@dataType" />

            <dbType value="String" />

            <size value="255" />

            <layout type="log4net.Layout.PatternLayout">

                <conversionPattern value="%property{DataType}" />

            </layout>

        </parameter>

        <parameter>

            <parameterName value="@message" />

            <dbType value="String" />

            <size value="999999999" />

            <layout type="log4net.Layout.PatternLayout">

                <conversionPattern value="%message" />

            </layout>

        </parameter>

        <parameter>

            <parameterName value="@exception" />

            <dbType value="String" />

            <size value="999999999" />

            <layout type="log4net.Layout.ExceptionLayout" />

        </parameter>

    </appender>

    <root>

        <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF-->

        <!--OFF:0-->

        <!--FATAL:FATAL-->

        <!--ERROR: ERROR,FATAL-->

        <!--WARN: WARN,ERROR,FATAL-->

        <!--INFO: INFO,WARN,ERROR,FATAL-->

        <!--DEBUG: INFO,WARN,ERROR,FATAL-->

        <!--ALL: DEBUG,INFO,WARN,ERROR,FATAL-->

        <priority value="ALL"/>

        <level value="INFO"/>

        <appender-ref ref="rollingAppender" />

        <appender-ref ref="AdoNetAppender_SqlServer" />

    </root>

</log4net>

2.2 重构实例化第3方“log4net”日志中间件的定义

//通过设定的持久化过滤规则及其配置文件(Log4net.config)中的数据实例,实例化第3方“log4net”日志中间件,最后把第3方“log4net”日志中间件依赖注入到内置容器中。

//注意:原示例代码是把把第3方“log4net”日志中间件依赖注入到内置依赖注入第3方“Autofac”容器中。

builder.Services.AddLogging(loging => {

    //第3方“log4net”日志中间件持久化过滤规则:在持久化时,过滤掉带有"System"命名空间的日志信息实例。

    loging.AddFilter("System", LogLevel.Error);

    //第3方“log4net”日志中间件持久化过滤规则:在持久化时,过滤掉带"Microsoft"命名空间的日志信息实例。

    loging.AddFilter("Microsoft", LogLevel.Error);

    loging.SetMinimumLevel(LogLevel.Error);

    loging.AddLog4Net("Log4net.config");

});


2.3 定义对日志实例进行持久化支撑的实体:GblLogAudit

008 GblLogAudit

GblLogAudit:继承了RootEntityTkey<Tkey>,通过该实体类及其属性成员,用于实现“log4net”日志中间件与“[Blog].[GblLogAudit]”表之间的CURD的插入操作,并把这些数据存储到数据库设置实例中(内存)。

  注意:

该实体类所对应的表是在“Code-First”模式下,由“SqlSugar”中间件自动生成;但插入操作通过“log4net”日志中间件,即“SqlSugar”中间件只能读取“[Blog].[GblLogAudit]”表,而不能对该表进行增/修/删等操作。 

        按F5执行程序后会自动把当前程序中的日志实例持久化到“[Blog].[GblLogAudit]”表中,如下图所示:

注意:

  1. 通过第3方“log4net”日志中间件把日志实例的持久化到表中只依赖于2个中间件:

(1)、“Microsoft.Extensions.Logging.Log4Net.AspNetCore”,被直接引用在“Extensions”项目中。

(2)、“System.Data.SqlClient”,被直接引用在启动项目中。

(3)、在原示例程序中并没有“System.Data.SqlClient”的直接引用。

        2、配置文件中的数据库提供程序的连接字符不要带版本和公共密钥信息,否则会导致不能被持久化到表中。

正确示例:

<connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient" />

              错误示例:

<connectionType value="System.Data.SqlClient.SqlConnection,System.Data.SqlClient, Version=4.6.1.3, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />

3、对于日志实例的持久化解决方案本人的看法:

第3方log4net日志中间件<第3方Nlog日志中间件<完全自定义,第3方Nlog日志中间件虽然在配置上可能相比第3方log4net日志中间件麻烦,但功能和可读性上比第3方log4net日志中间件安强的多;而完全自定义则可以保证实体类的定义实现的一致性,只获取自己需要被持久化的数据,强化了开发者对整个人程序的控制力。

4Bug由于“[Blog].[GblLogAudit]”表是在“Code-First”模式自动生成,所以在第1次执行程序时“[Blog].[GblLogAudit]”表中是无任何数据的,只有再次执行程序表中才有数据。

对以上功能更为具体实现和注释见:221123_04Blog(配置集成第3方log4net日志中间件)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/28353.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot2.X与redis Lettuce集成踩坑

起因 最近项目上发现一个问题&#xff0c;redis cluster集群有一台机崩了之后&#xff0c;后台服务的redis会一直报错&#xff0c;无法连接到redis集群。通过命令查看redis集群&#xff0c;发现redis cluster集群是正常的&#xff0c;备用的slave机器已经升级为master。 于是初…

c<7>存储

目录 1&#xff0c;局部变量 1,auto 2,static 2&#xff0c;全局变量的储存类型 3,register 4,extern 作用&#xff1a; 1&#xff0c;局部变量 #include <stdio.h> int main() {int fAuto(int a);int fStatic(int a); //函数声明int a 1, i; //自动局部变…

去了家新公司,技术总监不让用 IntelliJ IDEA想离职了

最近有个小伙伴微信和我说&#xff0c;新去的一家公司&#xff0c;技术团队全部规定要用的 Eclipse 开发&#xff0c;技术总监不让用 IntelliJ IDEA&#xff0c;付费也不行&#xff0c;说想离职了&#xff0c;问我该怎么办。 首先听到这件事情的时候&#xff0c;我表示十分理解…

关于消息队列的那些事

目录为什么需要消息队列1.异步处理2.服务解耦3.流量控制消息队列1.两种模型2.基本原理3.常见问题本篇文章参考文献如下&#xff1a; 面试题&#xff1a;如何保证消息不丢失&#xff1f;处理重复消息&#xff1f;消息有序性&#xff1f;消息堆积处理&#xff1f; (qq.com) 超详…

【数据通信】具有路由 WSN 模拟器的随机方式移动(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

Yolov5的类激活图

在本教程中&#xff0c;我们将了解如何将 EigenCAM&#xff08;无梯度方法之一&#xff09;用于 YOLO5。 这是https://github.com/jacobgil/pytorch-grad-cam/blob/master/tutorials/Class Activation Maps for Object Detection With Faster RCNN.ipynb 中 适用于 YOLO5的教程…

堆排序(算法实现)

文章目录堆排序-算法实现1. 向上调整和向下调整比较2. 堆排序1. 升序2. 降序堆排序-算法实现 前面介绍了堆的基本功能实现(https://blog.csdn.net/m0_46343224/article/details/127986662)&#xff0c;了解了堆&#xff0c;这里用堆实现排序 1. 向上调整和向下调整比较 思考&a…

1. pip和conda的区别

Pip 或者 conda的时候经常被混合使用&#xff0c;这两者也通常被认为是几乎相同的&#xff0c;尽管他们的很多功能是重叠的&#xff0c;但它们的设计和使用目的不同。所以这次参考官方的解释&#xff0c;来进行如下总结和归纳&#xff1a;附上官方解释&#xff1a;conda和pip的…

关于Python的局部变量和全局变量使用介绍

局部变量&#xff1a;在函数中定义的变量&#xff0c;作用域是当前函数&#xff0c;只对当前函数起作用。 全局变量&#xff1a;在代码开头定义的变量&#xff0c;作用域是整段代码&#xff0c;对整段代码起作用。 先看下面的实例&#xff0c; 最后给结论。 name ‘PythonTa…

月薪9K和年薪30W的职位,有什么区别?

【浙江杭州】加速科技 测试开发工程师&#xff08;15-30W/年&#xff09; 岗位职责&#xff1a; 1、根据产品的需求编写测试用例&#xff0c;搭建软硬件联合测试环境&#xff1b; 2、对研发的模块/系统进行测试并输出测试报告&#xff1b; 3、整理并定期提交buglist&#…

我的PFC岩土颗粒流离散元分析攻略(附赠学习资料)

作者 | Lobby &#xff0c;仿真秀专栏作者 导读&#xff1a;lobby曾是国内“双一流“”院校本硕连读土木专业的大学生&#xff0c;现在从事土木相关的研发工作。目前在仿真秀官网发布过数十篇付费文章&#xff0c;含金量颇高&#xff0c;受到用户的好评。本期我们将带来lobby老…

差分 【一维差分和二维差分】

全文目录&#x1f914;一维差分&#x1f615;差分数组的构建&#x1f914;二维差分&#x1f615;差分矩阵的构建&#x1f914;一维差分 首先来了解一下差分的性质&#xff0c;差分是前缀和的逆运算&#xff0c;如果说前缀和是&#xff1a;S f(n) &#xff0c;那么差分就是 D …

轻松拿下——类的默认成员函数

六大默认成员函数&#xff1a; 1、初始化&#xff1a;构造函数主要完成初始化工作 2、清理&#xff1a;析构函数主要完成清理工作 3、拷贝复制&#xff1a;拷贝构造是使用同类对象初始化创建对象 4、拷贝复制&#xff1a;赋值重载主要是把一个对象赋值给另一个对象&#xff…

linux文件压缩、解压缩以及归档

一、文件压缩、解压缩 1.linux compress命令&#xff08;compress/uncompress&#xff09; &#xff08;1&#xff09;压缩文件&#xff1a; [rootserver ~]# du -sh passwd1---查看文件大小 [rootserver ~]# time compress passwd1---time&#xff1a;查看时间 compress&…

医学主题词表(Medical Subject Headings, MeSH)

Medical Subject Headings 简称MeSH&#xff0c;由美国国立医学图书馆&#xff08;NLM出版&#xff09;&#xff0c;是目前最权威最常用的标准医学主题词表。 MeSH由范畴表&#xff08;Categories and Subcategories&#xff09;、字顺表&#xff08;Alphabetic listing&#…

AI 边缘计算平台 - 爱芯元智 AX620A 爱芯派开箱

最近疫情有点猛&#xff0c;宅在家里&#xff0c;没事找点事干&#xff0c;撸撸板子吧。 拿出来趁着双 11 优惠&#xff0c;花了 520 RMB / 块&#xff0c;买的两块爱芯派&#xff08;套餐&#xff09;&#xff0c;来个开箱贴&#xff0c;顺便测试一下开发板的串口、网口、音频…

智慧井盖解决方案-最新全套文件

智慧井盖解决方案-最新全套文件一、建设背景行业痛点二、建设思路三、建设方案四、获取 - 智慧井盖全套最新解决方案合集一、建设背景 城市井盖是每个城市管理的难点&#xff0c;井盖数量多&#xff0c;容易发生井盖破损或丢失后出现人员与财产损失。给群众生命财产带来损害。…

基于Netty的高性能API网关设计

0. 本文目的 对于网关设计&#xff0c;业界已有很多成熟的解决方案&#xff0c;开箱即用或者稍作自定义都能满足需求。本文主要是通过网关需求了解底层netty的使用&#xff0c;所以重心在netty的实践使用上。 1. 什么是网关 网关(Gateway)又称网间连接器、协议转换器。网关在…

基于球向量的粒子群优化(SPSO)算法在无人机路径规划中的实现(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客 &#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜…

PyTorch for Audio + Music Processing(2/3/4/5/6/7) :构建数据集和提取音频特征

基于Torchaudio构建数据集 文章目录基于Torchaudio构建数据集前言02 Training a feed forward network03 Making predictions04 Creating a custom dataset05 Extracting Mel spectrograms06 Padding audio files07 Preprocessing data on GPU一、下载数据集文件目录标注格式二…