In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
Editor to share with you the example analysis of log4Net high-performance writing and CSV format in c#, I believe most people don't know much about it, so share this article for your reference. I hope you can learn a lot after reading this article. Let's learn about it together.
Recently, in the use of log4net, we must know how the file stream is operated before using it, otherwise it will be touched by the blind. LockingModelBase is used to control the lock of the flow in the FileAppender.cs file, and there are 3 subclasses by default
ExclusiveLock: default, 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. Using Mutex to implement multiple processes
This means that MinimalLock is a little slower than ExclusiveLock because it opens and closes the file stream every time.
But there are two categories that feel more important, PatternString.cs.
And PatternLayout.cs
If the log file is in a public directory, it is recommended that you add the computer name, application name, process ID (for example, web has multiple workers) to the log file, such as:
But the log records here are synchronous by default, but I personally prefer to write log with asynchronous multithreading. First, the information of the log is recorded in the memory ConcurrentQueue, and then the contents of the ConcurrentQueue are recorded into the file stream through a background thread. As for how much better the performance is, I don't need to say much about it. Writing memory must be faster than writing stream.
The specific implementation of 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 {/ record message Queue / private readonly ConcurrentQueue _ que / signal / private readonly ManualResetEvent _ mre; / private readonly ILog _ log; / log / private static QueueLogger flashLog = new QueueLogger () Private QueueLogger () {/ / set log profile path / / XmlConfigurator.Configure (new FileInfo (Path.Combine (AppDomain.CurrentDomain.BaseDirectory, "log4net.config")); _ que = new ConcurrentQueue (); _ mre = new ManualResetEvent (false); _ log = LogManager.GetLogger (System.Reflection.MethodBase.GetCurrentMethod (). DeclaringType) Task.Run (() = > {WriteLog ();});} / write logs from queue to disk / private void WriteLog () {while (true) {/ / wait for signal notification _ mre.WaitOne () QueueLogMessage msg / / determine whether there is any content that needs to be obtained from the queue, such as disk, and delete the content in the queue while (_ que.Count > 0 & & _ que.TryDequeue (out msg)) {/ / determine the log level. Then 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 () }} / write log / log text / level / Exception 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}) / / notify thread to write log _ mre.Set () to disk;}} 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) }} / public enum QueueLogLevel {Debug, Info, Error, Warn, Fatal} / Log content / public class QueueLogMessage {public string Message {get; set;} public QueueLogLevel Level {get; set } public Exception Exception {get; set;}
As for the CSV format, there are two methods to implement. One is the custom PatternLayout class:
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 ();}
A comma is required in the configuration file
Here
Is\ r\ n endrow% Newfield is a comma, and% endrow is a comma + line break
Seeing here, we can actually splice the content of CSV ourselves, that is to say, as long as there is,\ r\ nit will be fine.
Call code:
StringBuilder sb = new StringBuilder (); sb.Append ("test"); sb.Append ("\",\ "); sb.Append (" debug "); QueueLogger.Debug (sb.ToString ())
The information written is "test", "debug", and the configuration in ConversionPattern is "test", "debug". The entire configuration is as follows:
The above is all the content of the article "log4Net High performance Writing in c # and sample Analysis of CSV format". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.