(新手学习中,语言组织能力不强,还望大家见谅!)
在工作或学习中,调试软件。尤其是当我们的软件交给客户使用的时候,遇到报错信息,找起来很麻烦,我们可以在软件中,加入log日志,每次报错都会写在log文件中。这样我们就可以准确定位,并且能够正确看到软件抛出来的错误。
废话不多说了,语言组织能力差。(坚持就是胜利哦也)
log4net是一个功能著名的开源日志记录组件。利用log4net可以方便地将日志信息记录到文件、控制台、Windows事件日志和数据库(包括MS SQL Server, Access, Oracle9i,Oracle8i,DB2,SQLite)中。并且我们还可以记载控制要记载的日志级别,可以记载的日志类别包括:FATAL(致命错误)、ERROR(一般错误)、WARN(警告)、INFO(一般信息)、DEBUG(调试信息)。要想获取最新版本的log4net组件库,可以到官方网站http://logging.apache.org/log4net/下载。
log4net是一个开源项目dll,下载下来,只要在我们的工程中引用dll,引用dll大家应该都会。dll使用的主要难点在于config文件的配置。dll是通过读取配置文件信息,记录日志的。通过配置文件,可以知道你是要把日志文件写在文件中还是数据库中等等的一系列操作。
接着我们配置相关的配置文件(WinForm对应的是*.exe.config,WebForm对应的是*.config),本实例中是控制台应用程序,配置如下(附各配置的说明):
下面主要包括了常用的几种常用的日志输出方式:输出到文件,输出到控制台命令行,输出到windows事件中,输出到数据库。
我工作一般喜欢把错误日志输出到文件中,比较方便搬移,清空等。
1 <?xml version="1.0" encoding="utf-8" ?> 2 <configuration> 3 <configSections> 4 <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> 5 </configSections> 6 <appSettings> 7 </appSettings> 8 <log4net> 9 <!--定义输出到文件中--> 10 <appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 11 <!--定义文件存放位置--> 12 <file value="data\Log.txt" /> 13 <appendToFile value="true" /> 14 <rollingStyle value="Date" /> 15 <datePattern value="yyyyMMdd-HH:mm:ss" /> 16 <layout type="log4net.Layout.PatternLayout"> 17 <!--每条日志末尾的文字说明--> 18 <footer value="by ITBoy" /> 19 <!--输出格式--> 20 <!--样例:2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info--> 21 <conversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" /> 22 </layout> 23 </appender> 24 <!--定义输出到控制台命令行中--> 25 <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> 26 <layout type="log4net.Layout.PatternLayout"> 27 <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> 28 </layout> 29 </appender> 30 <!--定义输出到windows事件中--> 31 <appender name="EventLogAppender" type="log4net.Appender.EventLogAppender"> 32 <layout type="log4net.Layout.PatternLayout"> 33 <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" /> 34 </layout> 35 </appender> 36 <!--定义输出到数据库中,这里举例输出到Access数据库中,数据库为C盘的log.mdb--> 37 <appender name="AdoNetAppender_Access" type="log4net.Appender.AdoNetAppender"> 38 <connectionString value="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:log.mdb" /> 39 <commandText value="INSERT INTO LogDetails ([LogDate],[Thread],[Level],[Logger],[Message]) VALUES (@logDate, @thread, @logLevel, @logger,@message)" /> 40 <!--定义各个参数--> 41 <parameter> 42 <parameterName value="@logDate" /> 43 <dbType value="String" /> 44 <size value="240" /> 45 <layout type="log4net.Layout.PatternLayout"> 46 <conversionPattern value="%date" /> 47 </layout> 48 </parameter> 49 <parameter> 50 <parameterName value="@thread" /> 51 <dbType value="String" /> 52 <size value="240" /> 53 <layout type="log4net.Layout.PatternLayout"> 54 <conversionPattern value="%thread" /> 55 </layout> 56 </parameter> 57 <parameter> 58 <parameterName value="@logLevel" /> 59 <dbType value="String" /> 60 <size value="240" /> 61 <layout type="log4net.Layout.PatternLayout"> 62 <conversionPattern value="%level" /> 63 </layout> 64 </parameter> 65 <parameter> 66 <parameterName value="@logger" /> 67 <dbType value="String" /> 68 <size value="240" /> 69 <layout type="log4net.Layout.PatternLayout"> 70 <conversionPattern value="%logger" /> 71 </layout> 72 </parameter> 73 <parameter> 74 <parameterName value="@message" /> 75 <dbType value="String" /> 76 <size value="240" /> 77 <layout type="log4net.Layout.PatternLayout"> 78 <conversionPattern value="%message" /> 79 </layout> 80 </parameter> 81 </appender> 82 <!--定义日志的输出媒介,下面定义日志以四种方式输出。也可以下面的按照一种类型或其他类型输出。--> 83 <root> 84 <!--文件形式记录日志--> 85 <appender-ref ref="LogFileAppender" /> 86 <!--控制台控制显示日志--> 87 <appender-ref ref="ConsoleAppender" /> 88 <!--Windows事件日志--> 89 <appender-ref ref="EventLogAppender" /> 90 <!-- 如果不启用相应的日志记录,可以通过这种方式注释掉 91 <appender-ref ref="AdoNetAppender_Access" /> 92 --> 93 </root> 94 95 </log4net> 96 </configuration>
下面我们来分析一下上面的配置文件:
在config文件中的配置
要使用log4net,首先要在config文件的<configSections>节点中增加配置(如果没有这个节点请手动增加),如下:
1 <configSections> 2 <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> 3 </configSections>
除此之外,还要在顶级节点<configuration>下增加<log4net>子节点。在<log4net>节点下就可以增加<appender>子节点,每个<appender>子节点代表一种记录日志的方式。配置了之后,还要启用才会真正的起作用。
比如上面的配置文件:
1 <!--定义输出到文件中--> 2 <appender name="LogFileAppender" type="log4net.Appender.FileAppender"> 3 <!--定义文件存放位置--> 4 <file value="data\Log.txt" /> 5 <appendToFile value="true" /> 6 <rollingStyle value="Date" /> 7 <datePattern value="yyyyMMdd-HH:mm:ss" /> 8 <layout type="log4net.Layout.PatternLayout"> 9 <!--每条日志末尾的文字说明--> 10 <footer value="by ITBoy" /> 11 <!--输出格式--> 12 <!--样例:2008-03-26 13:42:32,111 [10] INFO Log4NetDemo.MainClass [(null)] - info--> 13 <conversionPattern value="记录时间:%date 线程ID:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{NDC}] - 错误描述:%message%newline" /> 14 </layout> 15 </appender>
这个appender中间就表示定义了一种输出日志的方式:输出的log.txt文件中。
具体说来有如下Appender:
AdoNetAppender:利用ADO.NET记录到数据库的日志。
AnsiColorTerminalAppender:在ANSI 窗口终端写下高亮度的日志事件。
AspNetTraceAppender:能用asp.net中Trace的方式查看记录的日志。
BufferingForwardingAppender:在输出到子Appenders之前先缓存日志事件。
ConsoleAppender:将日志输出到控制台。
EventLogAppender:将日志写到Windows Event Log.
FileAppender:将日志写到文件中。
LocalSyslogAppender:将日志写到local syslog service (仅用于UNIX环境下).
MemoryAppender:将日志存到内存缓冲区。
NetSendAppender:将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。
RemoteSyslogAppender:通过UDP网络协议将日志写到Remote syslog service。
RemotingAppender:通过.NET Remoting将日志写到远程接收端。
RollingFileAppender:将日志以回滚文件的形式写到文件中。
SmtpAppender:将日志写到邮件中。
TraceAppender:将日志写到.NET trace 系统。
UdpAppender:将日志connectionless UDP datagrams的形式送到远程宿主或以UdpClient的形式广播。
关于使用log4net中可能会使用到的一些参数
%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
%n(new line):换行
%d(datetime):输出当前语句运行的时刻
%r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
%t(thread id):当前语句所在的线程ID
%p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
%c(class):当前日志对象的名称,例如:
%f(file):输出语句所在的文件名。
%l(line):输出语句所在的行号。
%数字:表示该项的最小长度,如果不够,则用空格填充,如“%-5level”表示level的最小宽度是5个字符,如果实际长度不够5个字符则以空格填充。
下面以一个实际的例子来说明问题,比如在配置中有“%date [%thread] (%file:%line) %-5level %logger [%property{NDC}] - %message%newline”,那么实际的日志中会是如下格式:
“记录时间:2010-11-17 16:16:36,561 线程ID:[9] 日志级别:文件:所在行ERROR 出错类:Log4NetDemo.Program property:[(null)] - 错误描述:error
System.Exception: 在这里发生了一个异常,Error Number:2036084948”
关于对数据库的支持
前面已经说过,log4net是支持包括MS SQL Server, Access, Oracle9i,Oracle8i,DB2,SQLite在内的数据库的,如果是文件型数据库(如Access或SQLite)的话就需要指定数据库文件的位置(在Web中最好指定在有读写权限的文件夹下,并且实现创建好表),如果是网络数据库就需要指定正确的数据库连接字符串。
比如要记录到Oracle数据库中,在配置文件中可以增加一个< appender>节点,配置如下:
1 <appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNetAppender"> 2 <connectionType value="System.Data.OracleClient.OracleConnection, System.Data.OracleClient, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> 3 <connectionString value="data source=[mydatabase];User ID=[user];Password=[password]" /> 4 <commandText value="INSERT INTO Log (Datetime,Thread,Log_Level,Logger,Message) VALUES (:log_date, :thread, :log_level, :logger, :message)" /> 5 <bufferSize value="128" /> 6 <parameter> 7 <parameterName value=":log_date" /> 8 <dbType value="DateTime" /> 9 <layout type="log4net.Layout.RawTimeStampLayout" /> 10 </parameter> 11 <parameter> 12 <parameterName value=":thread" /> 13 <dbType value="String" /> 14 <size value="255" /> 15 <layout type="log4net.Layout.PatternLayout"> 16 <conversionPattern value="%thread" /> 17 </layout> 18 </parameter> 19 <parameter> 20 <parameterName value=":log_level" /> 21 <dbType value="String" /> 22 <size value="50" /> 23 <layout type="log4net.Layout.PatternLayout"> 24 <conversionPattern value="%level" /> 25 </layout> 26 </parameter> 27 <parameter> 28 <parameterName value=":logger" /> 29 <dbType value="String" /> 30 <size value="255" /> 31 <layout type="log4net.Layout.PatternLayout"> 32 <conversionPattern value="%logger" /> 33 </layout> 34 </parameter> 35 <parameter> 36 <parameterName value=":message" /> 37 <dbType value="String" /> 38 <size value="4000" /> 39 <layout type="log4net.Layout.PatternLayout"> 40 <conversionPattern value="%message" /> 41 </layout> 42 </parameter> 43 </appender>
SQLite数据库:
1 <appender name="AdoNetAppender_SQLite" type="log4net.Appender.AdoNetAppender"> 2 <bufferSize value="100" /> 3 <connectionType value="System.Data.SQLite.SQLiteConnection, System.Data.SQLite, Version=1.0.66.0, Culture=neutral" /> 4 <!--SQLite连接字符串--> 5 <connectionString value="Data Source=c://log4net.db;Version=3;" /> 6 <commandText value="INSERT INTO Log (Date, Level, Logger,Source, Message) VALUES (@Date, @Level, @Logger, @Source, @Message)" /> 7 <parameter> 8 <parameterName value="@Date" /> 9 <dbType value="DateTime" /> 10 <layout type="log4net.Layout.RawTimeStampLayout" /> 11 </parameter> 12 <parameter> 13 <parameterName value="@Level" /> 14 <dbType value="String" /> 15 <layout type="log4net.Layout.PatternLayout"> 16 <conversionPattern value="%level" /> 17 </layout> 18 </parameter> 19 <parameter> 20 <parameterName value="@Logger" /> 21 <dbType value="String" /> 22 <layout type="log4net.Layout.PatternLayout"> 23 <conversionPattern value="%logger" /> 24 </layout> 25 </parameter> 26 <parameter> 27 <parameterName value="@Source" /> 28 <dbType value="String" /> 29 <layout type="log4net.Layout.PatternLayout"> 30 <conversionPattern value="%file:%line" /> 31 </layout> 32 </parameter> 33 <parameter> 34 <parameterName value="@Message" /> 35 <dbType value="String" /> 36 <layout type="log4net.Layout.PatternLayout"> 37 <conversionPattern value="%message" /> 38 </layout> 39 </parameter> 40 </appender>
从上面的配置中可以看出插入数据的SQL语句及参数信息,下面的<parameter>节点就是指定插入的数据,比如我们指定SQL语句中的"@Source"参数来源于log4net中的"%file:%line"参数,也就是这两个参数用“:”用连接起来。
控制日志文件大小的问题
对于一个长时间使用并且有大量业务日志的系统来说,如果使用FileAppender将日志一直记录到一个文件中会引起性能低下的问题,我曾见过有个系统的日志文件达到了800多M,最后系统无法及时响应了,在这种情况下可考虑使用RollingFileAppender循环记录日志,一种是指定文件的最大长度,如果超过了就重新生成一个文件,如下面的配置:
1 <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender"> 2 <file value="RollingFileAppender_log.txt" /> 3 <appendToFile value="true" /> 4 <rollingStyle value="Size" /> 5 <maxSizeRollBackups value="10" /> 6 <maximumFileSize value="100KB" /> 7 <staticLogFileName value="true" /> 8 <layout type="log4net.Layout.PatternLayout"> 9 <conversionPattern value="%date [%thread] (%file:%line) %-5level %logger [%property{NDC}] - %message%newline" /> 10 </layout> 11 </appender>
这样一来,每天的日志都写入到一个文件中,当天的日志文件名为“RollingLogFileAppender_DateFormat_log.txt”,非当天的日志都会带上当天的日期,如“RollingLogFileAppender_DateFormat_log.txt20101117”表示2010年11月17日的日志,这样就可以很方便地区分每天的日志了,将来查找起来也相当方便。
如上所说,配置文件配置好,可以配置很多种,配置完要启用后,才能真正看到效果。你想用哪一种,就启用哪一种记录方式。
在配置中启用和关闭日志
在config文件中可以很方便地关闭和启用日志,就是在<root>进行配置,如下就是一个例子:
1 <root> 2 <!--文件形式记录日志--> 3 <appender-ref ref="LogFileAppender" /> 4 <!--控制台控制显示日志--> 5 <appender-ref ref="ConsoleAppender" /> 6 <!--Windows事件日志--> 7 <!--<appender-ref ref="EventLogAppender" />--> 8 <!--SQLite事件日志--> 9 <appender-ref ref="AdoNetAppender_SQLite" /> 10 <!--RollingFileAppender事件日志--> 11 <appender-ref ref="RollingFileAppender" /> 12 <!--RollingFileAppender事件日志,每天一个日志--> 13 <appender-ref ref="RollingLogFileAppender_DateFormat" /> 14 <!-- 如果不启用相应的日志记录,可以通过这种方式注释掉 15 <appender-ref ref="AdoNetAppender_Access" /> 16 --> 17 </root>
在上面的例子中可以看出,如果想增加日志输出目的地,增加<appender-ref>节点就是了,注意后面的ref是在config中配置的appender name,如果想要取消,删除或者注释掉这行就可以了。
第一次写,组织能力不太好,借鉴了专家周公-周金桥的博客:
log4net使用详解:http://blog.csdn.net/zhoufoxcn/article/details/2220533
Log4Net使用详解(续):http://blog.csdn.net/zhoufoxcn/article/details/6029021