玩转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 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="applicationLog.log" /> -->
<file type="log4net.Util.PatternString" value="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="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<!--【备份log文件的个数最多10个】-->
<maximumFileSize value="2MB" />
<!--【每个log文件最大是2M,如果超过2M将重新创建一个新的log文件,并将原来的log文件备份。】-->
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%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="E:\Codes\Log4NetDemo\Log4NetDemo\%date{yyyy}\%date{MM}\record_log%date{yyyy-MM-dd}.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="2MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="[%date] %thread -- %-5level -- %logger [%M] -- %message%newline" />
</layout>
</appender>
<!--【如果是想实现功能的分类处理,比如 错误的error一类 记录的record一类;多个功能配置只需要再罗列appender和对应的logger节点即可】-->
<!--【logger的name,在c#代码中getlogger(name)来获取配置的对象】-->
<logger name="ErrorLog">
<level value="1"/>
<!--【ref指向关联的appender的name】-->
<appender-ref ref="ErrorLogFile"/>
</logger>
<!--【如果是想实现功能的分类处理,比如 错误的error一类 记录的record一类;多个功能配置只需要再罗列appender和对应的logger节点即可】如之 罗列的logger节点-->
<logger name="RecordLog">
<level value="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)是异常触发的事件
可以这样处理获取全局异常
// 在出现未处理的错误时运行的代码
里面有很多事件,程序第一次运行执行的事件,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记录下日志
注:在调试的时候,可能全局异常不起作用,还是报异常,把之部署在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>