当前位置: 代码网 > it编程>编程语言>Asp.net > C#使用log4net结合sqlite数据库实现记录日志

C#使用log4net结合sqlite数据库实现记录日志

2024年10月28日 Asp.net 我要评论
0 前言为什么要把日志存到数据库里?因为结构化的数据库存储的日志信息,可以写专门的软件读取历史日志信息,通过各种条件筛选,可操作性极大增强,有这方面需求的开发人员可以考虑。为什么选择sqlite?轻量

0 前言

为什么要把日志存到数据库里?

因为结构化的数据库存储的日志信息,可以写专门的软件读取历史日志信息,通过各种条件筛选,可操作性极大增强,有这方面需求的开发人员可以考虑。

为什么选择sqlite?

轻量级数据库,免安装,数据库的常用的基本功能都有,可以随程序迁移到不同的电脑上使用。

1 安装包

两个包:

  • log4net
  • system.data.sqlite

第二个包也可以使用microsoft.data.sqlite,查到的资料显示如果环境使用的是 .net core 或 .net 5+,建议使用microsoft.data.sqlite。但是我并没有测试第二个包,可能使用上有区别。

2 下载sqlite

如果本地没有sqlite环境的话,需要先下载。官网下载链接

进去之后直接找各自环境对应的版本,如果是windows环境的话,直接下载下图中标记的tool,中间那个下载链接是下载sqlite3.dll,不过我并不清楚如何使用,有知道的大佬可以在评论区交流一下。

tool解压之后有如下几个文件,双击打开sqlite3.exe即可。

3 sqlite常用命令

打开是一个命令行界面,可以使用.help查看常用的命令及解释。

.help

创建数据库文件使用.open xxx,这条语句,如果发现数据库文件存在,就会直接打开,如果不存在,就会先创建再打开。

.open test.db

在目录内可以看到创建的数据库文件。(划重点,这个文件拷到程序中就可以直接使用sqlite数据库,充分体现了轻量级的魅力)

.databases可以查询所有数据库文件

.tables可以查询所有表(我还未创建,所以目前还没有表)

sql语句请自行查询相关资料。

查询的数据以标准格式显示。

.header on
.mode column
select * from company;

当然sqlite也有可视化的软件,但是我目前没用到,所以没有下载安装,需要的话可以自行查询。

4 创建日志相关基本表

使用命令创建日志表,包含id(使用自增,当然可以换成uuid或者其它形式)、日期、线程号、级别(info、error这些)、记录者、具体记录的信息、异常信息。具体内容要对应log4net的配置。

create table log (
  id integer primary key autoincrement,
  date datetime,
  thread varchar(255),
  level varchar(50),
  logger varchar(255),
  message text,
  exception text
);

5 log4net配置

更换数据库连接。sql语句的内容一定要对应数据库基本表的字段。

<configuration>
  <configsections>
    <section name="log4net" type="log4net.config.log4netconfigurationsectionhandler, log4net" />
  </configsections>

  <log4net>
    <appender name="adonetappender" type="log4net.appender.adonetappender">
      <buffersize value="1" />
      <connectiontype value="system.data.sqlite.sqliteconnection, system.data.sqlite" />
      <connectionstring value="data source=./database/logs.db;version=3;" />
      <commandtext value="insert into log (date, thread, level, logger, message, exception) values (@log_date, @thread, @log_level, @logger, @message, @exception)" />
      
      <parameter>
        <parametername value="@log_date" />
        <dbtype value="datetime" />
        <layout type="log4net.layout.rawtimestamplayout" />
      </parameter>
      <parameter>
        <parametername value="@thread" />
        <dbtype value="string" />
        <size value="255" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%thread" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@log_level" />
        <dbtype value="string" />
        <size value="50" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%level" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@logger" />
        <dbtype value="string" />
        <size value="255" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%logger" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@message" />
        <dbtype value="string" />
        <size value="4000" />
        <layout type="log4net.layout.patternlayout">
          <conversionpattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parametername value="@exception" />
        <dbtype value="string" />
        <size value="2000" />
        <layout type="log4net.layout.exceptionlayout" />
      </parameter>
    </appender>

    <root>
      <level value="all" />
      <appender-ref ref="adonetappender" />
    </root>
  </log4net>
</configuration>

6 日志记录

把生成的db文件拷到程序里,这个文件就是记录文件的数据库了,其它的都不重要。当然,如果想查看数据库的话,也可以把sqlite3.exe拷过来。

读取log4net的配置建议写在assemblyinfo.cs,这样程序启动时会默认加载配置文件。

//log4net配置[assembly: log4net.config.xmlconfigurator(configfile = "log4net.config", watch = true)]

具体程序如下:

private static readonly ilog log = logmanager.getlogger(typeof(form1));

log.info("这是一条info语句");
log.warn("这是一条warn语句");
log.error("这是一条错误语句", new exception("测试异常"));

查看日志是否正常写入数据库。

7 使用c#程序查询sqlite

程序如下(不过感觉getstring(index)这种方式有点别扭吧,有没有getstring(key)的这种形式,欢迎大佬们补充)

// 构建连接字符串
string connectionstring = "data source=./database/softwarebaselog.db;version=3;";

// 创建 sqlite 连接
using (var connection = new sqliteconnection(connectionstring))
{
    connection.open();

    // 创建 sql 命令
    string sql = "select message from log where level='error'";
    using (var command = new sqlitecommand(sql, connection))
    {
        // 执行命令并读取数据
        using (var reader = command.executereader())
        {
            while (reader.read())
            {
                string msg = reader.getstring(0);
                console.writeline(msg);
            }
        }
    }
}

8 实时显示日志

现在所有日志都写到数据库里了,那要是还想实时显示到界面上,当然也有很多方式实现,不过我这里建议实时显示可以使用log4net的自有功能。

比如我想使用winform中的listbox来实时显示日志,可以建立一个appender(附加),继承于log4net的appenderskeleton,这是一个抽象类,有一个抽象方法。

具体的,可以参考以下程序,这里会显示所有的日志,如果需要过滤的话,可以在这个基础上改。另外,一定一定一定要给this.layout赋值,这是日志在界面上的显示方式,如果没有写的话,就会收获一个报错:“a layout must be set”,去网上搜这条内容,不一定能找到解决方案。

public class listboxappender : appenderskeleton
{
    private listbox _listbox;

    public listboxappender(listbox box)
    {
        _listbox = box;
        this.layout = new patternlayout("%date [%thread] %-5level %logger - %message%newline");
    }

    protected override void append(loggingevent loggingevent)
    {
        // 获取日志信息
        string logmessage = renderloggingevent(loggingevent);

        // 更新 ui 控件
        if (_listbox.invokerequired)
        {
            _listbox.invoke(new action(() => appendtext(logmessage)));
        }
        else
        {
            appendtext(logmessage);
        }
    }

    private void appendtext(string text)
    {
        _listbox.items.add(text);
    }
}

只需要给log4net配置一次就可以使用,这样,每次调用日志记录,界面上的lbxlog控件就可以一直显示最新的日志信息。

// 添加自定义 appender
var listboxappender = new listboxappender(lbxlog);
log4net.config.basicconfigurator.configure(listboxappender);

但是,我并不建议使用log4net直接操作控件显示日志信息,在多线程短时间写较多日志的情况下,可能会导致软件卡死,更佳的方式是增加缓存机制。

以上就是c#使用log4net结合sqlite数据库实现记录日志的详细内容,更多关于c# log4net结合sqlite记录日志的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com