C# 日志记录分级功能使用 按照日期,大小,或是单文件存储
本文将使用一个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# 日志记录分级功能使用 按照日期,大小,或是单文件存储的更多相关文章
- python内置函数print输出到文件,实现日志记录的功能
# bulid time 2018-6-22 import os import time def log(*args, **kwargs): # *kargs 为了通用 可不传 rule = &quo ...
- 基于java.util.logging实现轻量级日志记录库(增加根据当前类class初始化,修复线程池模型(javaEE)下的堆栈轨迹顺序与当前调用方法不一致问题)
前言: 本章介绍自己写的基于java.util.logging的轻量级日志记录库(baseLog). 该版本的日志记录库犹如其名,baseLog,是个实现日志记录基本功能的小库,适合小型项目使用,方便 ...
- mysql数据库安全性配置——日志记录
一:开启数据库日志记录 (1)在查看数据库是否开启日志记录,默认是OFF,即关闭状态.(可在数据库中执行该查询语句,也可在服务器端执行) show variables like 'log_bin'; ...
- 【干货】.NET开发通用组件发布(四) 日志记录组件
组件介绍和合作开发 http://www.cnblogs.com/MrHuo/p/MrHuoControls.html 日志记录组件功能介绍 通过基类Logger,实现了文本记录日志和数据库记录日志两 ...
- asp.net Web项目中使用Log4Net进行错误日志记录
使用log4net可以很方便地为应用添加日志功能.应用Log4net,开发者可以很精确地控制日志信息的输出,减少了多余信息,提高了日志记录性能.同时,通过外部配置文件,用户可以不用重新编译程序就能 ...
- 使用 ssm 实现登录日志记录
使用 ssm 实现登录日志记录 学习总结 一.基础准备 1. 实现效果 2. 数据表 2.1 登陆日志信息表 2.3 员工表 二.代码实现 1. SysLogLogin 实体类 2. LogAspec ...
- Hibernate使用Log4j日志记录(使用xml文件)
日志记录使程序员能够将日志详细信息永久写入文件. Log4j和Logback框架可以在hibernate框架中使用来支持日志记录. 使用log4j执行日志记录有两种方法: 通过log4j.xml文件( ...
- 如何自行给指定的SAP OData服务添加自定义日志记录功能
有的时候,SAP标准的OData实现或者相关的工具没有提供我们想记录的日志功能,此时可以利用SAP系统强大的扩展特性,进行自定义日志功能的二次开发. 以SAP CRM Fiori应用"My ...
- IOS异常日志记录与展现功能
在平常的APP开发过程中经常碰到程序遇到异常闪退的问题,通过日志可以把相关的详细错误信息进行记录,本实例要记录不管在哪个页面出错都要进行记录,这边使用到的日志记录插件CocoaLumberjack,以 ...
随机推荐
- ACM总结——2017区域赛网络赛总结
从省赛回来至今4周,每周周末都在打网络赛,每次都是划水,总结下自己弱弱的ACM吧!划水水~~ 首先是新疆赛区,基本上都是图论相关的东西,全靠队友,自己翻水水,实力躺了5道. 然后是沈阳赛区,终于有点贡 ...
- 模块 import 与from
什么是模块:就是一系列功能的集合体 模块的来源 :1内置模块 2 第三方模块 3 自定义模块 模块的格式: 1 使用python编写的.py文件 2 已被编译为共享库或DLL的C或C++扩展 ...
- 关于oracle result_cache
结果集缓存 和聚合物化视图类似,报表系统和数据仓库系统是最适合结果集缓存的,这些系统通常具有大量复杂的SQL,其中不少子查询包含聚合函数,如果能够尽可能重用这些已经计算过的聚合结果集,将极大的提升系统 ...
- CEF 跨域访问iframe
转载:https://www.cnblogs.com/wxxweb/p/3738696.html 在CefBrowserSettings也就是_cef_browser_settings_t结构体中,有 ...
- github笔记
git config --global user.name"liuhongli1"liuhongli@liuhongli:~/github/test$ git config --g ...
- Spring错误——Spring xml注释——org.xml.sax.SAXParseException; lineNumber: 24; columnNumber: 10; cvc-complex-type.2.3: 元素 'beans' 必须不含字符 [子级], 因为该类型的内容类型为“仅元素”。
背景:配置spring xml,注释xml中文件元素 错误: Caused by: org.xml.sax.SAXParseException; lineNumber: 24; columnNumbe ...
- 7.24-Codeforces Round #494 (Div. 3)
链接:http://codeforces.com/contest/1003 A. Polycarp's Pockets 题型:模拟 题意:把初始集合拆分,要求相同的数不在同一个集合中,求出需要的集合个 ...
- Apache web服务器(LAMP架构)
Apache web服务器(LAMP架构) apache介绍 1).世界上使用率最高的网站服务器,最高时可达70%:官方网站:apache.org 2).http 超文本协议 HTML 超文本标记语言 ...
- Bellman-Ford算法模板题
POJ 3259 虫洞(Bellman-Ford判断有无负环的问题) 描述: 在探索他的许多农场时,Farmer John发现了许多令人惊叹的虫洞.虫洞是非常奇特的,因为它是一条单向路径,在您进入虫洞 ...
- 学习笔记69—金蝶财务软件安装教程(KIS12.3,win10)
****************************************************** 如有谬误,请联系指正.转载请注明出处. 联系方式: e-mail: heyi9069@gm ...