023. log4Net使用笔记
Log4net是个啥, 为什么要记录日志:
Log4Net是用来记录日志的, 可以将程序运行过程中的信息输出到指定的地方(文件, 数据库, EventLog等), 日志就是程序的黑匣子, 可以通过日志查看系统的运行过程, 从而发现系统运行过程中的问题.
日志的作用: 将运行过程中的步骤, 成功失败记录下来, 将关键性的数据记录下来分析系统问题所在; 对于网站来讲, 不能把异常信息显示给用户, 异常信息只能记录到日志中, 出了问题把日志文件给开发人员, 就能知道问题的所在.
Log4net可以设定多个Appender, 可以实现同时将日志记录到文件, 数据, 邮件等. 可以设定不同的Appender的不同Level, 可以实现普通级别的都记录在文件, Error级别的都发送邮件. 更加紧急的定义为发送短信
Log4net简单使用步骤:
1. 新建一个控制台项目, 添加一个应用程序配置文件(App.config)
2. 其中App.config中的默认原始内容如下:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> </configuration>
3. 在App.config中添加如下配置. 如果是web项目则在web.config中添加
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <!--使用section表示添加节点, 使用name="log4net" 表示所添加的节点的名字log4net, 使用type指定log4net这个节点由log4net.Config.Log4NetConfigurationSectionHandler,log4net这个类来解释--> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/> </configSections> <!--站点日志配置部分--> <log4net> <!--append表示追加, 加上er表示追加器, 即appender可以帮助我们将日志内容追加到文件.数据库中, 再从他的type 中可以看到它使用log4net.Appender.RollingFileAppender这个类来解析. 其中:log4net.Appender.RollingFileAppender表示滚动文件 log4net.Appender.AdoNetAppender 表示数据库 SmtpAppender 表示邮件--> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> <!--日志文件路径名称--> <file value="C:\Users\LG\Desktop\log4net.txt"/> <!--是否追加到文件,默认为true,通常无需设置--> <appendToFile value="true"/> <!--日志文件最多保留几份备份, 与maximumFileSize配合使用--> <MaxSizeRollBackups value="10"/> <!--单个日志文件的最大大小,可用的单位:KB|MB|GB,不要使用小数,否则会一直写入当前日志--> <maximumFileSize value="1MB"/> <!--滚动备份的格式, 按照大小进行滚动, 这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义, 即按照1MB来滚动备份--> <RollingStyle value="Size"/> <!--文件名是否固定, 一般不固定. 所以很少看到此配置--> <staticLogFileName value="true" /> <!--多线程时采用最小锁定--> <lockingModel type="log4net.Appender.FileAppender+MinimalLock"/> <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置--> <datePattern value="(yyyyMMdd)"/> <!--日志中每一行的格式--> <layout type="log4net.Layout.PatternLayout"> <!--<conversionPattern value="%date [%t]%-5p %c - %m%n"/>这是缩写 date日期, therad进程号 level日志级别, logger日志名称, 对应程序中的GetLogger, message日志的内容, newline换行符--> <conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/> </layout> </appender> <root> <!--控制级别,由低到高: ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF--> <!--比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录--> <!--如果没有定义LEVEL的值,则缺省为DEBUG--> <level value="DEBUG"/> <!--当前记录的级别为DEBUG--> <appender-ref ref="RollingFileAppender"/> </root> </log4net> </configuration>
4. 添加log4net.dll的引用, 下载地址
5. 开始测试, 测试代码如下:
using log4net; using System; namespace Log4NetDemo { class Program { static void Main(string[] args) { //从配置文件中读取log4net的配置, 然后初始化 log4net.Config.XmlConfigurator.Configure(); //开始写日志, 因为配置文件中定义的DEbug级别, 所以DEbug级别及以上的会被写入 ILog logWriter = log4net.LogManager.GetLogger("DemoWriter"); // "DemoWriter"表示一个key , 可以是任意字符 ,但是如果想往同一个文件中写日志, 需要将此字符串设置为一致即可 logWriter.Debug("DEBUG级别的消息"); logWriter.Error("错误级别的消息"); //可以调试了 Console.ReadKey(); } } }
效果图:
****************************************************************************
将log4net引用web到项目中
1. 在项目的packages目录下创建log4net目录, 将log4net.dll文件放到此目录下
2. 打开web.config文件, 复制下面的代码, 在 <configSections> </configSections>节点下添加log4net的节点配置, 整个web.config如下内容:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<!--Entity Framework块配置-->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
<!--复制到这里来作为Sprign.Net的块配置-->
<sectionGroup name="spring">
<section name="context" type="Spring.Context.Support.MvcContextHandler, Spring.Web.Mvc5" />
</sectionGroup>
<!--使用section表示添加节点, 使用name="log4net" 表示所添加的节点的名字log4net,
使用type指定log4net这个节点由log4net.Config.Log4NetConfigurationSectionHandler,log4net这个类来解释-->
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<!--Log4net配置的节点-->
<log4net>
<!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL -->
<!-- Set root logger level to ERROR and its appenders -->
<root>
<level value="ALL"/>
<appender-ref ref="SysAppender"/>
</root>
<logger name="WebLogger">
<level value="DEBUG"/>
</logger>
<appender name="SysAppender" type="log4net.Appender.RollingFileAppender,log4net" >
<!--文件存放的位置, 注意这里没有文件名, 文件名是动态的-->
<param name="File" value="App_Data/" />
<param name="AppendToFile" value="true" />
<!-- 根据日期滚动-->
<param name="RollingStyle" value="Date" />
<!-- 日期的格式, 这里可以看做是文件名的命名规范-->
<param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" />
<!-- 非静态格式, 表示每天创建-->
<param name="StaticLogFileName" value="false" />
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
<param name="Header日志开始" value="
----------------------header--------------------------
" />
<param name="Footer日志结束" value="
----------------------footer--------------------------
" />
</layout>
</appender>
<appender name="consoleApp" type="log4net.Appender.ConsoleAppender,log4net">
<layout type="log4net.Layout.PatternLayout,log4net">
<param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" />
</layout>
</appender>
</log4net>
. . . 一些其他的配置省略不复制 . . .
3. 到项目的Global.asax.cs文件下, 添加初始化工具, 当然要记得引用dll
using System.Web.Mvc; using System.Web.Optimization; using System.Web.Routing; namespace muTian.sysAdmin.UI.Portal { public class MvcApplication : Spring.Web.Mvc.SpringMvcApplication //System.Web.HttpApplication { protected void Application_Start() { AreaRegistration.RegisterAllAreas(); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //从配置文件中读取log4net的配置, 然后进行一个初始化工作 log4net.Config.XmlConfigurator.Configure(); } } }
4. 到muTian.SysAdmin.Common下, 增加一个Log4NetWriter 类
using log4net;
namespace muTian.SysAdmin.Common
{
//这个项目中也要引用log4net.dll
public class Log4NetWriter:ILogWriter
{
public void WriteLogInfo(string txt)
{
// 设置GetLogger指定的名字, 将Error级别的信息都记录到此名字下
log4net.ILog logWriter = log4net.LogManager.GetLogger("muTianxPro");
logWriter.Error(txt);
}
}
}
5. 修改之前创建的logHelper类:
using System.Collections.Generic; namespace muTian.SysAdmin.Common { //定义委托 //public delegate void WriteLogDel(string str); public class LogHelper { // public static WriteLogDel WriteLogDelFunc; //定义队列, 将此队列中的内容写入到日志文件中去 public static Queue<string> ExceptionStringQueue = new Queue<string>(); public static List<ILogWriter> LogWriterList = new List<ILogWriter>(); //定义静态的构造函数, 把从队列中获取的错误消息, 写入到日志文件中去 //访问包含静态构造函数的静态成员时,会先调用静态构造函数,无论创建了多少个类实例,其静态构造函数都只调用了一次 static LogHelper() { //WriteLogDelFunc = new WriteLogDel(WriteLogToFile); //WriteLogDelFunc += WriteLogToMongodb; //LogWriterList.Add(new TextFileWrieter()); //LogWriterList.Add(new SqlServerWriter()); LogWriterList.Add(new Log4NetWriter()); //启动线程, 把从队列中获取错误消息写到日志文件里面去 System.Threading.ThreadPool.QueueUserWorkItem(o=>{ lock (ExceptionStringQueue) { while (true) //不断的循环进行日志的监控 { if (ExceptionStringQueue.Count > 0) { string str = ExceptionStringQueue.Dequeue(); //把异常信息写到日志文件中去 //变化点: 有可能写到文件或者数据库; 或者两者同时写? //执行委托方法, 把异常信息写到委托里面去 //WriteLogDelFunc(str); //ILogWriter writer = new TextFileWrieter(); //writer.WriteLogInfo(str); foreach (var logwriter in LogWriterList) { logwriter.WriteLogInfo(str); } } else { System.Threading.Thread.Sleep(30); //如果为空, 线程休眠30毫秒; 其实最好的是监听队列的事件, 只有当数据进队的时候, 然后执行一次写入日志的操作. 其它的时间段, 都休眠 } } } }); } public static void WriteLog(string exceptionText) { //队列加锁, 执行期间不能再写入 lock (ExceptionStringQueue) { ExceptionStringQueue.Enqueue(exceptionText); } } //public static void WriteLogToFile(string txt) //{ //} //public static void WriteLogToMongodb(string txt) //{ //} } }
6. 测试
using muTian.SysAdmin.IBLL; using System; using System.Linq; using System.Web.Mvc; namespace muTian.sysAdmin.UI.Portal.Controllers { public class ActionInfoController : Controller { // GET: ActionInfo public IActionInfoService actionInfoService { get; set; } public ActionResult Index() { try { //log4net, 并不能自动去捕获异常, 所有的捕获异常的动作还是要靠自己完成 throw new Exception("测试是否写入异常到文本中"); } catch (Exception ex) { muTian.SysAdmin.Common.LogHelper.WriteLog(ex.ToString()); } ViewData.Model = actionInfoService.GetUsers(u => true).ToList(); return View(); } } }
7. 测试结果:
转一篇非常详细的log4net介绍:
http://www.cnblogs.com/zhangchenliang/p/4546352.html