首页 > 代码库 > 玩转Log4Net

玩转Log4Net

玩转Log4Net
下载Log4Net

           下载地址:http://logging.apache.org/log4net/download_log4net.cgi

           把下载的  log4net-1.2.11-bin-newkey解压后,如下图所示:

          技术分享

            双击bin文件夹

              技术分享

              双击net文件夹,选择针对.NET FramerWork的不同版本

              技术分享

             找到相应版本的log4net.dll

 

创建LogHelper类库 {生成dll便于多个项目引用}
 
{这里实现 错误日志和记录日志两个功能}
 using log4net;//引用上面的log4net.dll
 using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace LogHelper
{
    public class Log : ApplicationException//自己定义的类log,继承ApplicationException,来实现自己定义的功能
    {
        private static ILog ErrorLog;//错误日志
        private static ILog RecordLog;//记录日志
        static Log()//静态构造函数的好处是只在使用它的程序中,在第一次new的时候在这里初始化信息;不然每次new就需要初始化一次
        {
            string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");//在需要使用log4net功能的项目中,根目录下配置log4net.config{新建项配置文件},引用这个类;就能够实现日志功能
            if (!File.Exists(configFile))
            {
                throw new System.Exception("log4net Config File Not Found");
            }
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(configFile));
            ErrorLog = log4net.LogManager.GetLogger("ErrorLog");
            RecordLog = log4net.LogManager.GetLogger("RecordLog");
        }//
 
        public static void WriteError(string error)
        {
            if (ErrorLog.IsErrorEnabled)
            {
                ErrorLog.Error(error);
            }
        }
        public static void WriteRecord(string record)
        {
            if (RecordLog.IsInfoEnabled)
            {
                RecordLog.Info(record);
            }
        }
        //其他功能...
 
    }
}

 
模拟项目引用 logherlper类库
 protected void Page_Load(object sender, EventArgs e)//aspx页面
        {
//引用 LogHelper.dll
            try
            {
                int a = 0;
                int c = 10 / a;
            }
            catch (Exception ex)
            {
                Log.WriteError(ex.Message);//异常情况下记录错误日志
            }
            Log.WriteRecord("模拟记录数据");
     
            Response.Write(1111);
        } 

 
在aspx页面所在的项目中配置Log4net 
新建项---web配置文件----命名为 log4net.config{需要和LOghelper中的名字对应}-----配置如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <!--【Log4Net配置开始】-->
  
  <configSections>
    
    <!--【这句话直接粘即可】-->
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />
  </configSections>
 
  <log4net debug="true">
    <!--【debug="true"便于调试;在正式发布的情况下为了安全起见,需要改为false!!!】-->
    
    <appender name="ErrorLogFile" type="log4net.Appender.RollingFileAppender">
      <!--<file value="http://www.mamicode.com/applicationLog.log" />   -->
      <file type="log4net.Util.PatternString"  value="http://www.mamicode.com/E:/Codes/Log4NetDemo/Log4NetDemo/%date{yyyy}/%date{MM}/error_log%date{yyyy-MM-dd}.log" />
      <!--
      【ErrorLogFile是为此appender节点起的名字,下面的Logger节点需要用到这个name;】
      
      【file可以指定具体的路径 eg : d:\\test.log。不指定的话log被生成在项目的bin/Debug 或者 bin/Release目录下 (web的项目 默认生成在根目录下);applicationLog.log就是生成的日志文件的名称】
      
      【File在实际开发的情况下,日志可能比较多,就需要分类文件夹来进行管理,使用type属性,value指定中使用%date{}的方式就可以指定自动创建文件夹和文件,存在的话不会再创建】
      -->
      <appendToFile value="http://www.mamicode.com/true" />
      <rollingStyle value="http://www.mamicode.com/Size" />
      <maxSizeRollBackups value="http://www.mamicode.com/10" />
      <!--【备份log文件的个数最多10个】-->
      
      <maximumFileSize value="http://www.mamicode.com/2MB" />
      <!--【每个log文件最大是2M,如果超过2M将重新创建一个新的log文件,并将原来的log文件备份。】-->
      
      <staticLogFileName value="http://www.mamicode.com/true" />
      <layout type="log4net.Layout.PatternLayout">
        
        <conversionPattern value="http://www.mamicode.com/[%date] %thread -- %-5level -- %logger [%M] -- %message%newline" />
        <!--指定log的格式【conversionPattern这里同样是通过%组合log4定义的特殊意义的标记来组合,日志要呈现的结果;这样的格式就很好,一般就这个不用动就行】-->
 
      </layout>
    </appender>
 
 
    <!--【如果是想实现功能的分类处理,比如 错误的error一类 记录的record一类;多个功能配置只需要再罗列appender和对应的logger节点即可】如之 罗列的appender节点-->
    
    <appender name="RecordLogFile" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString"  value="http://www.mamicode.com/E:/Codes/Log4NetDemo/Log4NetDemo/%date{yyyy}/%date{MM}/record_log%date{yyyy-MM-dd}.log" />
     
      <appendToFile value="http://www.mamicode.com/true" />
      <rollingStyle value="http://www.mamicode.com/Size" />
      <maxSizeRollBackups value="http://www.mamicode.com/10" />
      <maximumFileSize value="http://www.mamicode.com/2MB" />
      <staticLogFileName value="http://www.mamicode.com/true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="http://www.mamicode.com/[%date] %thread -- %-5level -- %logger [%M] -- %message%newline" />
       
      </layout>
    </appender>
    <!--【如果是想实现功能的分类处理,比如 错误的error一类 记录的record一类;多个功能配置只需要再罗列appender和对应的logger节点即可】-->
 
    
    <!--【logger的name,在c#代码中getlogger(name)来获取配置的对象】-->
    <logger name="ErrorLog">
      <level value="http://www.mamicode.com/1"/>
      <!--【ref指向关联的appender的name】-->
      <appender-ref ref="ErrorLogFile"/>
    </logger>
    <!--【如果是想实现功能的分类处理,比如 错误的error一类 记录的record一类;多个功能配置只需要再罗列appender和对应的logger节点即可】如之 罗列的logger节点-->
    <logger name="RecordLog">
      <level value="http://www.mamicode.com/2"/>
      <!--【ref指向关联的appender的name】-->
      <appender-ref ref="RecordLogFile"/>
    </logger>
    <!--【如果是想实现功能的分类处理,比如 错误的error一类 记录的record一类;多个功能配置只需要再罗列appender和对应的logger节点即可】如之 罗列的logger节点-->
    
  </log4net>
</configuration>
 

=========》ok 

 
global页面访问(全局)异常处理 
新建项---全局异常信息类---
Global.asax.cs 
只能出现一个
只能出现在根目录下
只能是默认的Global名字 

里面有很多事件,程序第一次运行执行的事件,session开始时执行的事件,页面访问异常执行的事件。。。
其中  protected void Application_Error(object sender, EventArgs e)是异常触发的事件

可以这样处理获取全局异常
 
   // 在出现未处理的错误时运行的代码 
            Exception ex = Server.GetLastError().GetBaseException();
            StringBuilder str = new StringBuilder();
            str.Append("\r\n" + DateTime.Now.ToString("yyyy.MM.dd HH:mm:ss"));
            str.Append("\r\n.客户信息:");
            string ip = "";
            if (Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR") != null)
            {
                ip = Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR").ToString().Trim();
            }
            else
            {
                ip = Request.ServerVariables.Get("Remote_Addr").ToString().Trim();
            }
            str.Append("\r\n\tIp:" + ip);
            str.Append("\r\n\t浏览器:" + Request.Browser.Browser.ToString());
            str.Append("\r\n\t浏览器版本:" + Request.Browser.MajorVersion.ToString());
            str.Append("\r\n\t操作系统:" + Request.Browser.Platform.ToString());
            str.Append("\r\n.错误信息:");
            str.Append("\r\n\t页面:" + Request.Url.ToString());
            str.Append("\r\n\t错误信息:" + ex.Message);
            str.Append("\r\n\t错误源:" + ex.Source);
            str.Append("\r\n\t异常方法:" + ex.TargetSite);
            str.Append("\r\n\t堆栈信息:" + ex.StackTrace);
            str.Append("\r\n--------------------------------");
 
            Log.WriteError(ip + str.ToString());
            Response.Redirect("error.html");//跳转到指定的页面;1友好2信息安全
注:在调试的时候,可能全局异常不起作用,还是报异常,把之部署在iis上就好了 

如 上面的页面 

  Response.Write(1111);前面写上   Int a2 = 0; int   c2 = 9/a2;  访问这个aspx时就会跳转到error.html 并会走application_error记录下日志





========

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quartz;
using Quartz.Impl;
using Quartz.Xml;
using Quartz.Simpl;
using log4net;
using System.IO;
 
namespace Log42Quartz
{
    class Program
    {
        static void Main(string[] args)
        {
            /*
            //纯代码版本
            //==========================================================
            ISchedulerFactory schedFact = new StdSchedulerFactory();
            IScheduler sched = schedFact.GetScheduler();
            sched.Start();
            IJobDetail job = JobBuilder.Create<MyJob1>()
               // .WithIdentity("myJob", "group1")
                                     .Build();
            //DateTimeOffset startTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddSeconds(1), 2);
            //DateTimeOffset endTime = DateBuilder.NextGivenSecondDate(DateTime.Now.AddHours(2), 3);
 
            ITrigger trigger = TriggerBuilder.Create()
                //.StartAt(startTime).EndAt(endTime) 
                                         .StartNow()
                .WithIdentity("myTriger", "group1")
                //.WithSimpleSchedule(x => x.WithIntervalInSeconds(10)
                //.RepeatForever())//适合 【每隔】 多少时间
                                         .WithCronSchedule("/3 * * * * ?")//适合 【具体时间】 如 2015年9月每周3的12点;也可以/设置每隔多长时间
                                         .Build();
            //异常  Support for specifying both a day-of-week AND a day-of-month parameter is not implemented.
            //当日和星期都是 * 和 都是 ?时,会报此错
            sched.ScheduleJob(job, trigger);
         
           
            //【多个任务继续添加,IJobDetail和ITrigger即可~】
 
 
            IJobDetail job2 = JobBuilder.Create<MyJob2>().Build();
            ITrigger trigger2 = TriggerBuilder.Create().StartNow().WithCronSchedule("/3 * * * * ?").Build();
            sched.ScheduleJob(job2, trigger2);
            //==========================================================
             * */
 
 
            //配置文件版本==================================================================
            XMLSchedulingDataProcessor processor = new XMLSchedulingDataProcessor(new SimpleTypeLoadHelper());
            ISchedulerFactory sf = new StdSchedulerFactory();
            IScheduler scheduler = sf.GetScheduler();
            string path = System.AppDomain.CurrentDomain.BaseDirectory;
 
 
            processor.ProcessFileAndScheduleJobs(path + "\\quar.xml", scheduler);
 
            Log4Help.WriteRecord("开始执行");
            scheduler.Start();
 
 
 
 
 
        }
    }
 
 
    /// <summary>
    /// 模拟任务1
    /// </summary>
    public class MyJob1 : IJob
    {
        static int count = 0;
        public void Execute(IJobExecutionContext context)
        {
            count++;
            Console.WriteLine("任务1执行--" + count);
        }
    }
 
 
    /// <summary>
    /// 模拟任务2
    /// </summary>
    public class MyJob2 : IJob
    {
        static int count = 0;
        public void Execute(IJobExecutionContext context)
        {
            count++;
            Console.WriteLine("任务2执行--" + count);
        }
    }
 
    public class Log4Help
    {
        private static ILog ErrorLog;//错误日志
        private static ILog RecordLog;//记录日志
        static Log4Help()//静态构造函数的好处是只在使用它的程序中,在第一次new的时候在这里初始化信息;不然每次new就需要初始化一次
        {
            string configFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config");//在需要使用log4net功能的项目中,根目录下配置log4net.config{新建项配置文件},引用这个类;就能够实现日志功能
            if (!File.Exists(configFile))
            {
                throw new System.Exception("log4net Config File Not Found");
            }
            log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(configFile));
            ErrorLog = log4net.LogManager.GetLogger("ErrorLog");
            RecordLog = log4net.LogManager.GetLogger("RecordLog");
        }//
 
        public static void WriteError(string error)
        {
            if (ErrorLog.IsErrorEnabled)
            {
                ErrorLog.Error(error);
            }
        }
        public static void WriteRecord(string record)
        {
            if (RecordLog.IsInfoEnabled)
            {
                RecordLog.Info(record);
            }
        }
        //其他功能...
 
    }
}
 


配置文件
<?xml version="1.0" encoding="utf-8" ?>
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0">
 
<processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives>
 
<schedule>
 
<job>
<name>MyJob1</name>
<group>sampleGroup</group>
<description>Sample job for Quartz Server</description>
<job-type>Log42Quartz.MyJob1,Log42Quartz</job-type>
 
<!--MyTest.sampleJob    [width namespace classname] ,-->  
<durable>true</durable>
<recover>false</recover>
</job>
<job>
<name>MyJob2</name>
<group>sampleGroup</group>
<description>Sample job for Quartz Server</description>
<job-type>Log42Quartz.MyJob2,Log42Quartz</job-type>
 
<!--MyTest.sampleJob    [width namespace classname] ,  -->
<durable>true</durable>
<recover>false</recover>
</job>
 
<trigger>
<!--<simple>
<name>sampleSimpleTrigger</name>
<group>sampleSimpleGroup</group>
<description>Simple trigger to simply fire sample job</description>
<job-name>sampleJob</job-name>
<job-group>sampleGroup</job-group>
<misfire-instruction>SmartPolicy</misfire-instruction>
<repeat-count>-1</repeat-count>
<repeat-interval>1000</repeat-interval>
<cron-expression>2 * * * * ?</cron-expression>
 
</simple>-->
 
 
<cron>
<name>sampleSimpleTrigger</name>
<group>sampleSimpleGroup</group>
<description>Simple trigger to simply fire sample job</description>
<job-name>MyJob1</job-name>
<job-group>sampleGroup</job-group>
<misfire-instruction>SmartPolicy</misfire-instruction>
<cron-expression>0/2 * * * * ?</cron-expression>
</cron>
 
</trigger>
 
 
<!--more-->
 
<trigger>
<cron>
<name>sampleSimpleTrigger2</name>
<!--多个任务时,触发器名字不能重复-->
<group>sampleSimpleGroup</group>
<!--可以重复-->
<description>Simple trigger to simply fire sample job</description>
<!--可填写可不填-->
<job-name>MyJob2</job-name>
<!--和要执行的任务的name保持一致-->
<job-group>sampleGroup</job-group>
<!--可以重复-->
<misfire-instruction>SmartPolicy</misfire-instruction>
<cron-expression>0/3 * * * * ?</cron-expression>
</cron>
</trigger>
 
 
</schedule>
 
</job-scheduling-data>
 

 

玩转Log4Net