使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)

前端之家收集整理的这篇文章主要介绍了使用log4net完成程序异常日志记录(使用SQLite数据库记录和普通文本记录)前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

在前端时间开发的时候由于需要将异常保存到数据库中,所以就到网上搜了下专门的日志记录工具,一搜果然很多,比如:log4net,NLog,EntLib Logging等等,但是还是log4net名气最大,所以就下载下来试用了一番,果然很方便,其涵盖了所有常用的日志记录方式具体的可以看下表:

AdoNetAppender 将日志记录到数据库中。可以采用sql和存储过程两种方式。

AnsiColorTerminalAppender 将日志高亮输出到ANSI终端。

AspNetTraceAppender 能用asp.net中Trace的方式查看记录的日志。

BufferingForwardingAppender输出到子Appenders之前先缓存日志事件。

ConsoleAppender 将日志输出到应用程序控制台。

EventLogAppender 将日志写到Windows Event Log。

FileAppender 将日志输出文件

ForwardingAppender 发送日志事件到子Appenders。

LocalSyslogAppender 将日志写到local syslog service (仅用于UNIX环境下)。

MemoryAppender 将日志存到内存缓冲区。

NetSendAppender 将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示

OutputDebugStringAppender 将日志输出到Debuger,如果程序没有Debuger,就输出到系统Debuger。如果系统Debuger也不可用,将忽略消息。

RemoteSyslogAppender 通过UDP网络协议将日志写到Remote syslog service。

RemotingAppender 通过.NET Remoting将日志写到远程接收端。

RollingFileAppender 将日志以回滚文件的形式写到文件中。

SmtpAppender 将日志写到邮件中。

SmtpPickupDirAppender 将消息以文件的方式放入一个目录中,像IIS SMTP agent这样的SMTP代理就可以阅读或发送它们。

TelnetAppender 客户端通过Telnet来接受日志事件。

TraceAppender 将日志写到.NET trace 系统。

UdpAppender 将日志以无连接UDP数据报的形式送到远程宿主或用UdpClient的形式广播。

怎么样?看了是不是很心动?如果想学习log4net的话可以看下园子里这位兄弟写的文章:如何使用Log4net创建日志及简单扩展,里面详细介绍了如何使用log4net记录日志,本文呢仅仅就对异常出现后如何记录下来进行讨论,同时也是做个记录方便日后写微软企业库 学习之路有所引用。

在日常的项目开发过程中总会碰到各种各样的异常,我们总是希望异常能第1时间捕获,同时能清楚的知道异常信息、异常发生的时间、发生异常的位置,这样我们好立刻追踪到其发生点来具体解决问题,log4net就很好的帮我们解决了这个问题

现在我们就开始对如何进行异常日志的记录做个分析:

首先是具体的config配置文件,主要分为2个日志记录器,一个是LogTosqlite(记录到sqlite数据库),另外一个是LogToFile(记录到相应的文件),如果要更换到其他数据库也是一样的,值需要更改connectionTypeconnectionString就可以了:

001 <?xml version="1.0" encoding="utf-8" ?>
002 <configuration>
003 <configSections>
004 <section name="log4net" type="System.Configuration.IgnoreSectionHandler,log4net" />
005 </configSections>
006 <log4net>
007 <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender,log4net">
008 <!--BufferSize为缓冲区大小-->
009 <bufferSize value="100" />
010
011 <!--<param name="BufferSize" value="2" />-->
012 <!--引用-->
013 <connectionType value="System.Data.sqlite.sqliteConnection,System.Data.sqlite,Version=1.0.65.0,Culture=neutral,PublicKeyToken=db937bc2d44ff139" />
014 <!--连接字符串-->
015 <connectionString value="data source=F:\\项目开发\\log4netDemo\\WebApplication1\\bin\\log.db3" />
016 <!--插入语句-->
017 <commandText value="insert into [Log2] ([Author],[LogDate],[Log_Level],[Message],[Location],[Exception]) Values(@Author,@Date,@Level,@Message,@Location,@Exception);" />
018 <commandType value="Text"/>
019 <!--操作者,暂时没用到-->
020 <parameter>
021 <parameterName value="@Author" />
022 <dbType value="String" />
023 <layout type="log4net.Layout.PatternLayout">
024 <conversionPattern value="%property{Operator}" />
025 </layout>
026 </parameter>
027 <!--记录时间-->
028 <parameter>
029 <parameterName value="@Date" />
030 <dbType value="DateTime" />
031 <layout type="log4net.Layout.RawTimeStampLayout" />
032 </parameter>
033 <!--日志等级-->
034 <parameter>
035 <parameterName value="@Level" />
036 <dbType value="String" />
037 <layout type="log4net.Layout.PatternLayout">
038 <conversionPattern value="%level" />
039 </layout>
040 </parameter>
041 <!--异常消息-->
042 <parameter>
043 <parameterName value="@Message" />
044 <dbType value="String" />
045 <layout type="log4net.Layout.PatternLayout">
046 <conversionPattern value="%message" />
047 </layout>
048 </parameter>
049 <!--异常位置-->
050 <parameter>
051 <parameterName value="@Location" />
052 <dbType value="String" />
053 <layout type="log4net.Layout.PatternLayout">
054 <conversionPattern value="%location" />
055 </layout>
056 </parameter>
057 <!--错误-->
058 <parameter>
059 <parameterName value="@Exception" />
060 <dbType value="String" />
061 <layout type="log4net.Layout.PatternLayout">
062 <conversionPattern value="%exception" />
063 </layout>
064 </parameter>
065 </appender>
066 <appender name="LogAllToFile" type="log4net.Appender.RollingFileAppender,log4net">
067 <!--输出格式
068 每种转换符号都以%开始,后面跟着一个格式符号和换符号。
069 %-数字 :该项的最小长度,小于最小长度的用空格填充
070 %m(message):输出的日志消息
071 %n(new line):换行
072 %d(datetime):输出当前语句运行的时刻
073 %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
074 %t(thread id):当前语句所在的线程ID
075 %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
076 %c(class):当前日志对象的名称
077 %L(line ):输出语句所在的行号
078 %F(file name):输出语句所在的文件
079 %logger 日志名称
080 -->
081 <param name="File" value="log\"/>
082 <param name="AppendToFile" value="true"/>
083 <param name="MaxSizeRollBackups" value="100"/>
084 <param name="MaximumFileSize" value="1KB"/>
085 <param name="StaticLogFileName" value="false"/>
086 <param name="DatePattern" value="yyyyMMdd&quot;.log&quot;"/>
087 <param name="RollingStyle" value="Date"/>
088 <layout type="log4net.Layout.PatternLayout">
089 <param name="ConversionPattern" value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 记录类:%logger 操作者ID:%property{Operator} 操作类型:%property{ActionType}%n当前机器名:%property%n当前机器名及登录用户:%username %n记录位置:%location%n消息描述:%property{Message}%n异常:%exception%n消息:%message%newline%n%n" />
090 </layout>
091 </appender>
092 <logger name="LogTosqlite">
093 <level value="ERROR"/>
094 <appender-ref ref="ADONetAppender"/>
095 </logger>
096 <!--<logger name="LogToFile">
097 <level value="ALL"/>
098 <appender-ref ref="LogAllToFile"/>
099 </logger>-->
100 <!--所有logger的基础,root的设置在所有logger中都起作用。
101 当在root和logger中重复设定相同的appender时,你会发现同一日志信息将被记录两次。-->
102 <!--<root>
103 <level value="ERROR"/>
104 ALL,DEBUG,INFO,WARN,ERROR,FATAL,OFF
105 <appender-ref ref="LogAllToFile"/>
106 <appender-ref ref="ADONetAppender"/>
107 </root>-->
108 </log4net>
109 </configuration>

在普通的C/S系统下都会有个程序入口,我们可以在这个入口点做文章,在程序启动时添加2个事件来监听异常:

1 Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
2 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

这2个事件是当执行Application.Run方法的线程发生未捕获异常时,触发 Application.ThreadException和如果 handler 抛出异常,或者不在 UI 线程中发生异常,将触发
AppDomain.UnhandledException事件。

其入口点代码如下:

01 static class Program
02 {
03 /// <summary>
04 /// 应用程序的主入口点。
05 /// </summary>
06 [STAThread]
07 static void Main()
08 {
09 //若不在AssemblyInfo.cs配置[assembly: log4net.Config.XmlConfigurator(ConfigFile = "WindowsFormsApplication1.exe.config",Watch = true)]
10 //可使用一下代码来读取log4net配置文件
11 string assemblyFilePath = Assembly.GetExecutingAssembly().Location;
12 string assemblyDirPath = Path.GetDirectoryName(assemblyFilePath);
13 string configFilePath = assemblyDirPath + " \\log4net.xml";
14 log4net.Config.XmlConfigurator.ConfigureAndWatch(new FileInfo(configFilePath));
15
16 //异常
17 Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
18 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
19 Application.EnableVisualStyles();
20 Application.SetCompatibleTextRenderingDefault(false);
21 Application.Run(new Form1());
22 }
23
24 static void CurrentDomain_UnhandledException(object sender,UnhandledExceptionEventArgs e)
25 {
26 if (e.ExceptionObject is System.Exception)
27 {
28 HandleException((System.Exception)e.ExceptionObject);
29 }
30 }
31
32 static void Application_ThreadException(object sender,System.Threading.ThreadExceptionEventArgs e)
33 {
34 HandleException(e.Exception);
35 }
36
37 public static void HandleException(Exception ex)
38 {
39 log4net.ILog log = (log4net.ILog)log4net.LogManager.GetLogger("LogTosqlite");
40 log.Error(ex.Message,ex);
41 }
42 }

而在B/S程序下面我们则可以利用页面级别的Page_Error事件或者整个应用程序级别的Application_Error事件(本例子中采用Page_Error处理),同时我们还要做一步处理就是在Global.asax中的Application_Start添加log4net的配置读取,或者也可以在AssemblyInfo.cs添加和WinFrom一样的配置,不过如果仅限于WebForm,而Web网站就只能在Global中配置,所以这边我们就采用通用配置:

1 protected void Application_Start(object sender,EventArgs e)
2 {
3 log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(Server.MapPath("~") + @"\log4net.xml"));
4 }

为了方便每个页面进行异常捕获我们建立一个PageBase,让所有的页面都继承这个PageBase,这样只需在PageBase中写一个Page_Error就可以了,代码如下:

01 public class PageBase : System.Web.UI.Page
02 {
03 protected void Page_Error(object sender,EventArgs args)
04 {
05 //获取最新的异常信息
06 var ex = Server.GetLastError();
07 //记录异常信息
08 log4net.ILog log = (log4net.ILog)log4net.LogManager.GetLogger("LogTosqlite");
09 log.Error(ex.Message,ex);
10 //清空异常信息
11 Server.ClearError();
12 }
13 }

这样在页面中就可以进行异常捕获及记录了。

Log4net下载地址

猜你在找的Sqlite相关文章