C# Log4net日志 配置 与AppenderSkeleton

news2025/1/12 18:04:00

https://www.cnblogs.com/yaopengfei/p/9428206.html

一、Log4Net简介

Log4net是从Java中的Log4j迁移过来的一个.Net版的开源日志框架,它的功能很强大,可以将日志分为不同的等级,以不同的格式输出到不同的存储介质中,比如:数据库、txt文件、内存缓冲区、邮件、控制台、ANSI终端、远程接收端等等,我们这里主要介绍最常用的两种:txt文件和数据库。

日志级别

Log4net将日志分为六个级别,

  • Trace: 最详细的日志信息。
  • Debug: 调试信息,通常用于开发和调试阶段。
  • Info: 一般信息,表示应用程序的正常操作状态。
  • Warn: 警告信息,指示可能的问题或异常情况。
  • Error: 错误信息,表示出现了异常或错误情况。
  • Fatal: 致命错误,表示程序可能无法继续运行

二、安装Log4Net

安装

 配置

<?xml version="1.0" encoding="utf-8"?>
<configuration>
	<!-- 1. 添加log4net的节点声明配置代码-->
	<configSections>
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
	</configSections>
	<!--2. log4net的核心配置代码-->
	<log4net>
		<!--把日志信息输出到以日期命名的文件里-->
		<appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender">
			<!--文件夹的位置-->
			<file value="D:\MyLog1\" />
			<appendToFile value="true" />
			<!--动态生成文件名-->
			<param name="StaticLogFileName" value="false" />
			<!--以日期命名-->
			<param name="DatePattern" value="yyyyMMdd&quot;.log&quot;" />
			<rollingStyle value="Date" />
			<!--日志在日志文件中的布局方式-->
			<layout type="log4net.Layout.PatternLayout">
				<conversionPattern value="%newline %n记录时间:%date %n线程ID:[%thread] %n日志级别:  %-5level %n出错类:%logger property: [%property{NDC}] - %n错误描述:%message%newline %n" />
			</layout>
			<!--使用最小锁定模型(minimal locking model),以允许多个进程可以写入同一个文件 -->
			<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
		</appender>
		<root>
			<level value="ALL"></level>
			<appender-ref ref="RollingFileAppender"></appender-ref>
		</root>
	</log4net>
	<startup>
		<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
	</startup>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="log4net" publicKeyToken="669e0ddf0bb1aa2a" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.0.15.0" newVersion="2.0.15.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>



添加配置

// log4net初始化配置文件     作用域全局 //代码:
//Log4net配置
[assembly: log4net.Config.XmlConfigurator(ConfigFileExtension = "config", Watch = true)]

测试:

        static void Main()
        {

            log4net.ILog _log = log4net.LogManager.GetLogger("Main");
            _log.Info("正常信息 ");
            _log.Error("错误");


            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

三、项目配置文件

步骤:

1、添加log4net.config

注意点:

2、编写 log4net.config文件

3、编写AssemblyInfo.cs 文本

[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", ConfigFileExtension = "config", Watch = true)]

测试;


        private void button1_Click(object sender, EventArgs e)
        {
            log4net.ILog log = log4net.LogManager.GetLogger("AppLogger1");

            log.Info("button  test");

        }

配置2:

不需要再AssemblyInfo.cs 文件,需要直接调用方法

     // strlog4Config  这里传入的是log4net.config 的配置文件
    public  static  void InitLogNet(string  strlog4Config)
        {
            log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(strlog4Config));
            _Logfile = strlog4Config;
            _Log["info_logo"] = log4net.LogManager.GetLogger("info_logo");
            _Log["error_logo"] = log4net.LogManager.GetLogger("error_logo");
        }

调用:

Log4NetHelper.InitLog4Net(Application.StartupPath + "\\log4net.config");    

code2 :

  public  class Log4NetHelper
  {
      private static string _Logfile;
      private static Dictionary<string, log4net.ILog> _Log = new Dictionary<string, log4net.ILog>();

      public  static  void InitLogNet(string  strlog4Config)
      {
          log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(strlog4Config));
          _Logfile = strlog4Config;
          _Log["info_logo"] = log4net.LogManager.GetLogger("info_logo");
          _Log["error_logo"] = log4net.LogManager.GetLogger("error_logo");
      }


      /// <summary>
      /// 写入日志
      /// </summary>
      public  static  void  WriteInfoLog(string strInfoLog)
      {
          if (_Log["info_logo"].IsInfoEnabled)
          {
              _Log["info_logo"].Info(strInfoLog);
          }
      }
      /// <summary>
      /// 功能描述:写入错误日志
      /// </summary>
      /// <param name="strErrLog">strErrLog</param>
      /// <param name="ex">ex</param>
      public static void WriteErrorLog(string strErrLog, Exception ex = null)
      {
          if (_Log["error_logo"].IsErrorEnabled)
          {
              _Log["error_logo"].Error(strErrLog, ex);
          }
      }
      /// <summary>
      /// 功能描述:写入日志
      /// </summary>
      /// <param name="strType">日志类型(对应log4net配置文件中logger.nama)</param>
      /// <param name="strLog">strLog</param>
      public static void WriteByLogType(string strType, string strLog)
      {
          if (!_Log.ContainsKey(strType))
          {
              //判断是否存在节点
              if (!HasLogNode(strType))
              {
                  WriteErrorLog("log4net配置文件不存在【" + strType + "】配置");
                  return;
              }
              _Log[strType] = log4net.LogManager.GetLogger(strType);
          }
          _Log[strType].Error(strLog);
      }

      /// <summary>
      /// 功能描述:是否存在指定的配置
      /// </summary>
      /// <param name="strNodeName">strNodeName</param>
      /// <returns>返回值</returns>
      private static bool HasLogNode(string strNodeName)
      {
          XmlDocument doc = new XmlDocument();
          doc.Load(_Logfile);
          var lstNodes = doc.SelectNodes("//configuration/log4net/logger");
          foreach (XmlNode item in lstNodes)
          {
              if (item.Attributes["name"].Value.ToLower() == strNodeName)
                  return true;
          }
          return false;
      }

  }

c# log4net 配置使用-腾讯云开发者社区-腾讯云

C#在window服务配置Log4Net.dll-腾讯云开发者社区-腾讯云

C# log4net 日志输出超详细_c#用log4net输出多个参数-CSDN博客

 四、目前项目配置

log4net.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <!--在配置选项中加入log4net的引用-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
  </configSections>
	
	
  <log4net>
    <logger name="modifyLogger">
      <level value="ALL" />
      <appender-ref ref="modifyLogFile" />
    </logger>

    <!--用于记录额外的一些重要记录,比如关键参数修改记录-->
    <appender  name="modifyLogFile" type="log4net.Appender.RollingFileAppender,log4net" >
      <!--日志路径-->
      <param name= "File" value= "log/modify/"/>
      <!--是否是向文件中追加日志-->
      <param name= "AppendToFile" value= "true"/>
      <!--log保留天数,只有当日志名称都一样的才一样,日志名称为日期的时候,此处配置失效,无法使用-->
      <param name= "MaxSizeRollBackups" value= "10"/>
      <!--日志文件名是否是固定不变的-->
      <param name= "StaticLogFileName" value= "false"/>
      <!--日志文件名格式为:2008-08-31.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd&quot;.log&quot;"/>
      <!-- RollingStyle Composite 综合  Size 按大小  Date 按时间 -->
      <param name= "RollingStyle" value= "Composite"/>
      <!--不要使用小数,否则会一直写入当前日志-->
      <maximumFileSize value="10MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="&#xD;&#xA;----------------------application startup--------------------------&#xD;&#xA;" />
        <param name="Footer" value="&#xD;&#xA; ----------------------application shutdown--------------------------&#xD;&#xA;" />
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} --%-5p-- %m%n" />
      </layout>
    </appender>

	  
	  
	  
    <logger name="logLogger">
      <level value="ALL" />
      <appender-ref ref="LogFile" />
    </logger>

    <appender  name="LogFile" type="log4net.Appender.RollingFileAppender,log4net" >
      <!--日志路径-->
      <param name= "File" value= "log/"/>
      <!--是否是向文件中追加日志-->
      <param name= "AppendToFile" value= "true"/>
      <!--log保留天数,只有当日志名称都一样的才一样,日志名称为日期的时候,失效-->
      <param name= "MaxSizeRollBackups" value= "10"/>
      <!--日志文件名是否是固定不变的-->
      <param name= "StaticLogFileName" value= "false"/>
      <!--日志文件名格式为:2008-08-31.log-->
      <param name= "DatePattern" value= "yyyy-MM-dd&quot;.log&quot;"/>
      <!-- RollingStyle Composite 综合  Size 按大小  Date 按时间 -->
      <param name= "RollingStyle" value= "Composite"/>
      <!--不要使用小数,否则会一直写入当前日志-->
      <maximumFileSize value="10MB"/>
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="&#xD;&#xA;----------------------application startup--------------------------&#xD;&#xA;" />
        <param name="Footer" value="&#xD;&#xA; ----------------------application shutdown--------------------------&#xD;&#xA;" />
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} --%-5p-- %m%n" />
      </layout>
    </appender>

    <appender>
      <!--一个配置文件可以有很多appender,一个appender节就相当于一个日志输出介质或方法。-->
    </appender>
    <logger name="logApp">
      <!--定义logger对象的名字为logApp,以方便在代码中使用logger-->
      <!--配置项可以不配置-->
      <level value="ALL" />
      <!--定义输出的信息等级为所有其中包括Fatal.Error.Warn.Info.Debug-->
    </logger>
    <root>
    </root>
  </log4net>
</configuration>

代码调用:

   public static bool s_IsStarting = false;//程序正在加载中 
   public static List<string> s_ErrMsg = new List<string>();//加载过程中是错误信息

   private static ILog log4Net = log4net.LogManager.GetLogger("logLogger");//全局日志 "logLogger"与log4net.config配置里的名称一致
   private static readonly ILog LogModify = LogManager.GetLogger("modifyLogger");//模块参数修改记录

注意:

五、AppenderSkeleton自定义

AppenderSkeletonlog4net 日志记录库中的一个抽象基类,用于实现自定义的日志附加器(Appender)。AppenderSkeleton 类提供了一个基本的实现框架,简化了创建自定义附加器的过程。

AppenderSkeleton 概述

log4net 中,Appender 是用于将日志消息输出到某个目标的组件,例如文件、控制台、数据库等。AppenderSkeleton 作为一个基类,帮助开发者创建自定义的附加器,而无需从头开始实现所有的功能

主要功能和特性

  • 基础功能: AppenderSkeleton 提供了一些基本的功能,如处理日志事件和配置附加器。
  • 日志事件处理: 它实现了处理日志事件的逻辑,这样你可以集中精力在如何将日志输出到特定目标上。
  • 配置支持: 支持通过 log4net 的配置文件进行配置。

关键方法和属性

  • Append(LoggingEvent loggingEvent):

    • 这是一个抽象方法,必须在自定义附加器中实现。它接收一个 LoggingEvent 对象,表示一个日志事件,并定义如何处理这个日志事件。你可以在这里实现将日志消息输出到目标的逻辑。    
  • ActivateOptions():

    • 这个方法用于初始化附加器的配置选项。log4net 会在附加器的配置被激活时调用这个方法。
  • RenderLoggingEvent(LoggingEvent loggingEvent):

    • 这个方法将 LoggingEvent 转换为字符串,通常用于格式化日志消息。可以根据需要重写这个方法以提供自定义的日志消息格式。

配置config 文件

<appender name="CustomAppender" type="YourNamespace.CustomAppender, YourAssembly">
  <!-- 这里可以添加自定义配置选项 -->
</appender>

<root>
  <level value="DEBUG" />
  <appender-ref ref="CustomAppender" />
</root>

示例代码


    public class CustomAppender : AppenderSkeleton
    {
        protected  override void Append(LoggingEvent loggingEvent)
        {

            // 实现自定义的日志处理逻辑
            //RenderLoggingEvent 方法将 LoggingEvent 对象中的信息(如日志级别、日志消息、时间戳等)转换为字符串。这使得日志消息可以被输出到配置的目标(如文件或控制台)中。
            string _logMessage =RenderLoggingEvent(loggingEvent);
            Console.WriteLine($"Custom Log Output: {_logMessage}");

        }

        public override void ActivateOptions()
        {
            base.ActivateOptions();
            // 自定义初始化逻辑
        }
   }

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

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

相关文章

Vue框架学习笔记-6

Vue中的路由 Vue中的路由&#xff08;Routing&#xff09;是通过Vue Router这个官方提供的路由管理器来实现的。Vue Router允许你通过不同的URL访问应用中不同的页面&#xff08;组件&#xff09;&#xff0c;而无需重新加载页面。这对于构建单页应用&#xff08;SPA, Single …

数字引领风尚·智能改变生活“青岛电博会”路演活动(济南站)

2024CICE中国国际消费电子博览会路演活动&#xff08;济南站&#xff09;成功举行 数字引领风尚&#xff0c;智能改变生活。 8月7日&#xff0c;50余家行业协会、企业嘉宾、展商代表等云集2024中国国际消费电子博览会路演活动&#xff08;济南站&#xff09;现场&#xff0c;共…

【香菇带你学Mysql】Linux下Mysql8使用二进制安装包安装教程【建议收藏】

⚠️ 本人声明&#xff1a;本教程可100%复现​ 网上看了很多Mysql8安装的方式&#xff0c;基本上都是都过一个yum方式直接访问公网下载依赖资源安装的。 但是在企业内部一般并不允许生产环境直接连接公网。针对此情况。本文将介绍如何在内网环境下使用二进制安装包本地安装方式…

【多线程】乐观/悲观锁、重量级/轻量级锁、挂起等待/自旋锁、公平/非公锁、可重入/不可重入锁、读写锁

文章目录 乐观锁和悲观锁重量级锁和轻量级锁挂起等待锁和自旋锁公平锁和非公平锁可重入锁和不可重入锁读写锁相关面试题 锁&#xff1a;非常广义的概念&#xff0c;不是指某个具体的锁&#xff0c;所有的锁都可以往这些策略中套 synchronized&#xff1a;只是市面上五花八门的锁…

新形势下职业教育云计算人才培养策略

一、引言 在数字化转型的浪潮中&#xff0c;云计算作为核心技术之一&#xff0c;正在深刻影响着各行各业的发展。职业教育作为培养技术技能型人才的重要途径&#xff0c;需要紧跟时代步伐&#xff0c;不断优化和创新云计算人才培养模式&#xff0c;以满足社会对云计算人才的迫…

基于MyBatis-plus的SpringBoot开发

目录 一、SpringBoot整合mybatis 二、SpringBoot整合mybatis-plus 1、什么是mybatis-plus&#xff1f; 2、mybatis-plus的特性 3、mybatis-plus的使用 &#xff08;1&#xff09;编写注解配置实体类与关系表映射关系 &#xff08;2&#xff09;mapper层 &#xff08;3…

Sandbox: rsync.samba(80134) deny(1) file-write-create

Xcode15运行报错:Sandbox: rsync.samba(80134) deny(1) file-write-create/xxx/xxx 如下图: 解决办法: Build Settings 搜索 sandbox&#xff0c;把 Build Options 中的 User Script Sandboxing改为 NO

iPhone很多空相簿怎么删除:简化你的照片库

随着我们使用iPhone拍摄越来越多的照片和视频&#xff0c;管理这些内容的需求也随之增加。创建相簿是组织照片的一种便捷方式&#xff0c;但随着时间的推移&#xff0c;可能会产生许多未使用或空的相簿。这些空相簿不仅占用了照片应用的界面空间&#xff0c;也让照片库显得更加…

代码随想录算法训练营第四十二天|广度优先搜索理论基础、岛屿数量:深搜版、岛屿数量:广搜版

广度优先搜索理论基础 广搜&#xff08;bfs&#xff09;是一圈一圈的搜索过程。因为广搜是从起点出发&#xff0c;以起始点为中心一圈一圈进行搜索&#xff0c;一旦遇到终点&#xff0c;记录之前走过的节点就是一条最短路。 广搜的过程&#xff1a;我们从图中可以看出&#x…

HTML+CSS进阶用法(上)——平面转换、渐变、空间转换

欢迎来到CSS变换的世界&#xff0c;这里充满了创意和可能性。在本篇博客中&#xff0c;我们将一起学习如何使用transform属性来实现各种平面和空间转换效果&#xff0c;包括位移、旋转、缩放&#xff0c;以及如何通过渐变和动画来增强我们的网页设计。无论你是初学者还是有经验…

【区块链+金融服务】基于区块链的区域股权金融综合服务平台 | FISCO BCOS应用案例

区域性股权市场是我国资本市场的重要组成部分&#xff0c;是多层次资本市场体系的基石。区块链技术与区域性股权市场 分散特征天然匹配&#xff0c;从新型金融基础设施层面为场外参与各方提供公共的可信服务&#xff0c;以技术手段完善市场基础条 件&#xff0c;弥补区域性短板…

仿RabbiteMq实现简易消息队列正式篇(需求分析)

TOC 目录 MQ的实现方法 RabbitMq中的相关概念 消息队列系统模块划分 总体划分 服务端模块 数据管理模块 虚拟机数据管理模块 交换机路由模块 消费者管理模块 信道&#xff08;通信&#xff09;管理模块 连接管理模块 服务端BrokerServer模块 客户端模块 消费者管…

iPhone 16 机模视频曝光,五种颜色各有千秋

科技博主的最新视频分享了苹果 iPhone 16 标准版的机模上手体验。 视频中展示了五种颜色的 iPhone 16&#xff1a;深邃的蓝色、柔和的粉色、纯净的白色、经典的黑色和生机勃勃的绿色。 与 iPhone 15 相比&#xff0c;iPhone 16 弃用了黄色&#xff0c;新增了白色&#xff0c;…

等保测评中的供应链安全管理:构建安全的数字生态

在数字化转型的浪潮中&#xff0c;供应链已成为企业运营的核心环节&#xff0c;同时也是信息安全的潜在脆弱点。等保测评&#xff0c;作为我国信息安全等级保护制度的重要组成部分&#xff0c;对供应链安全管理提出了明确的要求&#xff0c;旨在构建一个安全、可靠的数字生态。…

Vue 3+Vite+Eectron从入门到实战系列之(六)一工作台界面开发及实现响应式

工作台&#xff0c;是每个后台系统必备的&#xff0c;也是管理系统的首页。这次我们来实现一个工作台&#xff0c;并适配他的响应性 实现效果 代码实现 <template><div class"dashboard"><el-row :gutter"20"><el-col class"mb…

小程序学习day06-wx:for续、WXSS模版样式、rpx尺寸单位、@import、全局样式与局部样式、全局配置

25、wx&#xff1a;for续 &#xff08;5&#xff09;手动指定索引和当前项的变量名 1&#xff09;使用wx:for-index可以指定当前循环项的索引变量名 2&#xff09;使用wx:for-item可以指定当前项的变量名 &#xff08;6&#xff09;wx:key的使用 类似于Vue列表渲染中的:key&a…

2025考研西安电子科技大学马克思主义理论经验贴

学长从西安电子科技大学马克思主义理论专业毕业&#xff0c;现从事高校思政课工作&#xff0c;拥有三年西安电子科技大学马理论考研辅导经验&#xff0c;现写出2025西安电子科技大学马克思主义理论经验贴供大家参考。 一、选学校 选学校首先考虑的是就业&#xff0c;因为咱们…

【书生大模型实战营(暑假场)】基础任务四 InternLM+LlamaIndex RAG 实践

基础任务四 InternLMLlamaIndex RAG 实践 任务文档视频Retrieval-Augmented Generation for Large Language Models: A Survey 文章目录 基础任务四 InternLMLlamaIndex RAG 实践1 理解RAG&#xff0c;使用 RAG1.1 RAG技术概览1.2 RAG工作原理1.3 向量数据库 Vector-DB1.4 RAG…

多态(二)

1. final &#xff1a;修饰虚函数&#xff0c;表示该虚函数不能再被重写 class Car { public:virtual void Drive() final {} }; class Benz :public Car { public:virtual void Drive() {cout << "Benz-舒适" << endl;} }; 2. override: 检查派生类…

如何选取网络中间的输出?并极简方法可视化

文章目录 一、提供几种方法1. 直接修改模型的 forward 方法&#xff1a;2. 使用 hook 函数&#xff1a;3. 直接访问模型的子模块&#xff1a;4. 使用 nn.Sequential 来提取中间层&#xff1a; 2. 如何选择方法3. 实际操作——提取特征并可视化1. 可视化2. 提取特征 一、提供几种…