记一次Log4net 的过坑历程-单线程到多线程的跨越

这是本人初次在CSDN写文章,旨在记录自己平常在开发过程中遇到的问题,以及问题的解决过程,最终的解决办法,可以帮到各位有需要的当然更好,如有写得不好的地方,还请各位多多包涵,欢迎在下方评论处提出宝贵意见,谢谢大家。

言归正传。作为开发,日志组件是软件构成里面必不可少的一个模块,不管软件大小,日志都可以作为发现和解决问题的一个手段,很重要。在.Net 系里面log4Net是其中的一个不错的日志组件。
log4Net的优点有不少,例如配置简单灵活,轻松使用。
但是在使用过程中,我遇到了一些坑。
1.我将WebApi项目配置log4Net记录日志时,当请求数逐渐增加,会出现文件夹不断嵌套新的文件夹,然后在嵌套的文件夹下会产生新的日志文件的情况。
这种主要是由于请求太多,多个线程在争夺文件资源,然后读写日志文件的时候,文件被锁定,其他线程就会创建新的文件来存储日志,然后文件名或者文件夹名就会不断变长,Windows最终会判定这些文件不能删除。
解决办法,在配置文件中增加以下配置

<!--最小锁定模型以允许多个进程可以写入同一个文件-->
<param name="lockingModel"  type="log4net.Appender.FileAppender+MinimalLock" />

这当然是可以解决的,但是也会带来严重的后果。那就是你的应用程序变慢了。我当时的推测是这个配置让你实现了多个进程可以写入同一个日志文件,这样就不会不断产生新的文件夹了,但这个是排队等待的结果,在上一进程在写入日志文件的时候,其他刚好也需要执行这个写入日志的操作的话,就会需要等待,最终拖慢整个WebApi的响应速度(这是我当时的推测,后续并未验证,如有不对欢迎指出,谢谢)。

2.如何解决进程排队的问题。最终掏出了杀手锏–多线程 + 队列。
日志文件,作为软件一个重要但非必要组件,不能因为它而拖累整体应用程序的运行速度,那就通过开启多线程的方式来实现,但是多线程不能保证日志的写入顺序,可能会导致产生正确的日志数据,但是顺序是错的,所以需要加上队列,先进先出的原则,保证日志顺序准确。

微软全家桶里面有个System.Collections.Concurrent.ConcurrentQueue 的队列,用它就可以了,至此,log4net带来的问题已经解决,可以愉快的使用这个日志组件咯,甚至可以打包组合在其他项目中引用,简单复用,这才是高效的开发人该做的事情。
以下是一些主体代码和说明:

		//标识字段
		private volatile bool IsProcessing = false;
		//日志组件启动时就要开始执行,初始化这个队列
        private void StartThread()
        {
            messageQueue = new ConcurrentQueue<LoggerModel>();
            thread = new Thread(InternalWriteLog);
            thread.SetApartmentState(ApartmentState.STA);
            thread.IsBackground = true;
            thread.Start();
        }
		//当有日志写入的时候调用
        public void LogIn()
        {
            if (IsProcessing)
            {
                return;
            }
            else
            {
                _ = Task.Factory.StartNew(() =>
                {
                    WriteLog();
                });
            }
        }
		

因篇幅所致,这里并未展示所有的代码,如有需要的可以下方留言。

猜你喜欢

转载自blog.csdn.net/qq_15000459/article/details/107802619