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

posted on 2017-03-07 11:51  印子  阅读(228)  评论(0)    收藏  举报

导航