WebForm应用log4net记录错误日志——使用线程列队写入
程序员文章站
2022-05-13 23:36:01
我的项目结构如下图: 日志帮助类库需要log4net包:工具—NuGet包管理器—管理解决方案NuGet程序包 线程日志帮助类 FlashLogger.cs 代码 using System; using System.Collections.Concurrent; using System.Coll ......
我的项目结构如下图:
日志帮助类库需要log4net包:工具—nuget包管理器—管理解决方案nuget程序包
线程日志帮助类 flashlogger.cs 代码
using system; using system.collections.concurrent; using system.collections.generic; using system.io; using system.linq; using system.threading; using system.web; using log4net; using log4net.config; namespace flashlog { public sealed class flashlogger { /// <summary> /// 记录消息queue /// </summary> private readonly concurrentqueue<flashlogmessage> _que; /// <summary> /// 信号 /// </summary> private readonly manualresetevent _mre; /// <summary> /// 日志 /// </summary> private readonly ilog _log; /// <summary> /// 日志 /// </summary> private static flashlogger _flashlog = new flashlogger(); private flashlogger() { var configfile = new fileinfo(httpcontext.current.server.mappath("~/log4net.config")); if (!configfile.exists) { throw new exception("未配置log4net配置文件!"); } // 设置日志配置文件路径 xmlconfigurator.configure(configfile); _que = new concurrentqueue<flashlogmessage>(); _mre = new manualresetevent(false); _log = logmanager.getlogger(system.reflection.methodbase.getcurrentmethod().declaringtype); } /// <summary> /// 实现单例 /// </summary> /// <returns></returns> public static flashlogger instance() { return _flashlog; } /// <summary> /// 另一个线程记录日志,只在程序初始化时调用一次 /// </summary> public void register() { thread t = new thread(new threadstart(writelog)); t.isbackground = false; t.start(); } /// <summary> /// 从队列中写日志至磁盘 /// </summary> private void writelog() { while (true) { // 等待信号通知 _mre.waitone(); flashlogmessage msg; // 判断是否有内容需要如磁盘 从列队中获取内容,并删除列队中的内容 while (_que.count > 0 && _que.trydequeue(out msg)) { // 判断日志等级,然后写日志 switch (msg.level) { case flashloglevel.debug: _log.debug(msg.message, msg.exception); break; case flashloglevel.info: _log.info(msg.message, msg.exception); break; case flashloglevel.error: _log.error(msg.message, msg.exception); break; case flashloglevel.warn: _log.warn(msg.message, msg.exception); break; case flashloglevel.fatal: _log.fatal(msg.message, msg.exception); break; } } // 重新设置信号 _mre.reset(); thread.sleep(1); } } /// <summary> /// 写日志 /// </summary> /// <param name="message">日志文本</param> /// <param name="level">等级</param> /// <param name="ex">exception</param> public void enqueuemessage(string message, flashloglevel level, exception ex = null) { if ((level == flashloglevel.debug && _log.isdebugenabled) || (level == flashloglevel.error && _log.iserrorenabled) || (level == flashloglevel.fatal && _log.isfatalenabled) || (level == flashloglevel.info && _log.isinfoenabled) || (level == flashloglevel.warn && _log.iswarnenabled)) { _que.enqueue(new flashlogmessage { message = "[" + datetime.now.tostring("yyyy-mm-dd hh:mm:ss,fff") + "]\r\n" + message, level = level, exception = ex }); // 通知线程往磁盘中写日志 _mre.set(); } } public static void debug(string msg, exception ex = null) { instance().enqueuemessage(msg, flashloglevel.debug, ex); } public static void error(string msg, exception ex = null) { instance().enqueuemessage(msg, flashloglevel.error, ex); } public static void fatal(string msg, exception ex = null) { instance().enqueuemessage(msg, flashloglevel.fatal, ex); } public static void info(string msg, exception ex = null) { instance().enqueuemessage(msg, flashloglevel.info, ex); } public static void warn(string msg, exception ex = null) { instance().enqueuemessage(msg, flashloglevel.warn, ex); } } /// <summary> /// 日志等级 /// </summary> public enum flashloglevel { debug, info, error, warn, fatal } /// <summary> /// 日志内容 /// </summary> public class flashlogmessage { public string message { get; set; } public flashloglevel level { get; set; } public exception exception { get; set; } } }
webform项目创建:
1.需要引用线程日志类库 flashlog
2.添加log4net配置文件 log4net.config,实现了数据库及文件记录日志
create table errorlog ( dtdate datetime, sthread nvarchar(100), slevel nvarchar(100), slogger nvarchar(500), smessage nvarchar(500), sexception ntext )
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configsections> <section name="log4net" type="log4net.config.log4netconfigurationsectionhandler,log4net"/> </configsections> <log4net debug="false"> <!-- 将日志信息写入sql server数据库--> <appender name="adonetappender" type="log4net.appender.adonetappender"> <buffersize value="1" /> <connectiontype value="system.data.sqlclient.sqlconnection, system.data, version=1.0.5000.0, culture=neutral, publickeytoken=b77a5c561934e089" /> <connectionstring value="server=服务器;database=数据库;uid=用户名;pwd=密码;connect timeout=15;" /> <commandtext value="insert into errorlog ([dtdate],[sthread],[slevel],[slogger],[smessage],[sexception]) values (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parametername value="@log_date" /> <dbtype value="datetime" /> <layout type="log4net.layout.rawtimestamplayout" /> </parameter> <parameter> <parametername value="@thread" /> <dbtype value="string" /> <size value="100" /> <layout type="log4net.layout.patternlayout"> <conversionpattern value="%t" /> </layout> </parameter> <parameter> <parametername value="@log_level" /> <dbtype value="string" /> <size value="200" /> <layout type="log4net.layout.patternlayout"> <conversionpattern value="%p" /> </layout> </parameter> <parameter> <parametername value="@logger" /> <dbtype value="string" /> <size value="500" /> <layout type="log4net.layout.patternlayout"> <conversionpattern value="%logger" /> </layout> </parameter> <parameter> <parametername value="@message" /> <dbtype value="string" /> <size value="3000" /> <layout type="log4net.layout.patternlayout"> <conversionpattern value="%m" /> </layout> </parameter> <parameter> <parametername value="@exception" /> <dbtype value="string" /> <layout type="log4net.layout.exceptionlayout" /> </parameter> </appender> <!-- 将日志信息写入到项目日志文件 --> <appender name="logtofile" type="log4net.appender.rollingfileappender"> <encoding value="utf-8" /> <lockingmodel type="log4net.appender.fileappender+minimallock" /> <file value="logs\" /> <datepattern value="yyyy.mm.dd'.log'" /> <staticlogfilename value="false" /> <appendtofile value="true" /> <rollingstyle value="composite" /> <maxsizerollbackups value="10" /> <maximumfilesize value="50mb" /> <layout type="log4net.layout.patternlayout"> <conversionpattern value="%date 线程id:[%thread] 日志级别:%-5level 出错类:%logger property:[%property{ndc}] - 错误描述:%message %newline" /> </layout> </appender> <!--设置根目录,添加appenders并设置默认日志等级 --> <root> <level value="all" /> <appender-ref ref="adonetappender" /> <appender-ref ref="logtofile"/> </root> </log4net> </configuration>
3.需要添加全局应用程序类 global.asax
using system; using system.collections.generic; using system.linq; using system.web; using system.web.security; using system.web.sessionstate; namespace logweb { public class global : system.web.httpapplication { protected void application_start(object sender, eventargs e) { // 在应用程序启动时运行的代码 flashlog.flashlogger.instance().register(); } } }
4.实例应用:访问无效域名时记录错误日志
try { string checktonkenurl = "http://url.abcde.com"; webrequest wrequest = webrequest.create(checktonkenurl); wrequest.method = "get"; wrequest.contenttype = "text/html;charset=utf-8"; webresponse wresponse = wrequest.getresponse(); stream stream = wresponse.getresponsestream(); streamreader reader = new streamreader(stream, system.text.encoding.utf8); string str = reader.readtoend(); //url返回的值 } catch (exception ex) { flashlogger.error("error", ex); }
到此,log4net日志配置完成。
相关程序源码可以点击此处下载:链接: https://pan.baidu.com/s/1bu29ba9zxyas-oamdasi-a 密码: upw2
另外附上自己整理的.net core webapi 应用log4net,大家可以看下源码:链接: https://pan.baidu.com/s/14woii1je0a02blm7_zlasg 密码: gd9b