本文将使用一个Nuget的一个组件库来实现一个简单强大的日志记录功能,包采用线程安全实现,所有的记录在后台完成,即使您在前台调用100万次方法,耗时也不过1000ms(具体时间依照电脑性能决定),支持日志等级,并提供了一个控件用于分析所有的日志消息。

在visual studio 中的Nuget管理器中可以下载安装,也可以直接在Nuget控制台输入下面的指令安装:

Install-Package HslCommunication

Nuget安装教程:http://www.cnblogs.com/dathlin/p/7705014.html

联系作者及加群方式(激活码在群里发放):http://www.hslcommunication.cn/Cooperation

本组件提供了一个日志功能,实现了常用的3中日志模式:

  • 单日志文件模式,日志始终都向该文件写入,需要程序中自行清除或手动编写代码清空,不然文件会很大。
  • 根据文件大小存储的多文件模式,一个日志文件写入达到某个数值时,创建新文件写入。
  • 根据时间日期的多文件模式,每条日志将根据写入的时间日志来判断文件名,比如创建按每天存储的日志。

我也曾使用过.net中大名鼎鼎的log4net日志组件,一般使用起来确实方便,但是我在诸如实现上述的需求的时候就特别麻烦,而且log4net功能众多,大多数功能并不是我所需要的,我就需要一个实现txt日志的存储方式,简单高效,多种模式即可。于是就自行开发了一个简单高效的日志组件,并集成到了该通信库中,本日志组件还提供了一个分析控件及窗口,可以对一个长长的日志文件进行分析统计(只对本组件生成的日志有效),快速定位需要查找的日志信息,支持使用正则表达式来筛选,本日志组件也提供了分级存储。

Demo程序下载 HslCommunicationDemo.zip

使用之前先要进行命名控件的引用,如下:

using HslCommunication.LogNet;

  

实例化

首先先实例化一个对象,如果您用于整个application的日志存储,可以定义成静态对象。或者直接定义在form窗口的下面也可以。此处先实例化单文件存储的机制

private ILogNet logNet = new LogNetSingle("D:\\123.txt");

  

我们通常的做法是日志文件存储在exe程序目录下的Logs文件夹中,无论在服务器端还是客户端都是非常适用的,所以

private ILogNet logNet = new LogNetSingle(Application.StartupPath + "\\Logs\\123.txt");

  

写日志

接下来你就可以在窗口的其他地方进行写入日志了,本组件提供了5个等级的日志写入功能,名称参考了常规的日志等级,有 DEBUG , INFO, WARN , ERROR , FATAL ,根据需要进行存储,还提供了对exception异常的方法支持和自定义的描述化文本写入,该文本不属于日志范畴,在日志分析中会被忽略,如下代码演示几种不同的写入(写入的方式采用统一的接口实现,对于三种日志模式都是适用的):

        private void userButton1_Click(object sender, EventArgs e)
{
// 一般日志写入
logNet.WriteDebug("调试信息");
logNet.WriteInfo("一般信息");
logNet.WriteWarn("警告信息");
logNet.WriteError("错误信息");
logNet.WriteFatal("致命信息");
logNet.WriteException(null, new IndexOutOfRangeException()); // 带有关键字的写入,关键字建议为方法名或是类名,方便分析的时候归类搜索
logNet.WriteDebug("userButton1_Click", "调试信息");
logNet.WriteInfo("TestForm", "一般信息");
logNet.WriteWarn("随便什么", "警告信息");
logNet.WriteError("userButton1_Click", "错误信息");
logNet.WriteFatal("userButton1_Click", "致命信息");
logNet.WriteException("userButton1_Click", new IndexOutOfRangeException());
}

写入异常时会被自动赋予 FATAL 等级。写入效果如下:

下面再说明写入描述文本的时候发生的事情:

logNet.WriteDescrition("这是一条描述文本");

 

描述性文本的前面会再新增一行作为明显的区分。描述性文本不列入到日志分析工具中,会被自动被过滤。

 

设置等级

为什么要实现日志分级呢?有两个巨大的好处。第一个好处是方便在日志追述的时候进行筛选,比如我需要查看日志中致命错误的时候就尤为重要,可以进行快速的筛选。第二个好处就是用于开发的时候调试使用,有时候我们为了快速的找到程序问题的时候,会对程序运行中各种数据状态,系统状态进行输出,然后分析日志得出结论。当你已经写了很多很多的

logNet.WriteDebug("调试信息");

代码后,准备发布使用的时候不想输出这种仅用于调试的时候的日志,总不可能取消所有的调试日志吧?效率太低,万一以后需要恢复输出就麻烦了,所以本日志组件支持写入日志的时候的等级设置,如果我们把日志的等级设置为INFO级别,那么所有的DEBUG级别的日志都不会存储,所以我们在发布软件的时候,只要设置等级就行。

下面再来说明下如何设置日志存储等级。使用方法:

logNet.SetMessageDegree(HslMessageDegree.DEBUG);//所有等级存储
logNet.SetMessageDegree(HslMessageDegree.INFO);//除DEBUG外,都存储
logNet.SetMessageDegree(HslMessageDegree.WARN);//除DEBUG和INFO外,都存储
logNet.SetMessageDegree(HslMessageDegree.ERROR);//只存储ERROR和FATAL
logNet.SetMessageDegree(HslMessageDegree.FATAL);//只存储FATAL
logNet.SetMessageDegree(HslMessageDegree.None);//不存储任何等级

选择上面的一行代码执行就行。

自定义事件

组件默认存储所有的等级,如果需要设置,在实例化后即可设置等级。日志组件支持一个事件,在所有的日志进行存储前(被日志等级过滤掉的不会触发)会报告事件,可以用于其他操作或是控制台的显示等等,注意: 如果在事件关联方法中直接访问UI线程,会异常

这个事件有个非常大的好处,可以统一输出显示你的程序中所有地方的日志,方便统一的控制和处理。

logNet.BeforeSaveToFile += LogNet_BeforeSaveToFile;
private void LogNet_BeforeSaveToFile(object sender, HslEventArgs e)
{
// 如果需要UI显示,就要取消注释下方的代码 //if(InvokeRequired)
//{
// Invoke(new Action(() =>{
// LogNet_BeforeSaveToFile(sender, e);
// }));
// return;
//} string degree = e.HslMessage.Degree.ToString();//获取等级
DateTime time = e.HslMessage.Time;//获取时间
string text = e.HslMessage.Text;//日志文本
int threadId = e.HslMessage.ThreadId;//记录日志的线程id
}

  

这个事件在2019年2月10日 16:36:41上新增了一个额外的功能,就是允许你手动取消当前日志的存储

        private void LogNet_BeforeSaveToFile( object sender, HslEventArgs e )
{
e.HslMessage.Cancel = checkBox1.Checked;
}

假设这样设置后,所有的日志都不存储到文件中去。

        private void LogNet_BeforeSaveToFile( object sender, HslEventArgs e )
{
if (e.HslMessage.Degree != HslMessageDegree.INFO)
{
e.HslMessage.Cancel = checkBox1.Checked;
}
}

如果这么写,就是只存储INFO等级的日志信息。

过滤指定的关键字日志存储

有些日志数据可能我们想要触发BeforeSaveToFile事件,但是不能存储到日志文件里,那么可以直接按照如下的配置进行设置,会过滤掉存储到文件中,如下就是过滤掉关键字的信息

logNet.FiltrateKeyword( "123" );

按文件大小存储的实例化

若要按照文件大小进行存储,例如日志存储2M后,自动生成新的文件,然后存满2M后生成新文件,如此重复,则需要指定文件的 存储路径大小 ,这种方式存储的文件名称不可控制,自动定义为 Logs_20170903170604.txt 的格式,会以当前时间自动命名,如下举例了实例化一个2M大小的对象:

ILogNet logNet = new LogNetFileSize(Application.StartupPath + "\\customer1", 2 * 1024 * 1024);

  

只要定义了对象,就可以按照上述写入日志的代码来写了。

按时间日期存储的实例化

也是一种多文件的存储机制,和按照大小的存储非常类似,此处可以配置按照每小时生成新的文件,每天新的文件,每月新的文件,每季度新的文件,每年新的文件,生成的文件名称也是固定的,需要指定 路径存储模式

ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2",GenerateMode.ByEveryHour);//按每小时
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEveryDay);//按每天
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEveryMonth);//按每月
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEverySeason);//按每季度
ILogNet logNet = new LogNetDateTime(Application.StartupPath + "\\customer2", GenerateMode.ByEveryYear);//按每年

  

单文件模式

单文件的模式在上述已经作为演示说明过了,但是单文件模式提供了两个额外的方法:

  • 获取该文件日志中所有的内容
  • 清空该文件的所有数据

具体的代码如下所示:

LogNetSingle logNetSingle = logNet as LogNetSingle;
if (logNetSingle != null)
{
string logData = logNetSingle.GetAllSavedLog();//获取所有的日志信息
logNetSingle.ClearLog();//清除所有的日志信息
}

  

日志查看器

如果只提供了一个日志的写入而没有分析工具,那么本组件就是没什么竞争力的,本日志组件提供了一个大杀器,日志分析控件!您可以集成到您自己的系统中,该控件只需要接受一个 日志源字符串 (就是日志文件的所有字符串数据,服务器读取文件发送给远程客户端就可以现实远程查看日志分析!棒不棒!)原先的 ClientServerProject 项目中已经带有了2个日志查看器,一个服务器端使用了本组件提供的标准form窗口,客户端使用了日志分析控件实现远程查看功能,具体代码可以参照 ClientServerProject 项目的代码。

功能概述

  • 对日志文件中的所有等级日志进行分析,每种等级多少个
  • 可以同时根据日志等级和时间区段来筛选日志,比如查看某一时间段的 DEBUG 等级日志
  • 可以进行可视化分析,查看日志数据的时间分布情况
  • 在可视化的界面,如果某个区间段的某日数量特别高,鼠标移动上去后还可以自动跳转

此处直接演示一个组件标准的日志查看窗口,这个窗口也可以在wpf项目中显示:

        private void userButton13_Click(object sender, EventArgs e)
{
// 日志查看器
using (HslCommunication.LogNet.FormLogNetView form = new HslCommunication.LogNet.FormLogNetView())
{
form.ShowDialog();
}
}

效果上图

查看日志信息

上图中点击了 信息 按钮后,显示的图形发生了变化,只显示了 信息 等级日志

光标移动到某一区间后,下方会有该区间的日志数量和时间范围,双击后的操作就您自己去发现了。^_^

控件的方式,新建一个窗口,将组件的控件给拖进去,如果这个组件在工具箱不显示,那么需要将dll文件拖到工具箱。

至于显示信息代码:

        private void FormLogNetTest_Load(object sender, EventArgs e)
{
// 该source可以是本地读取的文件,也可以是网络发送过来的数据
string source = Encoding.UTF8.GetString(System.IO.File.ReadAllBytes("123.txt")); // 传入路径
logNetAnalysisControl1.SetLogNetSource(source);
}

C# 日志记录分级功能使用 按照日期,大小,或是单文件存储的更多相关文章

  1. python内置函数print输出到文件,实现日志记录的功能

    # bulid time 2018-6-22 import os import time def log(*args, **kwargs): # *kargs 为了通用 可不传 rule = &quo ...

  2. 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)

    前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...

  3. mysql数据库安全性配置——日志记录

    一:开启数据库日志记录 (1)在查看数据库是否开启日志记录,默认是OFF,即关闭状态.(可在数据库中执行该查询语句,也可在服务器端执行) show variables like 'log_bin'; ...

  4. 【干货】.NET开发通用组件发布(四) 日志记录组件

    组件介绍和合作开发 http://www.cnblogs.com/MrHuo/p/MrHuoControls.html 日志记录组件功能介绍 通过基类Logger,实现了文本记录日志和数据库记录日志两 ...

  5. asp.net Web项目中使用Log4Net进行错误日志记录

      使用log4net可以很方便地为应用添加日志功能.应用Log4net,开发者可以很精确地控制日志信息的输出,减少了多余信息,提高了日志记录性能.同时,通过外部配置文件,用户可以不用重新编译程序就能 ...

  6. 使用 ssm 实现登录日志记录

    使用 ssm 实现登录日志记录 学习总结 一.基础准备 1. 实现效果 2. 数据表 2.1 登陆日志信息表 2.3 员工表 二.代码实现 1. SysLogLogin 实体类 2. LogAspec ...

  7. Hibernate使用Log4j日志记录(使用xml文件)

    日志记录使程序员能够将日志详细信息永久写入文件. Log4j和Logback框架可以在hibernate框架中使用来支持日志记录. 使用log4j执行日志记录有两种方法: 通过log4j.xml文件( ...

  8. 如何自行给指定的SAP OData服务添加自定义日志记录功能

    有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...

  9. IOS异常日志记录与展现功能

    在平常的APP开发过程中经常碰到程序遇到异常闪退的问题,通过日志可以把相关的详细错误信息进行记录,本实例要记录不管在哪个页面出错都要进行记录,这边使用到的日志记录插件CocoaLumberjack,以 ...

随机推荐

  1. Base64 空格,加号问题

    缘由: 在一个项目中,app请求tcpdump日志与记录的日志内容不一致 请求%2B 识别成 + 请求 + 识别成 空格 这个在base64解密的时候会出现异常,base64需要的是加号,而不是空格 ...

  2. 破解微信防盗链&微信公众号文章爬取方案

    破解微信图文防盗链:https://www.cnblogs.com/xsxshmily/p/8000043.html 图片解除防盗链:https://blog.csdn.net/show_ljw/ar ...

  3. A_Pancers团队作业4—基于原型的团队项目需求调研与分析

    任务1:实施团队项目软件用户调研活动. (1)用户调研对象:我们的项目软件是基于安卓系统的音乐播放器,以设计出操作简单的音乐播放器为目的,所以本次用户调研的对象主要以身边的老人为主,对他们听音乐,听戏 ...

  4. iconfont作用在css伪类中的写法

    iconfont作用在css伪类中需要注意两点: 1.字体声明(font-family: "iconfont";). 2.把字体写成十六进制的Unicode编码.比如:" ...

  5. 一个完整的成年果蝇大脑的电子显微镜图谱 | A Complete Electron Microscopy Volume of the Brain of Adult Drosophila melanogaster

    paper:A Complete Electron Microscopy Volume of the Brain of Adult Drosophila melanogaster 果蝇是一个非常完美的 ...

  6. Go语言开发Prometheus Exporter示例

    一.Prometheus中的基本概念 Prometheus将所有数据存储为时间序列,这里先来了解一下prometheus中的一些基本概念 指标名和标签每个时间序列都由指标名和一组键值对(也称为标签)唯 ...

  7. Python requests代理

    self.ip=requests.get('http:ip获取') self.ip=(self.ip.text).replace('\r','').replace('\n','') print('IP ...

  8. Matlab:椭圆方程的导数边值问题

    tic; clear clc N=; M=*N; h1=/M; h2=/N; x=:h1:; y=:h2:; fun=inline('exp(x)*sin(pi*y)','x','y'); f=inl ...

  9. Descriptors;Hello1 project中的Web.xml

    Deployment Descriptors(描述符)是一个xml文件,用来描述如何部署一个模块或者应用(根据描述符中定义的配置和容器选项).举例来说,一个EJB的部署描述符会向EJB容器传递如何管理 ...

  10. 快速高效实现微信小程序图片上传与腾讯免费5G存储空间的使用

    本文介绍了如何在微信小程序开发中使用腾讯官方提供的云开发功能快速实现图片的上传与存储,以及介绍云开发的 5G 存储空间的基本使用方法,这将大大提高微信小程序的开发效率 对于一般的图片上传功能开发,我们 ...