C# 使用 log4net 日志组件
一、 什么是 log4net
Apache log4net 库是帮助程序员将日志语句输出到各种输出目标的工具,它是从Java中的Log4j迁移过来的一个.Net版的开源日志框架。log4net 的一个显著特征是分层记录器的概念。使用这些记录器可以有选择地控制以任意粒度输出哪些日志语句。主要特征如下:
- 支持多个框架
- 输出到多个日志记录目标
- 分层日志记录体系结构
- XML 配置
- 动态配置
- 日志记录上下文
- 久经考验的架构
- 模块化和可扩展设计
- 高性能和灵活性
二、C# 使用 log4net
添加Nuget 包,搜索到“log4net”后 ,选择安装,具体如下图所示:
三、添加 log4net 配置文件
使用 log4net需要我们配置log4net的配置文件,目前,配置文件是用 XML 编写的。一般有两种方式,一种是使用og4net自动生成的 “log4net.xml”进行配置,另一种是直接嵌入到运行程序的 app.config 文件中。
具体内容如下:


1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <configSections> 4 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> 5 </configSections> 6 <startup> 7 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 8 </startup> 9 <log4net> 10 <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --> 11 <!-- Set root logger level to ERROR and its appenders --> 12 <root> 13 <level value="ALL" /> 14 <appender-ref ref="SysAppender" /> 15 </root> 16 <!-- Print only messages of level DEBUG or above in the packages --> 17 <logger name="WebLogger"> 18 <level value="DEBUG" /> 19 </logger> 20 <appender name="SysAppender" type="log4net.Appender.RollingFileAppender,log4net"> 21 <param name="File" value="log/" /> 22 <param name="AppendToFile" value="true" /> 23 <param name="RollingStyle" value="Date" /> 24 <param name="DatePattern" value="'demo_'yyyy_MM_dd-HH'.log'" /> 25 <param name="StaticLogFileName" value="false" /> 26 <param name="RollingStyle" value="Composite" /> 27 <layout type="log4net.Layout.PatternLayout,log4net"> 28 <param name="ConversionPattern" value="%date [th=%3thread] [line:%5L] [%-5level] %message%newline"/> 29 </layout> 30 </appender> 31 <appender name="consoleApp" type="log4net.Appender.ConsoleAppender,log4net"> 32 <layout type="log4net.Layout.PatternLayout,log4net"> 33 <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> 34 </layout> 35 </appender> 36 </log4net> 37 </configuration>
View Code
主要参数含义如下:
三、源码测试
我们可以添加一个日志类,专门用于输出日志打印,具体代码如下:


1 public static class LogUtil 2 { 3 private static log4net.ILog Log { get; } = log4net.LogManager.GetLogger("log"); 4 5 6 public static void Configure(string exeConfigFile) 7 { 8 log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(exeConfigFile)); 9 } 10 11 private static string GetMethodName(int skipFrames = 2) 12 { 13 try 14 { 15 // 这里忽略skipFrames层堆栈,也就忽略了当前方法GetMethodName,以及调用此方法的方法,这样拿到的就正好是外部调用打印日志所在函数的方法信息 16 var method = new StackFrame(skipFrames).GetMethod(); 17 var properties = 18 method?.DeclaringType?.GetProperties( 19 BindingFlags.Instance | 20 BindingFlags.Static | 21 BindingFlags.Public | 22 BindingFlags.NonPublic); 23 var property = properties?.Where(p => p.GetGetMethod(true) == method || p.GetSetMethod(true) == method) 24 .FirstOrDefault(); 25 26 var name = $"{method?.DeclaringType?.ToString().Split('.').Last()}.{method?.Name}"; 27 return property == null 28 ? $"{name,-50}" 29 : $"{property.Name,-50}"; 30 } 31 catch (Exception e) 32 { 33 return "ERROR TO GET CALLING METHOD"; 34 } 35 } 36 private static string NoWarp(string msg) 37 { 38 return msg?.Replace("\r\n", " ").Replace("\n", " "); 39 } 40 private static string WrapException(string msg, Exception e) 41 { 42 var builder = new StringBuilder(msg); 43 builder.Append("\t[").Append(e.Message).Append("]"); 44 if (e.InnerException != null) 45 { 46 builder.Append(" --> [").Append(e.InnerException.Message).Append("]"); 47 } 48 49 return builder.ToString(); 50 } 51 52 53 54 55 public static void Debug(string msg) 56 { 57 Log.Debug(msg); 58 } 59 public static void Debug(string msg, Exception e) 60 { 61 Log.Debug(WrapException(msg, e), e); 62 } 63 64 public static void Info(string msg) 65 { 66 Log.Info(msg); 67 } 68 public static void Info(string msg, Exception e) 69 { 70 Log.Info(WrapException(msg, e), e); 71 } 72 73 public static void Warn(string msg) 74 { 75 Log.Warn(msg); 76 } 77 public static void Warn(string msg, Exception e) 78 { 79 Log.Warn(WrapException(msg, e), e); 80 } 81 82 public static void Error(string msg) 83 { 84 Log.Error(msg); 85 } 86 public static void Error(string msg, Exception e) 87 { 88 Log.Error(WrapException(msg, e), e); 89 } 90 91 public static void Fatal(string msg) 92 { 93 Log.Fatal(msg); 94 } 95 public static void Fatal(string msg, Exception e) 96 { 97 Log.Fatal(WrapException(msg, e), e); 98 } 99 }
View Code
测试代码如下:


1 static void Main(string[] args) 2 { 3 try 4 { 5 string exeConfigFile = $"{AppDomain.CurrentDomain.BaseDirectory}//Log4netDemo.exe.config"; 6 7 if (File.Exists(exeConfigFile) == false) 8 { 9 throw new Exception($"应用程序配置文件 [{exeConfigFile}] 不存在,无法加载日志 log4net 的配置"); 10 } 11 12 XmlConfigurator.Configure(new FileInfo(exeConfigFile)); 13 LogUtil.Info("====================================== Log4netDemo started, log4net setup..."); 14 LogUtil.Warn("程序启动入参不合理"); 15 LogUtil.Error("程序启动失败"); 16 17 Console.ReadKey(); 18 } 19 catch (Exception ex) 20 { 21 Console.WriteLine(ex); 22 LogUtil.Error("程序加载失败",ex); 23 } 24 }
View Code
运行程序后,实际输出效果如下:
四、引用地址
- //logging.apache.org/log4net/release/manual/configuration.html
- //www.sohu.com/a/254335960_696685
- //blog.csdn.net/hr541659660/article/details/45575473