考虑题4所示的日志记录_基于Log4Net实现日志信息双向存储
1、引言
在上位机开发中,日志记录是必不可少的,我们可以通过日志记录做日志分析及错误追踪。初学者会采用txt文本写入来实现日志保存,但是文本写入不是线程安全,当存在多个线程同时写入日志时,就会出现一些问题。Log4net库是.Net下一个非常优秀的开源日志记录组件,是一个帮助开发者将日志信息输出到各种目标(控制台、文件、数据库等)的工具。本节主要采用开源组件Log4Net来实现错误ERROR信息文本存储,并结合SQLite数据库,将日志INFO信息存储到数据库中,便于后续的查询。
2、开发准备
- 首先新建一个Windows窗体应用,取名为thinger.cn.Log4NetSQLitePro,UI界面设计如下所示:
- 通过Nuget添加Log4Net开源组件,如下所示:
- 通过Nuget添加SQLite组件,如下所示:
3、文本存储
一般情况下,我们可以将一些错误及异常信息存储在文本中,便于随时打开文件进行查询,文本存储将自动以天为单位,每天对应一个文件,步骤如下:
- 添加一个应用程序配置文件
项目右击添加新建项,项目类型选择应用程序配置文件,名称为log4net.config,如下所示:
- 配置文件编写
日志配置文件增加相关节点,如下所示:
配置文件规定了日志信息的相关属性、存储方式、日志内容格式等,配置信息如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/></configSections><log4net><root></root><appender name="InfoAppender" type="log4net.Appender.RollingFileAppender,log4net" ><param name="File" type="" value="Log/Error/" /><param name="AppendToFile" value="true" /><param name="RollingStyle" value="Date" /><param name="DatePattern" value="yyyyMMdd".ini"" /><param name="StaticLogFileName" value="false" /><layout type="log4net.Layout.PatternLayout,log4net"><param name="ConversionPattern" value="[%d]%n%m%n%n" /></layout></appender><logger name="Error"><level value="ERROR" /><appender-ref ref="InfoAppender" /></logger></log4net>
</configuration>
其中,较为重要的是日志信息的格式,对应上面文件中的ConversionPattern,值为"[%d]%n%m%n%n",每个占位符有对应的含义,如下所示:
字符格式 | 说明 |
%m(message) | 输出的日志消息 |
%n(newline) | 换行 |
%d(datetime) | 输出当前语句运行的时刻 |
%r(runtime) | 输出程序执行到当前消耗的毫秒数 |
%t(threadid) | 当前语句所在的线程ID |
%p(priority) | 日志的当前日志级别 |
%c(class) | 当前日志对象的名称 |
%L | 输出语句所在的行号 |
%F | 输出语句所在的文件名 |
%-10 | 最小长度为10,不够空格填充 |
字符格式 | 说明 |
%m(message) | 输出的日志消息 |
%n(newline) | 换行 |
%d(datetime) | 输出当前语句运行的时刻 |
%r(runtime) | 输出程序执行到当前消耗的毫秒数 |
%t(threadid) | 当前语句所在的线程ID |
%p(priority) | 日志的当前日志级别 |
%c(class) | 当前日志对象的名称 |
%L | 输出语句所在的行号 |
%F | 输出语句所在的文件名 |
%-10 | 最小长度为10,不够空格填充 |
- 配置文件属性中的复制到输出目录,设置为始终复制或如果较新则复制,如下图所示:
- 项目的AssemblyInfo.cs类中添加一行代码,如下所示:
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "log4net.config", ConfigFileExtension = "config", Watch = true)]
- 添加一个LogHelper类,编写2个Error的方法,如下所示:
// 错误日志带异常public static void Error(string message,Exception ex){ILog log = LogManager.GetLogger("Error"); if (log.IsErrorEnabled){log.Error(message,ex);}}// 错误日志不带异常public static void Error(string message){ILog log = LogManager.GetLogger("Error");if (log.IsErrorEnabled){log.Error(message);}}
- 在ini文本存储按钮事件下,调用错误日志写入,如下所示:
private void btn_ini_Click(object sender, EventArgs e){//不带异常LogHelper.Error(this.txt_ini.Text.Trim());//带异常LogHelper.Error(this.txt_ini.Text.Trim(),new Exception("这是一条异常错误信息"));}
- 执行完成后,在项目目录,LogError目录下,产生一条当天日志命名的文件,打开如下所示:
4、SQLite存储
日志信息存储到数据库的好处在于便于用户通过界面进行查询,这里采用开源免费数据库SQLite,其他关系型数据库,如SQLServer、mysql,原理都是一样的,具体步骤如下所示:
- 创建数据库及数据表
通过SQLiteStudio软件创建一个数据库,取名为Log4NetSQLite,执行以下脚本创建一个Log数据表:
CREATE TABLE Log
(LogId INTEGER PRIMARY KEY,Date DATETIME NOT NULL,Level VARCHAR(50) NOT NULL,Logger VARCHAR(255) NOT NULL,Message TEXT DEFAULT NULL
);
- 将数据库文件复制到项目根目录下的DataBase文件夹中
- 修改log4net.config文件,增加数据库存储相关配置,如下所示:
<?xml version="1.0" encoding="utf-8" ?>
<configuration><configSections><section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/></configSections><log4net><root></root><appender name="InfoAppender" type="log4net.Appender.RollingFileAppender,log4net" ><param name="File" type="" value="Log/Error/" /><param name="AppendToFile" value="true" /><param name="RollingStyle" value="Date" /><param name="DatePattern" value="yyyyMMdd".ini"" /><param name="StaticLogFileName" value="false" /><layout type="log4net.Layout.PatternLayout,log4net"><param name="ConversionPattern" value="[%d]%n%m%n" /></layout></appender><appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender"><bufferSize value="0" /><connectionType value="System.Data.SQLite.SQLiteConnection,System.Data.SQLite" /><connectionString value="Data Source=C:UsersxiketangDesktopthinger.com.Log4NetSQLiteProthinger.com.Log4NetSQLiteProbinDebugDataBaseLog4NetSQLite.db;Version=3;" /><commandText value="INSERT INTO Log (Date, Level, Logger, Message) VALUES (@Date, @Level, @Logger, @Message)" /><parameter><parameterName value="@Date" /><dbType value="DateTime" /><layout type="log4net.Layout.RawTimeStampLayout" /></parameter><parameter><parameterName value="@Level" /><dbType value="String" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%level" /></layout></parameter><parameter><parameterName value="@Logger" /><dbType value="String" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%logger" /></layout></parameter><parameter><parameterName value="@Message" /><dbType value="String" /><layout type="log4net.Layout.PatternLayout"><conversionPattern value="%message" /></layout></parameter></appender><logger name="Error"><level value="ERROR" /><appender-ref ref="InfoAppender" /></logger><logger name="Info"><level value="INFO" /><appender-ref ref="AdoNetAppender" /></logger></log4net>
</configuration>
bufferSize:日志缓存写入条数 设置为0时只要有一条就立刻写到数据库
connectionString:SQLite指向的是数据库文件的绝对路径
- LogHelper类中增加一个Info方法,如下所示:
public static void Info(string message){ILog log = LogManager.GetLogger("Info");if (log.IsInfoEnabled){log.Info(message);}}
- 在SQLite存储按钮事件下,调用Info日志写入,如下所示:
private void btn_SQLite_Click(object sender, EventArgs e){//日志信息写入数据库LogHelper.Info(this.txt_SQLite.Text.Trim());}
- 执行完成后,打开数据库,查看是否有相关记录:
5、实际应用
通过上面一系列的描述,相信大家对Log4Net的应用有了一些了解,Log4Net构建的日志系统是很多项目必备的一个功能,对项目开发、调试及后续维护都有着至关重要的作用。实际使用时,我们还可以将Log4Ne作为一个简单的数据存储工具,甚至可以使用Log4Net做多表多库存储,这些内容后续再给大家进行介绍。
考虑题4所示的日志记录_基于Log4Net实现日志信息双向存储相关推荐
- php出错日志记录_关于PHP错误日志踩过的一些坑
nginx是一个web服务器,因此nginx的access日志只有对访问页面的记录,不会有php 的 error log信息. nginx把对php的请求发给php-fpm fastcgi进程来处理, ...
- log4j2 无日志记录_在Log4j2中更好地执行非日志记录器调用
log4j2 无日志记录 使用Log4j 1.x并希望避免在某些情况下可能会造成额外的性能影响(即使实际上未记录该消息)时,通常使用日志记录防护 . Java的简单日志记录外观 ( SLF4J )带给 ...
- go语言web开发系列之五:gin用zap+file-rotatelogs实现日志记录及按日期切分日志
一,安装需要用到的库: 1,安装zap日志库: liuhongdi@ku:/data/liuhongdi/zaplog$ go get -u go.uber.org/zap 2,安装go-file-r ...
- 基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)...
背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或 ...
- mysql 日志记录 archive_完美起航-Mysql日志管理、备份与恢复
一.Mysql日志分类 MySQL的默认日志保存位置为/usr/local/mysql/data vim /etc/my.cnf 1.错误日志 说明: 在对应的数据目录中,以主机名+.err命名的文件 ...
- c#物联网_基于C#实现日志记录与SQL SERVER的双向存储工控数字化之旅
↑ 点击上方 "智能制造之家" 关注我们 写在前面 我们在做一些PLC设备联网改造.SCADA项目.MES项目等的时候,我们经常需要做日志记录,这样便于后续做日志分析及错误追踪.比 ...
- 服务器日志记录_5种改善服务器日志记录的技术
服务器日志记录 在最近的时间里,我们已经看到了许多工具可以帮助您理解日志. 开源项目(例如Scribe和LogStash),内部部署工具(例如Splunk)以及托管服务(例如SumoLogic和Pap ...
- 日志记录到字段变更_Wal日志解析工具开源: Walminer
作者简介 李传成: 瀚高软件内核研发工程师,主要研究方向为数据库的备份和恢复,对wal日志的原理和应用有较深的理解.自研了wal日志解析工具walminer.pg块恢复工具pg_lightool. 一 ...
- 【日志记录】基于AOP实现自定义日志注解,并支持动态设置注解内容
前言 平时在java项目开发过程中,涉及到记录操作日志的场景很多,有时候大家习惯把操作日志的生成代码写到业务代码中,这样造成了日志和业务代码的耦合性比较高.可维护性也不强,易读性更差,更多的时候是使用 ...
最新文章
- 2009下半年网络管理员试题及答案
- java 过滤文件名_Java FileNameFilter过滤文件名
- Ribbon源码解析(二)
- 一致性环Hash算法.NET实现
- Avalonia跨平台入门第十三篇之Expander控件
- CF1067E Random Forest Rank(树形dp,概率与期望,线性代数)
- Android学习系列(15)--App列表之游标ListView(索引ListView)
- IntelliJ IDEA中Maven项目的默认JDK版本
- 深度学习笔记_基本概念_神经网络中的epoch、batch_size和iteration
- 云服务器操作系统新手,云服务器操作系统新手
- maven集成tomcat7
- [破解] nasca drm file -ver1.00
- [转]word只能用安全模式才能打开怎么解决
- 面部表情识别---学习笔记
- GB2312 编码(转)
- 炒鸡详细的windows安装python教程
- JavaScript中let的用法
- 1032 挖掘机技术哪家强 (20 分)
- 刷题总结——regular words(hdu1502 dp+高精度加法+压位)
- 我的奇思妙想机器人消防员_我是小小消防员~来啊~斗图啊~看一场奇思妙想SHOW!...