necore webapi log4net插件 配置日期和文件大小滚动 Composite模式 自动删除自定义几天前的日志

Apache log4net – Apache log4net: Config Examples - Apache log4net

  • 官方示例实现RollingFileAppender

logging-log4net/DerivedAppender.cs at 3f2b32ca3259f0099358107dfcb032d15a56cdb8 · apache/logging-log4net (github.com)

  • Stack Overflow

c# - How I can set log4net to log my files into different folders each day? - Stack Overflow

  • 1、log4net.config 配置信息 VS2022 设置文件输出到目录
复制代码
<?xml version="1.0" encoding="utf-8" ?>
<log4net xsi:noNamespaceSchemaLocation="http://csharptest.net/downloads/schema/log4net.xsd"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <root>
        <!-- 控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF -->
        <level value="ALL" />
        <appender-ref ref="ErrorRollingFileAppender" />
        <appender-ref ref="WarnRollingFileAppender" />
        <appender-ref ref="InfoRollingFileAppender" />
        <appender-ref ref="DebugRollingFileAppender" />
    </root>

    <!--一般错误日志定义,用于记录已知需处理的与未捕获的异常-->
    <!--日志输出格式:[时间]:类名 线程号 消息-->
    <appender name="ErrorRollingFileAppender" type="System.MyRollingFileAppender">
        <!--  自定义删除几天前的日志 -->
        <param name= "MyOutDateDays" value= "30"/>
        <filter type="log4net.Filter.LevelRangeFilter">
            <levelMin value="ERROR" />
            <levelMax value="FATAL" />
        </filter>

        <filter type="log4net.Filter.DenyAllFilter" />
        <file value="logs/" />
        <rollingStyle value="Composite" />
        <!--保留文件的数量-->
        <maxSizeRollBackups value="20" />
        <!--保留文件的大小  可用的单位:KB|MB|GB-->
        <maximumFileSize value="300MB" />
        <datePattern value="yyyy-MM-dd/&quot;Error.log&quot;" />
        <staticLogFileName value="false" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="[%d{HH:mm:ss.fff}]  %c T%t %n%m%n" />
        </layout>
    </appender>

    <!--警告日志定义,用于记录已知不需处理的异常,系统警告信息-->
    <!--日志输出格式:[时间]:类名 线程号 消息-->
    <appender name="WarnRollingFileAppender" type="System.MyRollingFileAppender">
        <!--  自定义删除几天前的日志 -->
        <param name= "MyOutDateDays" value= "30"/>
        <filter type="log4net.Filter.LevelMatchFilter">
            <levelToMatch value="WARN" />
        </filter>
        <filter type="log4net.Filter.DenyAllFilter" />
        <file value="logs/" />
        <appendToFile value="true" />
        <rollingStyle value="Composite" />
        <!--保留文件的数量-->
        <maxSizeRollBackups value="20" />
        <!--保留文件的大小  可用的单位:KB|MB|GB-->
        <maximumFileSize value="300MB" />
        <datePattern value="yyyy-MM-dd/&quot;Warn.log&quot;" />
        <staticLogFileName value="false" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="[%d{HH:mm:ss.fff}] %c T%t %m%n" />
        </layout>
    </appender>

    <!--信息日志定义,用于记录用户相关信息-->
    <!--日志输出格式:[时间]:消息-->
    <appender name="InfoRollingFileAppender" type="System.MyRollingFileAppender">
        <!--  自定义删除几天前的日志 -->
        <param name= "MyOutDateDays" value= "30"/>
        <filter type="log4net.Filter.LevelMatchFilter">
            <levelToMatch value="INFO" />
        </filter>
        <filter type="log4net.Filter.DenyAllFilter" />
        <file value="logs/" />
        <appendToFile value="true" />
        <!--保留文件的数量-->
        <maxSizeRollBackups value="20" />
        <!--保留文件的大小  可用的单位:KB|MB|GB-->
        <maximumFileSize value="300MB" />
        <rollingStyle value="Composite" />
        <datePattern value="yyyy-MM-dd/&quot;Info.log&quot;" />
        <staticLogFileName value="false" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="[%d{HH:mm:ss}] (%c) %m%n" />
        </layout>
    </appender>

    <!--信息日志定义,用于收集开发调试信息-->
    <!--日志输出格式:[时间]:类名 线程号 消息-->
    <appender name="DebugRollingFileAppender" type="System.MyRollingFileAppender">
        <!--  自定义删除几天前的日志 -->
        <param name= "MyOutDateDays" value= "30"/>
        <filter type="log4net.Filter.LevelMatchFilter">
            <levelToMatch value="DEBUG" />
        </filter>
        <filter type="log4net.Filter.DenyAllFilter" />
        <file value="logs/" />
        <appendToFile value="true" />
        <!--保留文件的数量-->
        <maxSizeRollBackups value="20" />
        <!--保留文件的大小  可用的单位:KB|MB|GB-->
        <maximumFileSize value="300MB" />
        <rollingStyle value="Composite" />
        <datePattern value="yyyy-MM-dd/&quot;Debug.log&quot;" />
        <staticLogFileName value="false" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
        <layout type="log4net.Layout.PatternLayout">
            <conversionPattern value="[%d{HH:mm:ss.fff}] %c T%t: %m%n" />
        </layout>
    </appender>
</log4net>
复制代码

2、自定义RollingFileAppender

复制代码
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    public class MyRollingFileAppender : log4net.Appender.RollingFileAppender
    {
        /// <summary>
        /// 自动删除N天之前的日志 须大于0
        ///例如日志处于D:\bin\Debug\Logs\2022-09-28\20220928_Error.log  -> D:\bin\Debug\Logs\下文件夹  大于天数的日志文件夹会被删除
        /// </summary>
        public int MyOutDateDays { get; set; }

        protected override void OpenFile(string fileName, bool append)
        {

            base.OpenFile(fileName, append);
        }
        /// <summary>
        /// 自定义自己的操作
        /// </summary>
        public override void ActivateOptions()
        {
            base.ActivateOptions();
            //自定义删除操作
            DeleteLogFilesForOutDate();
        }

        private void DeleteLogFilesForOutDate()
        {
            try
            {
                string pBasepath = System.IO.Path.GetDirectoryName(File);
                //获取目录
                string strBasepath = Path.GetDirectoryName(pBasepath);
                foreach (string dirs in Directory.GetDirectories(strBasepath))
                {
                    DeleteDirtorys(dirs);
                }
            }
            catch (Exception ex)
            {

            }

        }

        private void DeleteDirtorys(string dir)
        {
            try
            {
                string datetimename = Path.GetFileNameWithoutExtension(dir);
                if (DateTime.TryParse(datetimename, out var dirWithSuccessTime) == false)
                {
                    //不是日期开始文件夹结束
                    return;

                }

                //当前的减去文件夹的名称时间天数
                if ((DateTime.Now - dirWithSuccessTime).TotalDays > MyOutDateDays && MyOutDateDays > 0)
                {
                    try
                    {
                        //强制删除文件夹
                        Directory.Delete(dir, true);
                    }
                    catch (Exception ex)
                    {
                    }

                }
            }
            catch (Exception ex)
            {
            }

        }
    }
}
复制代码

 netcore Startup.cs 使用

复制代码
 /// <summary>
        ///
        /// </summary>
        public IConfiguration Configuration { get; }
        public static ILoggerRepository LoggerRepository { get; set; }

   

        /// <summary>
        ///
        /// </summary>
        /// <param name="configuration"></param>
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
            //初始化log4net
            LoggerRepository = LogManager.CreateRepository("NETCoreRepository");
            Log4NetHelper.SetConfig(LoggerRepository, "log4net.config");
        }
复制代码
Log4NetHelper帮助类 配置
复制代码
  
using log4net;
using log4net.Config;
using log4net.Repository;
using System;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.IO;

namespace KK.Commons.Log
{
    /// <summary>
    /// log4net封装类
    /// *********************************使用说明**********************************
    /// 1.首先将配置文件(log4net.config或App.config)放置在程序运行目录
    /// 2.调用SetConfig方法,并传入配置文件的全路径
    /// </summary>
    public class Log4NetHelper
    {
        /// <summary>
        ///  log4net 仓储库
        /// </summary>
        private static ILoggerRepository _repository;

        private static readonly ConcurrentDictionary<string, ILog> Loggers = new ConcurrentDictionary<string, ILog>();

        /// <summary>
        /// 读取配置文件,并使其生效。如果未找到配置文件,则抛出异常
        /// </summary>
        /// <param name="repository"></param>
        /// <param name="configFilePath">配置文件全路径</param>
        public static void SetConfig(ILoggerRepository repository, string configFilePath)
        {
            _repository = repository;
            var fileInfo = new FileInfo(configFilePath);
            if (!fileInfo.Exists)
            {
                throw new Exception("未找到配置文件" + configFilePath);
            }
            XmlConfigurator.ConfigureAndWatch(_repository, fileInfo);
        }

        /// <summary>
        /// 获取记录器
        /// </summary>
        /// <param name="source">soruce</param>
        /// <returns></returns>
        private static ILog GetLogger(string source)
        {
            if (Loggers.ContainsKey(source))
            {
                return Loggers[source];
            }
            else
            {
                ILog logger = LogManager.GetLogger(_repository.Name, source);
                Loggers.TryAdd(source, logger);
                return logger;
            }
        }

        #region Log a message object

        /// <summary>
        /// 调试信息日志
        /// </summary>
        /// <param name="msg">日志信息</param>
        public static void Debug(string msg)
        {
            ILog logger = GetLogger("Debug");
            if (logger.IsDebugEnabled)
            {
                var stackTrace = new StackTrace();
                var stackFrame = stackTrace.GetFrame(1);
                var methodBase = stackFrame.GetMethod();
                var message = "方法名称:" + methodBase.Name + "\r\n日志内容:" + msg;
                logger.Debug(message);
            }
        }

        /// <summary>
        /// 错误信息日志
        /// </summary>
        /// <param name="msg">日志信息</param>
        public static void Error(string msg)
        {
            ILog logger = GetLogger("Debug");
            if (logger.IsErrorEnabled)
            {
                var stackTrace = new StackTrace();
                var stackFrame = stackTrace.GetFrame(1);
                var methodBase = stackFrame.GetMethod();
                var message = "方法名称:" + methodBase.Name + "\r\n日志内容:" + msg;
                logger.Error(message);
            }
        }

        /// <summary>
        /// 异常错误信息日志
        /// </summary>
        /// <param name="throwMsg">异常抛出信息</param>
        /// <param name="ex">异常信息</param>
        public static void Error(string throwMsg, Exception ex)
        {
            ILog logger = GetLogger("Error");
            if (logger.IsErrorEnabled)
            {
                var message =
                    $"抛出信息:{throwMsg} \r\n异常类型:{ex.GetType().Name} \r\n异常信息:{ex.Message} \r\n堆栈调用:\r\n{ex.StackTrace}";
                logger.Error(message);
            }
        }

        /// <summary>
        /// 异常错误信息
        /// </summary>
        /// <param name="source">source</param>
        /// <param name="throwMsg">异常抛出信息</param>
        /// <param name="ex">异常信息</param>
        public static void Error(Type source, object throwMsg, Exception ex)
        {
            ILog logger = GetLogger("Error");
            if (logger.IsErrorEnabled)
            {
                var message =
                    $"抛出信息:{throwMsg} \r\n异常类型:{ex.GetType().Name} \r\n异常信息:{ex.Message} \r\n【堆栈调用】:\r\n{ex.StackTrace}";
                logger.Error(message);
            }
        }

        /// <summary>
        /// 关键信息日志
        /// </summary>
        /// <param name="msg">日志信息</param>
        public static void Info(string msg)
        {
            ILog logger = GetLogger("Info");
            if (logger.IsInfoEnabled)
            {
                var stackTrace = new StackTrace();
                var stackFrame = stackTrace.GetFrame(1);
                var methodBase = stackFrame.GetMethod();
                var message = "方法名称:" + methodBase.Name + "\r\n日志内容:" + msg;
                logger.Info(message);
            }
        }

        /// <summary>
        /// 警告信息日志
        /// </summary>
        /// <param name="msg">日志信息</param>
        public static void Warn(string msg)
        {
            ILog logger = GetLogger("Warn");
            if (logger.IsWarnEnabled)
            {
                var stackTrace = new StackTrace();
                var stackFrame = stackTrace.GetFrame(1);
                var methodBase = stackFrame.GetMethod();
                var message = "方法名称:" + methodBase.Name + "\r\n日志内容:" + msg;
                logger.Warn(message);
            }
        }

        /// <summary>
        /// 失败信息日志
        /// </summary>
        /// <param name="msg">日志信息</param>
        public static void Fatal(string msg)
        {
            ILog logger = GetLogger("Fatal");
            if (logger.IsFatalEnabled)
            {
                var stackTrace = new StackTrace();
                var stackFrame = stackTrace.GetFrame(1);
                var methodBase = stackFrame.GetMethod();
                var message = "方法名称:" + methodBase.Name + "\r\n日志内容:" + msg;
                logger.Fatal(message);
            }
        }

        #endregion Log a message object

        /// <summary>
        /// 关键信息日志
        /// </summary>
        /// <param name="path">文件路径</param>
        /// <param name="msg">日志信息</param>
        public static void Info(string path, string msg)
        {
            ILog logger = GetLogger("Info");
            if (logger.IsInfoEnabled)
            {
                var stackTrace = new StackTrace();
                var stackFrame = stackTrace.GetFrame(1);
                var methodBase = stackFrame.GetMethod();
                var message = "方法名称:" + methodBase.Name + "\r\n日志内容:" + msg;
                logger.Info(message);
            }
        }
    }
}
复制代码

 

  • 例如 全局异常处理器中使用:
            var type = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType;
            string exDesc = requestPath + queryString;
            Log4NetHelper.Error(type, "全局捕获程序运行异常信息\n\r" + exDesc, context.Exception);

 

日志信息

 

 

  •  3、效果明细,自定义RollingFileAppender类读取和新增文件时,自动检查上两级下的目录是否为日期类型,检查日期名称距离今天是否大于配置的天数,删除目录下日志

 

posted @   JohnnyLei  阅读(511)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示