使用log4net将日志文件输出为csv格式
我们在编写程序时,会在程序运行过程中记录一些日志。log4net作为一款经久耐用的日志组件,值得我们信赖。在中小型公司中,往往没有专业的日志服务器来处理应用程序产生的日志,而格式化不好的日志文件又为上线后日志的统计、分析、查找造成了困难。
Excel作为一款常用的办公软件,用来处理一些中小数量级的数据还是游刃有余的。如果log4net输出的日志能够直接导入Excel,那么查询和分析起来岂不是要快很多?
我们有很多方法可以实现这个功能,csv的优势是其文件格式比较简单,可以用任意的文本编辑器打开,而且解析起来比较方便。效果如下:
新建控制台程序,引用log4net类库这些步骤不必说,直接进入正题,我们需要增加4个类文件 CsvTextWriter 、 NewFieldConverter 、 EndRowConverter 和 CsvPatternLayout。
CsvTextWriter.cs
using System.IO;
using System.Text; namespace CoderBusy.Log4Net.Layout
{
public class CsvTextWriter : TextWriter
{
private readonly TextWriter _textWriter; public CsvTextWriter(TextWriter textWriter)
{
_textWriter = textWriter;
} public override Encoding Encoding => _textWriter.Encoding; public override void Write(char value)
{
_textWriter.Write(value);
if (value == '"')
_textWriter.Write(value);
} public void WriteQuote()
{
_textWriter.Write('"');
}
}
}
NewFieldConverter.cs
using System.IO;
using log4net.Util; namespace CoderBusy.Log4Net.Layout
{
public class NewFieldConverter : PatternConverter
{
protected override void Convert(TextWriter writer, object state)
{
var ctw = writer as CsvTextWriter;
ctw?.WriteQuote(); writer.Write(','); ctw?.WriteQuote();
}
}
}
EndRowConverter.cs
using System.IO;
using log4net.Util; namespace CoderBusy.Log4Net.Layout
{
public class EndRowConverter : PatternConverter
{
protected override void Convert(TextWriter writer, object state)
{
var ctw = writer as CsvTextWriter; ctw?.WriteQuote(); writer.WriteLine();
}
}
}
CsvPatternLayout.cs
using System.IO;
using log4net.Core;
using log4net.Layout; namespace CoderBusy.Log4Net.Layout
{
public class CsvPatternLayout : PatternLayout
{
public override void ActivateOptions()
{
AddConverter("newfield", typeof(NewFieldConverter));
AddConverter("endrow", typeof(EndRowConverter));
base.ActivateOptions();
} public override void Format(TextWriter writer, LoggingEvent loggingEvent)
{
var ctw = new CsvTextWriter(writer);
ctw.WriteQuote();
base.Format(ctw, loggingEvent);
}
}
}
在书写 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 " />
<conversionPattern
value="%date{yyyy-MM-dd HH:mm:ss}%newfield%thread%newfield%level%newfield%logger%newfield%message%newfield%exception%endrow" />
</layout>
我为初学者准备了一个log4net的配置文件。这个配置文件会将日志在控制台和csv文件中同时输出,每天一个CSV文件(本地时间),且控制台中,不同的日志级别会有不同的颜色。
<?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="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="Logs/" />
<param name="AppendToFile" value="True" />
<param name="MaxSizeRollBackups" value="10" />
<param name="StaticLogFileName" value="false" />
<param name="DatePattern" value="yyyy-MM-dd".csv"" />
<param name="RollingStyle" value="Date" />
<layout type="CoderBusy.Log4Net.Layout.CsvPatternLayout,CoderBusy.Log4Net">
<header value="Time,Thread,Level,Logger,Message,Exception " />
<conversionPattern
value="%date{yyyy-MM-dd HH:mm:ss}%newfield%thread%newfield%level%newfield%logger%newfield%message%newfield%exception%endrow" />
</layout>
</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="RollingLogFileAppender" />
<appender-ref ref="ColoredConsoleAppender" />
</root>
</log4net>
</configuration>
配合以上配置,测试一下功能。
using System;
using log4net;
using log4net.Config; [assembly: XmlConfigurator(ConfigFile = "log4net.config")] namespace CoderBusy.Log4Net.Tests
{
internal class Program
{
public static void Main(string[] args)
{
var log = LogManager.GetLogger("Default");
log.Debug("Message", new Exception("Test Exception"));
log.Info("Hello World.");
log.WarnFormat("A={0} B={1}", "\"123123", Environment.NewLine);
Console.ReadLine();
}
}
}
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 下载,谢谢阅读,并祝你成功。
使用log4net将日志文件输出为csv格式的更多相关文章
- 使用log4net生成日志文件
(一)使用log4net生成日志文件 1.引入log4net.dll 1.1 Nuget安装 或 http://logging.apache.org/log4net/下载log4net的源代码,编 ...
- C# Log4net根据日志等级输出到不同文件
原文地址: Log4Net.Config <?xml version="1.0" encoding="utf-8"?> <configurat ...
- Log4net根据日志等级输出到不同文件
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSec ...
- log4Net(写入日志文件)
这里就简单介绍下log4Net对写入日志文件的一些了解,写入数据库类似,就不在一一介绍了. 首先去log4net下载. 然后我们新建一个控制台应用程序,并引入log4net.dll程序集,log4ne ...
- (一)使用log4net生成日志文件
1.引入log4net.dll 1.1 Nuget安装 或 http://logging.apache.org/log4net/下载log4net的源代码,编译后把log4net.dll引入项目. 2 ...
- 利用log4net创建日志文件时过滤日志,这是坑还是?
前言 网上貌似没有太多关于log4net过滤日志的资料,在研究过程中发现一点小问题,这里做下记录,希望对后续有用到的童鞋起到一丢丢帮助作用. log4net日志过滤 由于是在.NET Core中使用, ...
- 记一次log4j日志文件输出错误的解决
log4j错误信息:log4j:ERROR Failed to rename [D:/logs/wmts_] to [D:/logs/wmts_2015-12-21.log ]. 起因:部门网站使用B ...
- 使用logback.xml配置来实现日志文件输出
转自:http://sungang-1120.iteye.com/blog/2104296 Logback是由log4j创始人设计的又一个开源日志组件.logback当前分成三个模块:logback- ...
- Qt5 调试之详细日志文件输出(qInstallMessageHandler)
注明:以下方法仅适用于 Qt5 及以上版本 函数说明: QtMessageHandler qInstallMessageHandler(QtMessageHandler handler) 此函数在使 ...
随机推荐
- KRKR基础篇(二)
这里介绍一些krkr的语法规范,具体的命令含义及用法以后再叙述 一:kag语法及基本概念 KAG使用的剧本语言为KAG Script,文件扩展名为.ks 脚本内的文字除 注释, 命令 , 段落标 ...
- 《零基础学JavaScript(全彩版)》学习笔记
<零基础学JavaScript(全彩版)>学习笔记 二〇一九年二月九日星期六0时9分 前期: 刚刚学完<零基础学HTML5+CSS3(全彩版)>,准备开始学习JavaScrip ...
- 简单在kubernetes中安装cadvisor
cadvisor用于分析docker资源占用情况及性能的工具 安装命令: docker run --volume=/:/rootfs:ro --volume=/: --detach=true --na ...
- 2.hive里的增删改查
1.hive的增删改查 查询数据库 hive> show databases; OK default Time taken: 0.254 seconds, Fetched: 1 row(s) h ...
- 《C》指针
储存单元: 不同类型的数据所占用的字节不同,上面一个长方形格子表示4个字节 变量: 变量的值,就是存储的内容.变量的名就相当于地址的名.根据变量类型分配空间:通过变量名引用变量的值,程序经过编译将变量 ...
- oracle数据库 expdp/impdp 和 exp/imp
--EXPDP导出,需要系统用户权限,一般不使用--sqlplus--1.创建dmp导出逻辑目录 create directory 目录名 as '目录路径' create directory exp ...
- Python:迭代器的简单理解
一.什么是迭代器 迭代,顾名思义就是重复做一些事很多次(就现在循环中做的那样).迭代器是实现了__next__()方法的对象(这个方法在调用时不需要任何参数),它是访问可迭代序列的一种方式,通常其从序 ...
- 求1到N(正整数)之间1出现的个数
一.题目要求 给定一个十进制的正整数,写下从1开始,到N的所有整数,然后数一下其中出现“1”的个数. 要求: 写一个函数 f(N) ,返回1 到 N 之间出现的“1”的个数.例如 f(12) = 5 ...
- 用javascript代码拼html
公司新来的同事说,他们是用javascript代码拼html代码的,如果要修改值,就是修改对象的属性. 交代下,我们现在都是用拼字符串的方式拼html代码的.他提到如果写在单独的javascript文 ...
- DB2 UDB V8.1 管理
在DB2中有关实例(Instance), 数据库(Database),表空间(TableSpace),容器(Container)等概念: 在一个操作系统中,DB2数据服务可以同时运行多个实例(有别于O ...