Log4net应用
今天主要说的是数据库保存日志,采用sqlite,c#.net的网站应用,实现了自定义信息的扩展,满足和兼容了之前的日志功能,采用数据库存储日志的目的,主要是考虑到日后查询的方便.
最近计划改进项目的日志处理方式,所以选择了开源的Log4net作为首选,使用中大部分功能都从网上找到了教程和案例,唯独一个问题,纠缠了我2个小时,郁闷之极,但最后焕然大悟,解决了,就是log4net保存sqlite数据库文件的权限问题,大家需要注意,log4net保存数据库日志时,受web站权限限制,无法保存日志记录,所以DB文件不要放在网站结构的目录里,可以使用绝对路径,放在网站根目录之上的目录或其他盘中.
下面是一些应用中使用的代码及说明:
我的项目是一个网站项目,所以在设置log4net配置文件的时候,尽量做到灵活一点:将log4net配置文件的文件路径设置到web.config中:
<configuration>
<appSettings>
<add key ="log4net_TG" value="TG\log4net_sqlite.config"/>
</appSettings>
</configuration>
然后在Global.asax中配置log4net:
string pa = System.Configuration.ConfigurationManager.AppSettings["log4net_setfile"]; // Server.MapPath("~") + @"\log4net_sqlite.config";
pa = System.Web.HttpContext.Current.Server.MapPath(pa);
log4net.Config.XmlConfigurator.Configure(new System.IO.FileInfo(pa));
下面贴出log4net_sqlite.config的配置内容:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="log4net" type="log4net.Config.IgnoreSectionHandler,log4net" /> </configSections> <log4net> <appender name="ADONetAppender" type="log4net.Appender.ADONetAppender,log4net"> <!--BufferSize为缓冲区大小--> <bufferSize value="1" /> <!--引用--> <connectionType value="System.Data.SQLite.SQLiteConnection, System.Data.SQLite,Version=1.0.65.0, Culture=neutral, PublicKeyToken=db937bc2d44ff139" /> <!--连接字符串--> <connectionString value="data source=F:\\log_tnt.db3" /> <commandText value="insert into [log_tnt] ([UserName],[DT],[LogLevel],[Logger],[Message],[UIP],[Exception]) Values(@UserName,@Date,@Level,@Logger,@Message,@Uip,@Exception);" /> <commandType value="Text"/> <!--用户名--> <parameter> <parameterName value="@UserName" /> <dbType value="String" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%property{UserName}" /> </layout> </parameter> <!--记录时间--> <parameter> <parameterName value="@Date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <!--日志等级--> <parameter> <parameterName value="@Level" /> <dbType value="String" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <!--消息--> <parameter> <parameterName value="@Message" /> <dbType value="String" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <!--Logger--> <parameter> <parameterName value="@Logger" /> <dbType value="String" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%Logger" /> </layout> </parameter> <!--用户ip--> <parameter> <parameterName value="@UIP" /> <dbType value="String" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%property{Uip}" /> </layout> </parameter> <!--错误--> <parameter> <parameterName value="@Exception" /> <dbType value="String" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%exception" /> </layout> </parameter> </appender> <logger name="LogToSqlite"> <level value="ALL"/> <appender-ref ref="ADONetAppender"/> </logger> <logger name="LogToFile"> <level value="ALL"/> <appender-ref ref="LogAllToFile"/> </logger> </log4net> </configuration>
省去了保存的txt文本文件的设置,请参考其他出处;当然,还有一些属性没有弄明白意思,日后有时间再做一些研究
log4net的调用更简单,如果做自定义字段扩展,就多几行代码处理下就可以了:
Log.LogEx.SetCustomInfo("u1","loca","ok1"); //添加扩展的自定义信息
log4net.ILog log = log4net.LogManager.GetLogger("LogToSqlite"); //创建Log
log.Info("新消息"); //输出日志数据
其中,SetCustomInfo方法的代码是这样的实现自定义信息的:
public static void SetCustomInfo(string _username,string _location,string _remarke) { log4net.ThreadContext.Properties["UserName"] = _username; log4net.ThreadContext.Properties["Uip"] = MaComm_web.GetClientIP(); log4net.ThreadContext.Properties["Location"] = _location; log4net.ThreadContext.Properties["Remark"] = _remarke; }
正因为这里的代码设置了新的信息,所以在log4net_sqlite.config里的参数数据,才可以通过%property{UserName}来获取。还有其他的方法也可以实现自定义信息,网上有相关资料,这里我就不提了。
最后说明下,缓存的数量根据每个项目单个日志的数据量和每小时保存次数来设定50-200之间比较合适,避免频繁操作数据库,占用CPU与磁盘资源
好了,下班,其他资料以后再补充了。