Log4net examples of high performance writes and CSV formats

Source: Internet
Author: User
Tags log4net

Recently in the use of log4net, before using, we must know how the file stream operation, or the blind touch ... , there is a lockingmodelbase in the FileAppender.cs file to control the lock of the stream, the default is 3 sub-classes

Exclusivelock: Default, hold a exclusive lock on the output file,open the file once for writing and hold it Open until Closefil E 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 holdi Ng the lock for the minimal amount of time. This method of locking was considerably slower than Fileappender.exclusivelock but allows other processes to move/delete th E log file whilst logging continues.

Interprocesslock:provides cross-process file locking. Using mutexes to implement multiple processes

This means that minimallock is slower than exclusivelock because it opens and closes the file stream every time.

But there are 2 of classes that feel more important PatternString.cs


and PatternLayout.cs




If the log file is in a common directory, it is recommended that you log files plus the computer name, application name, process ID (such as multiple workers on the web) such as:

<file type= "log4net. Util.patternstring "value=" \\192.168.0.1\logs\%env{computername}\%appsetting{applicationname}\%processid\log\ "/ >

But the log records here by default are synchronized, but I personally tend to use asynchronous multi-threaded thinking to write log, first log information recorded in the memory Concurrentqueue inside, It then logs the contents of the Concurrentqueue into the file stream through a background thread . As for the performance of how much more I would like to say no more, write memory must be faster than writing flow

The specific implementation code is as follows:

[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>///Record Message queue///</summary> PR        Ivate readonly concurrentqueue<queuelogmessage> _que;        <summary>///signal///</summary> private readonly ManualResetEvent _mre;        <summary>///journal///</summary> private readonly ILog _log; <summary>///Log///</summary> private static Queuelogger Flashlog = new Queuelogger        (); Private Queuelogger () {//Set Log profile path//xmlconfigurator.configure (New FileInfo (Path.Combine (A            PpDomain.CurrentDomain.BaseDirectory, "Log4net.config"))); _que = new ConcurreNtqueue<queuelogmessage> ();            _mre = new ManualResetEvent (false); _log = Logmanager.getlogger (System.Reflection.MethodBase.GetCurrentMethod ().            DeclaringType);        Task.run (() = {Writelog ();});            }///<summary>//write logs from the queue to disk///</summary> private void Writelog () { while (true) {//waits for signal notification _mre.                WaitOne ();                Queuelogmessage msg; Determine if there is a need for content such as a disk to get content from a queue and delete the contents of a queue while (_que. Count > 0 && _que. Trydequeue (out msg)) {//Judge log level, then write log 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 }}//Reset signal _mre.            Reset (); }}///<summary>//write Log///</summary>//<param name= "message" > Log Text </param>//<param Name= "level" > Grade </param>//<param name= "ex" >exception</par am> 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}); Notifies the thread to write log _mre to disk.            Set (); }} public static void Debug (String msg, Exception ex = null) {Flashlog.enqueuemessage (ms        G, Queueloglevel.debug, ex); public static void Error (String msg, Exception ex = null) {flashlog.enqueuemessage (msg, Queuel        Oglevel.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, Queuelo        Glevel.info, ex); } public static void Warn (String msg, Exception ex = null) {flashlog.enqueuemessage (msg, Queuelo        Glevel.warn, ex); }}///<summary>///log level///</summary> public enum Queueloglevel {Debug, I NFO, Error, Warn, Fatal}//<summary>//log content///</summary> public CLA        SS Queuelogmessage {public string Message {get; set;}        Public Queueloglevel level {get; set;}    Public Exception Exception {get; set;} }}

namespace log4net{using Layout;    Using System.IO;    Using System.Text;    Using Util;    Using Core; public class Csvpatternlayout:patternlayout {public override void Activateoptions () {Addco            Nverter ("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 Co            Nvert (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 (); }    }}

A comma is required in the configuration file

<layout type= "log4net. Csvpatternlayout,consoleapp ">

Here & #13;& #10; \r\n,%newfield is a comma,%endrow is a comma + newline

See here in fact we can join the content of the CSV itself, that is, as long as there is, \ r \ n can

<layout type= "log4net. Layout.patternlayout ">

Call Code:

StringBuilder sb = new StringBuilder (); sb. Append ("Test"); sb. Append ("\", \ ""); sb. Append ("Debug"); Queuelogger.debug (sb.) ToString ());

The information written is"test", "Debug", in addition to the configuration of the Conversionpattern, "" "Debug". The entire configuration is as follows:

<?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="/> <maxim "       Umfilesize value= "10MB"/> <staticlogfilename value= "false"/> <rollingstyle value= "Composite"/> <datepattern value= "YyyyMMdd '. csv '"/> <lockingmodel type= "log4net. Appender.fileappender+minimallock "/> <layout type=" log4net. Csvpatternlayout,consoleapp "> 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.