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&quot;.ini&quot;" /><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&quot;.ini&quot;" /><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实现日志信息双向存储相关推荐

  1. php出错日志记录_关于PHP错误日志踩过的一些坑

    nginx是一个web服务器,因此nginx的access日志只有对访问页面的记录,不会有php 的 error log信息. nginx把对php的请求发给php-fpm fastcgi进程来处理, ...

  2. log4j2 无日志记录_在Log4j2中更好地执行非日志记录器调用

    log4j2 无日志记录 使用Log4j 1.x并希望避免在某些情况下可能会造成额外的性能影响(即使实际上未记录该消息)时,通常使用日志记录防护 . Java的简单日志记录外观 ( SLF4J )带给 ...

  3. go语言web开发系列之五:gin用zap+file-rotatelogs实现日志记录及按日期切分日志

    一,安装需要用到的库: 1,安装zap日志库: liuhongdi@ku:/data/liuhongdi/zaplog$ go get -u go.uber.org/zap 2,安装go-file-r ...

  4. 基于log4net的日志组件扩展封装,实现自动记录交互日志 XYH.Log4Net.Extend(微服务监控)...

    背景: 随着公司的项目不断的完善,功能越来越复杂,服务也越来越多(微服务),公司迫切需要对整个系统的每一个程序的运行情况进行监控,并且能够实现对自动记录不同服务间的程序调用的交互日志,以及通一个服务或 ...

  5. mysql 日志记录 archive_完美起航-Mysql日志管理、备份与恢复

    一.Mysql日志分类 MySQL的默认日志保存位置为/usr/local/mysql/data vim /etc/my.cnf 1.错误日志 说明: 在对应的数据目录中,以主机名+.err命名的文件 ...

  6. c#物联网_基于C#实现日志记录与SQL SERVER的双向存储工控数字化之旅

    ↑ 点击上方 "智能制造之家" 关注我们 写在前面 我们在做一些PLC设备联网改造.SCADA项目.MES项目等的时候,我们经常需要做日志记录,这样便于后续做日志分析及错误追踪.比 ...

  7. 服务器日志记录_5种改善服务器日志记录的技术

    服务器日志记录 在最近的时间里,我们已经看到了许多工具可以帮助您理解日志. 开源项目(例如Scribe和LogStash),内部部署工具(例如Splunk)以及托管服务(例如SumoLogic和Pap ...

  8. 日志记录到字段变更_Wal日志解析工具开源: Walminer

    作者简介 李传成: 瀚高软件内核研发工程师,主要研究方向为数据库的备份和恢复,对wal日志的原理和应用有较深的理解.自研了wal日志解析工具walminer.pg块恢复工具pg_lightool. 一 ...

  9. 【日志记录】基于AOP实现自定义日志注解,并支持动态设置注解内容

    前言 平时在java项目开发过程中,涉及到记录操作日志的场景很多,有时候大家习惯把操作日志的生成代码写到业务代码中,这样造成了日志和业务代码的耦合性比较高.可维护性也不强,易读性更差,更多的时候是使用 ...

最新文章

  1. 2009下半年网络管理员试题及答案
  2. java 过滤文件名_Java FileNameFilter过滤文件名
  3. Ribbon源码解析(二)
  4. 一致性环Hash算法.NET实现
  5. Avalonia跨平台入门第十三篇之Expander控件
  6. CF1067E Random Forest Rank(树形dp,概率与期望,线性代数)
  7. Android学习系列(15)--App列表之游标ListView(索引ListView)
  8. IntelliJ IDEA中Maven项目的默认JDK版本
  9. 深度学习笔记_基本概念_神经网络中的epoch、batch_size和iteration
  10. 云服务器操作系统新手,云服务器操作系统新手
  11. maven集成tomcat7
  12. [破解] nasca drm file -ver1.00
  13. [转]word只能用安全模式才能打开怎么解决
  14. 面部表情识别---学习笔记
  15. GB2312 编码(转)
  16. 炒鸡详细的windows安装python教程
  17. JavaScript中let的用法
  18. 1032 挖掘机技术哪家强 (20 分)
  19. 刷题总结——regular words(hdu1502 dp+高精度加法+压位)
  20. 我的奇思妙想机器人消防员_我是小小消防员~来啊~斗图啊~看一场奇思妙想SHOW!...

热门文章

  1. flow使用_使用Microsoft Flow进行文本分析
  2. CF1042D Petya and Array
  3. 【工具相关】Web-Sublime Text2的用法(一)
  4. jsp 运用 session 登录输出
  5. 理解Android安全机制
  6. Updatepanel 注册javascript 方法
  7. Struts2 标签库讲解
  8. MVC添加控制器时提示无法检索“MyContosoUniversity.Models.Student”的元数据
  9. Form验证之简单应用
  10. twisted学习资料