necore webapi log4net插件 配置日期和文件大小滚动 Composite模式 自动删除自定义几天前的日志
- 安装log4net NuGet Gallery | log4net 2.0.15
- 官方配置信息
Apache log4net – Apache log4net: Config Examples - Apache log4net
- 官方示例实现RollingFileAppender
- 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/"Error.log"" /> <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/"Warn.log"" /> <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/"Info.log"" /> <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/"Debug.log"" /> <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类读取和新增文件时,自动检查上两级下的目录是否为日期类型,检查日期名称距离今天是否大于配置的天数,删除目录下日志
分类:
Log工具
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现