zoukankan      html  css  js  c++  java
  • 使用log4net将日志文件输出为csv格式

      我们在编写程序时,会在程序运行过程中记录一些日志。log4net作为一款经久耐用的日志组件,值得我们信赖。在中小型公司中,往往没有专业的日志服务器来处理应用程序产生的日志,而格式化不好的日志文件又为上线后日志的统计、分析、查找造成了困难。

      Excel作为一款常用的办公软件,用来处理一些中小数量级的数据还是游刃有余的。如果log4net输出的日志能够直接导入Excel,那么查询和分析起来岂不是要快很多?

      我们有很多方法可以实现这个功能,csv的优势是其文件格式比较简单,可以用任意的文本编辑器打开,而且解析起来比较方便。效果如下:

      新建控制台程序,引用log4net类库这些步骤不必说,直接进入正题,我们需要增加4个类文件 CsvTextWriter 、 NewFieldConverter 、 EndRowConverter 和 CsvPatternLayout。

    CsvTextWriter.cs

     1 using System.IO;
     2 using System.Text;
     3 
     4 namespace CoderBusy.Log4Net.Layout
     5 {
     6     public class CsvTextWriter : TextWriter
     7     {
     8         private readonly TextWriter _textWriter;
     9 
    10         public CsvTextWriter(TextWriter textWriter)
    11         {
    12             _textWriter = textWriter;
    13         }
    14 
    15         public override Encoding Encoding => _textWriter.Encoding;
    16 
    17         public override void Write(char value)
    18         {
    19             _textWriter.Write(value);
    20             if (value == '"')
    21                 _textWriter.Write(value);
    22         }
    23 
    24         public void WriteQuote()
    25         {
    26             _textWriter.Write('"');
    27         }
    28     }
    29 }

    NewFieldConverter.cs

     1 using System.IO;
     2 using log4net.Util;
     3 
     4 namespace CoderBusy.Log4Net.Layout
     5 {
     6     public class NewFieldConverter : PatternConverter
     7     {
     8         protected override void Convert(TextWriter writer, object state)
     9         {
    10             var ctw = writer as CsvTextWriter;
    11             ctw?.WriteQuote();
    12 
    13             writer.Write(',');
    14 
    15             ctw?.WriteQuote();
    16         }
    17     }
    18 }

    EndRowConverter.cs

     1 using System.IO;
     2 using log4net.Util;
     3 
     4 namespace CoderBusy.Log4Net.Layout
     5 {
     6     public class EndRowConverter : PatternConverter
     7     {
     8         protected override void Convert(TextWriter writer, object state)
     9         {
    10             var ctw = writer as CsvTextWriter;
    11 
    12             ctw?.WriteQuote();
    13 
    14             writer.WriteLine();
    15         }
    16     }
    17 }

    CsvPatternLayout.cs

     1 using System.IO;
     2 using log4net.Core;
     3 using log4net.Layout;
     4 
     5 namespace CoderBusy.Log4Net.Layout
     6 {
     7     public class CsvPatternLayout : PatternLayout
     8     {
     9         public override void ActivateOptions()
    10         {
    11             AddConverter("newfield", typeof(NewFieldConverter));
    12             AddConverter("endrow", typeof(EndRowConverter));
    13             base.ActivateOptions();
    14         }
    15 
    16         public override void Format(TextWriter writer, LoggingEvent loggingEvent)
    17         {
    18             var ctw = new CsvTextWriter(writer);
    19             ctw.WriteQuote();
    20             base.Format(ctw, loggingEvent);
    21         }
    22     }
    23 }

      在书写 log4net 的配置文件时,只要将 appender 的 layout 设置为 CoderBusy.Log4Net.Layout.CsvPatternLayout ,且设置好日志头,日志格式即可。注意,header后需要编写换行字符,%newfield代表字段分隔符,%endrow代表一行结束。

          <layout type="CoderBusy.Log4Net.Layout.CsvPatternLayout,CoderBusy.Log4Net">
            <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>

      我为初学者准备了一个log4net的配置文件。这个配置文件会将日志在控制台和csv文件中同时输出,每天一个CSV文件(本地时间),且控制台中,不同的日志级别会有不同的颜色。 

     1 <?xml version="1.0" encoding="utf-8"?>
     2 
     3 <configuration>
     4   <configSections>
     5     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
     6   </configSections>
     7   <log4net xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
     8     <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
     9       <param name="File" value="Logs/" />
    10       <param name="AppendToFile" value="True" />
    11       <param name="MaxSizeRollBackups" value="10" />
    12       <param name="StaticLogFileName" value="false" />
    13       <param name="DatePattern" value="yyyy-MM-dd&quot;.csv&quot;" />
    14       <param name="RollingStyle" value="Date" />
    15       <layout type="CoderBusy.Log4Net.Layout.CsvPatternLayout,CoderBusy.Log4Net">
    16         <header value="Time,Thread,Level,Logger,Message,Exception&#13;&#10;" />
    17         <conversionPattern
    18           value="%date{yyyy-MM-dd HH:mm:ss}%newfield%thread%newfield%level%newfield%logger%newfield%message%newfield%exception%endrow" />
    19       </layout>
    20     </appender>
    21 
    22     <appender name="ColoredConsoleAppender" type="log4net.Appender.ColoredConsoleAppender">
    23       <mapping>
    24         <level value="ERROR" />
    25         <foreColor value="Red" />
    26       </mapping>
    27       <mapping>
    28         <level value="INFO" />
    29         <foreColor value="Green" />
    30       </mapping>
    31 
    32       <layout type="log4net.Layout.PatternLayout">
    33         <conversionPattern value="# %date{HH:mm:ss} [%thread] %-5level %logger #%newline%message%newline" />
    34       </layout>
    35       <filter type="log4net.Filter.LevelRangeFilter">
    36         <param name="LevelMin" value="DEBUG" />
    37         <param name="LevelMax" value="FATAL" />
    38       </filter>
    39     </appender>
    40 
    41     <root>
    42       <!-- OFF < FATAL < ERROR < WARN < INFO < DEBUG < ALL -->
    43       <level value="ALL" />
    44       <appender-ref ref="RollingLogFileAppender" />
    45       <appender-ref ref="ColoredConsoleAppender" />
    46     </root>
    47   </log4net>
    48 </configuration>

      配合以上配置,测试一下功能。

     1 using System;
     2 using log4net;
     3 using log4net.Config;
     4 
     5 [assembly: XmlConfigurator(ConfigFile = "log4net.config")]
     6 
     7 namespace CoderBusy.Log4Net.Tests
     8 {
     9     internal class Program
    10     {
    11         public static void Main(string[] args)
    12         {
    13             var log = LogManager.GetLogger("Default");
    14             log.Debug("Message", new Exception("Test Exception"));
    15             log.Info("Hello World.");
    16             log.WarnFormat("A={0} B={1}", ""123123", Environment.NewLine);
    17             Console.ReadLine();
    18         }
    19     }
    20 }

    Logs文件夹中,生成的csv文件内容如下:

    Time,Thread,Level,Logger,Message,Exception
    "2016-08-25 23:13:19","9","DEBUG","Default","Message","System.Exception: Test Exception
    "
    "2016-08-25 23:13:19","9","INFO","Default","Hello World.",""
    "2016-08-25 23:13:19","9","WARN","Default","A=""123123 B=
    ",""

      输出字段被使用双引号包裹,且消息体中的双引号被重复输出。这样的结果表明我们的程序是正常的。本文的代码可以在 http://pan.baidu.com/s/1hr4EOPu 下载,谢谢阅读,并祝你成功。

  • 相关阅读:
    use paramiko to connect remote server and execute command
    protect golang source code
    adjust jedi vim to python2 and python3
    install vim plugin local file offline
    add swap file if you only have 1G RAM
    datatables hyperlink in td
    django rest framework custom json format
    【JAVA基础】网络编程
    【JAVA基础】多线程
    【JAVA基础】String类的概述和使用
  • 原文地址:https://www.cnblogs.com/Soar1991/p/5808788.html
Copyright © 2011-2022 走看看