当前位置: 移动技术网 > IT编程>开发语言>.net > WebForm应用log4net记录错误日志——使用线程列队写入

WebForm应用log4net记录错误日志——使用线程列队写入

2018年08月29日  | 移动技术网IT编程  | 我要评论

龙腾小说网亚洲最大的精品小说阅读网,g买卖官网,玩三公秘诀

我的项目结构如下图:

日志帮助类库需要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; }

    }
}
view code

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
) 
view code
<?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>
view code

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();
        }
    }
}
view code

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);
                }
view code

到此,log4net日志配置完成。

相关程序源码可以点击此处下载:链接: https://pan.baidu.com/s/1bu29ba9zxyas-oamdasi-a 密码: upw2

另外附上自己整理的.net core webapi 应用log4net,大家可以看下源码:链接: https://pan.baidu.com/s/14woii1je0a02blm7_zlasg 密码: gd9b

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网