欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析-創(chuàng)新互聯(lián)

小編給大家分享一下c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)建站長期為上1000+客戶提供的網(wǎng)站建設(shè)服務(wù),團隊從業(yè)經(jīng)驗10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為祁門企業(yè)提供專業(yè)的網(wǎng)站設(shè)計、做網(wǎng)站,祁門網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

最近在使用log4net,在使用之前我們必須知道文件流是如何操作的,否則就是盲人摸向。。。,在FileAppender.cs文件里面有LockingModelBase來控制流的鎖,默認有3個子類

ExclusiveLock:默認的,Hold an exclusive lock on the output file,Open the file once for writing and hold it open until CloseFile is called.  Maintains an exclusive lock on the file during this time.

MinimalLock:Acquires the file lock for each write,Opens the file once for each AcquireLock / ReleaseLock cycle,  thus holding the lock for the minimal amount of time.This method of locking is considerably slower than FileAppender.ExclusiveLock but allows  other processes to move/delete the log file whilst logging continues.

InterProcessLock:Provides cross-process file locking.使用Mutex來實現(xiàn)多進程

這里意思是MinimalLock比ExclusiveLock慢一點,因為它每次都會打開關(guān)閉文件流。

不過有2個類感覺比較重要PatternString.cs

c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析

和PatternLayout.cs

c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析

c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析

如果log文件在一個公共的目錄,建議大家log文件加上計算機名稱、應(yīng)用程序名稱、進程ID(如web 有多個工作者) 如:

<file type="log4net.Util.PatternString" value="\\192.168.0.1\logs\%env{COMPUTERNAME}\%appsetting{ApplicationName}\%processid\Log\" />

但是這里的log記錄默認都是采用同步方式的,但是我個人更趨向用異步多線程的思路來寫log,首先log的信息記錄在內(nèi)存ConcurrentQueue里面,然后在通過一個后臺線程把ConcurrentQueue里面的東西記錄到文件流里面。至于性能高出多少我想就不用多說了吧,寫內(nèi)存肯定比寫流快啊

具體實現(xiàn)code如下:

[assembly: log4net.Config.XmlConfigurator(Watch = true, ConfigFile = "log4net.config")]namespace ConsoleApp
{    using log4net;    using System;    using System.Collections.Concurrent;    using System.Threading;    using System.Threading.Tasks;    public sealed class QueueLogger
    {        /// <summary>
        /// 記錄消息Queue        /// </summary>
        private readonly ConcurrentQueue<QueueLogMessage> _que;        /// <summary>
        /// 信號        /// </summary>
        private readonly ManualResetEvent _mre;        /// <summary>
        /// 日志        /// </summary>
        private readonly ILog _log;        /// <summary>
        /// 日志        /// </summary>
        private static QueueLogger flashLog = new QueueLogger();        private QueueLogger()
        {            // 設(shè)置日志配置文件路徑            //XmlConfigurator.Configure(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log4net.config")));
            _que = new ConcurrentQueue<QueueLogMessage>();
            _mre = new ManualResetEvent(false);
            _log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            Task.Run(() => { WriteLog(); });
        }        /// <summary>
        /// 從隊列中寫日志至磁盤        /// </summary>
        private void WriteLog()
        {            while (true)
            {                // 等待信號通知                _mre.WaitOne();
                QueueLogMessage msg;                // 判斷是否有內(nèi)容需要如磁盤 從列隊中獲取內(nèi)容,并刪除列隊中的內(nèi)容
                while (_que.Count > 0 && _que.TryDequeue(out msg))
                {                    // 判斷日志等級,然后寫日志
                    switch (msg.Level)
                    {                        case QueueLogLevel.Debug:
                            _log.Debug(msg.Message, msg.Exception);                            break;                        case QueueLogLevel.Info:
                            _log.Info(msg.Message, msg.Exception);                            break;                        case QueueLogLevel.Error:
                            _log.Error(msg.Message, msg.Exception);                            break;                        case QueueLogLevel.Warn:
                            _log.Warn(msg.Message, msg.Exception);                            break;                        case QueueLogLevel.Fatal:
                            _log.Fatal(msg.Message, msg.Exception);                            break;
                    }
                }                // 重新設(shè)置信號                _mre.Reset();
            }
        }        /// <summary>
        /// 寫日志        /// </summary>
        /// <param name="message">日志文本</param>
        /// <param name="level">等級</param>
        /// <param name="ex">Exception</param>
        public void EnqueueMessage(string message, QueueLogLevel level, Exception ex = null)
        {            if ((level == QueueLogLevel.Debug && _log.IsDebugEnabled)             || (level == QueueLogLevel.Error && _log.IsErrorEnabled)             || (level == QueueLogLevel.Fatal && _log.IsFatalEnabled)             || (level == QueueLogLevel.Info && _log.IsInfoEnabled)             || (level == QueueLogLevel.Warn && _log.IsWarnEnabled))
            {
                _que.Enqueue(new QueueLogMessage
                {                    // Message = "[" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff") + "]\r\n" + message,
                    Message = message,
                    Level = level,
                    Exception = ex
                });                // 通知線程往磁盤中寫日志                _mre.Set();
            }
        }        public static void Debug(string msg, Exception ex = null)
        {
            flashLog.EnqueueMessage(msg, QueueLogLevel.Debug, ex);
        }        public static void Error(string msg, Exception ex = null)
        {
            flashLog.EnqueueMessage(msg, QueueLogLevel.Error, ex);
        }        public static void Fatal(string msg, Exception ex = null)
        {
            flashLog.EnqueueMessage(msg, QueueLogLevel.Fatal, ex);
        }        public static void Info(string msg, Exception ex = null)
        {
            flashLog.EnqueueMessage(msg, QueueLogLevel.Info, ex);
        }        public static void Warn(string msg, Exception ex = null)
        {
            flashLog.EnqueueMessage(msg, QueueLogLevel.Warn, ex);
        }
    }    /// <summary>
    /// 日志等級    /// </summary>
    public enum QueueLogLevel
    {
        Debug,
        Info,
        Error,
        Warn,
        Fatal
    }    /// <summary>
    /// 日志內(nèi)容    /// </summary>
    public class QueueLogMessage
    {        public string Message { get; set; }        public QueueLogLevel Level { get; set; }        public Exception Exception { get; set; }
    }
}

至于CSV格式有2中方法 實現(xiàn),一是自定義PatternLayout類:

namespace log4net
{    using Layout;    using System.IO;    using System.Text;    using Util;    using Core;    public class CSVPatternLayout : PatternLayout
    {        public override void ActivateOptions()
        {
            AddConverter("newfield", typeof(CSVNewFiledConverter));
            AddConverter("endrow", typeof(CSVEndRowConverter));            base.ActivateOptions();
        }        public override void Format(TextWriter writer, LoggingEvent loggingEvent)
        {            var csvWriter = new CSVTextWriter(writer);
            csvWriter.WriteQuote();            base.Format(csvWriter, loggingEvent);
        }
    }    public class CSVTextWriter : TextWriter
    {        private readonly TextWriter textWriter;        public CSVTextWriter(TextWriter txtWriter)
        {
            textWriter = txtWriter;
        }        public override void Write(char value)
        {            // base.Write(value);            textWriter.Write(value);            //if (value == '"')            //{            //}        }        public void WriteQuote()
        {
            textWriter.Write('"');
        }        public override Encoding Encoding
        {            get
            {                return textWriter.Encoding;
            }
        }
    }    public class CSVNewFiledConverter : PatternConverter
    {        protected override void Convert(TextWriter writer, object state)
        {            var csvWriter = writer as CSVTextWriter;
            csvWriter?.WriteQuote();
            writer.Write(",");
            csvWriter?.WriteQuote();
        }
    }    public class CSVEndRowConverter : PatternConverter
    {        protected override void Convert(TextWriter writer, object state)
        {            var csvWriter = writer as CSVTextWriter;
            csvWriter?.WriteQuote();
            writer.WriteLine();
        }
    }
}

配置文件中需要加上逗號

<layout type="log4net.CSVPatternLayout,ConsoleApp">
<header value="Time,Thread,Level,Logger,Message,Exception&#13;&#10;" />
<conversionPattern value="%date{yyyy-MM-dd HH:mm:ss}
%newfield
%thread%newfield%level%newfield%logger%newfield%message%newfield%exception
%endrow
" />
</layout>

這里&#13;&#10;是\r\n,%newfield是一個逗號,%endrow是逗號+換行

看到這里其實我們可以自己拼接CSV的內(nèi)容,也就是說只要有,\r\n就可以了

<layout type="log4net.Layout.PatternLayout">
<header value="Time,Message,Type
,&#13;&#10;
" />
<param name="ConversionPattern" value="
&quot;%date{yyyy-MM-dd HH:mm:ss}&quot;,&quot;%message%&quot;&#13;&#10;
"/>
</layout>

調(diào)用code:

StringBuilder sb = new StringBuilder();
sb.Append("test");
sb.Append("\",\"");
sb.Append("debug");
QueueLogger.Debug(sb.ToString());

寫入的信息是test","debug,在加上ConversionPattern里面的配置就是"test","debug".整個配置如下:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
  </configSections>
  <log4net xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <appender name="InfoLog" type="log4net.Appender.RollingFileAppender">
      <param name="File" value="Log\Info\Info" />
      <param name="AppendToFile" value="True" />
      <appendToFile value="true" />
      <maxSizeRollBackups value="100" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="false" />
      <rollingStyle value="Composite" />
      <datePattern value="yyyyMMdd'.csv'" />
      <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
      <layout type="log4net.CSVPatternLayout,ConsoleApp">
        <header value="Time,Thread,Level,Logger,Message,Exception&#13;&#10;" />
        <conversionPattern  value="%date{yyyy-MM-dd HH:mm:ss}%newfield%thread%newfield%level%newfield%logger%newfield%message%newfield%exception%endrow" />
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="INFO" />
        <param name="LevelMax" value="INFO" />
      </filter>
    </appender>
    <appender name="DebugLog" type="log4net.Appender.RollingFileAppender">
      <file type="log4net.Util.PatternString" value="Log\Debug\Debug" />
      <appendToFile value="true" />
      <maxSizeRollBackups value="100" />
      <maximumFileSize value="10MB" />
      <staticLogFileName value="false" />
      <rollingStyle value="Composite" />
      <datePattern value="yyyyMMdd'.csv'" />
      <lockingModel type="log4net.Appender.FileAppender+ExclusiveLock" />
      <layout type="log4net.Layout.PatternLayout">
        <header value="Time,Message,Type,&#13;&#10;" />
        <param name="ConversionPattern" value="&quot;%date{yyyy-MM-dd HH:mm:ss}&quot;,&quot;%message%&quot;&#13;&#10;"/>
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="DEBUG" />
      </filter>
    </appender>
    <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
      <mapping>
        <level value="ERROR" />
        <foreColor value="Red" />
      </mapping>
      <mapping>
        <level value="INFO" />
        <foreColor value="Green" />
      </mapping>
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="# %date{HH:mm:ss} [%thread] %-5level %logger #%newline%message%newline" />
      </layout>
      <filter type="log4net.Filter.LevelRangeFilter">
        <param name="LevelMin" value="DEBUG" />
        <param name="LevelMax" value="FATAL" />
      </filter>
    </appender>
    <root>
      <!-- OFF < FATAL < ERROR < WARN < INFO < DEBUG < ALL -->
      <level value="ALL" />
      <appender-ref ref="InfoLog" />
      <appender-ref ref="DebugLog" />
      <!-- 
        <appender-ref ref="ColoredConsoleAppender" />
      -->
    </root>
  </log4net>
</configuration>

以上是“c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章題目:c#中l(wèi)og4Net高性能寫入和CSV格式的示例分析-創(chuàng)新互聯(lián)
文章網(wǎng)址:http://www.chinadenli.net/article8/dcdgop.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供建站公司用戶體驗網(wǎng)站策劃營銷型網(wǎng)站建設(shè)響應(yīng)式網(wǎng)站手機網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)