Log4Net记录日志到数据库启动24小时后将无法向mysql数据库插入数据

2023-05-16

最近用Log4Net做成服务把日志记录到MySql数据库可是发现可以个奇怪的的问题,每过一个晚上Log4Net就不会自动向MySql数据库记录日志,后来经过多方面测试发现这个问题主要是Mysql会把空闲8小时(wait_timeout默认值为28800秒)没有操作的数据库连接给主动断开,由于晚上没有操作造成log4net长时间没有记录日志,mysql把数据库连接断开了,到第二天白天开始写日志时由于数据库连接状态部位打开状态而被跳过了记录操作,

在github上下载了log4net的源码发现有一个“ReconnectOnError”的参数意图是在数据库连接异常时是否重新连接,在构造函数中设置了默认值为false错误不重连

解决方案:

方案1、把mysql的wait_timeout设置长一些具体多长根据自己实际需求;
方案2、在log4net的配置文件中添加一行“<param name="ReconnectOnError" value="true"/>”
方案3、下log4net载源码修改掉ReconnectOnError的默认值;

AdoNetAppender代码片段:

public class AdoNetAppender : BufferingAppenderSkeleton
{
    #region Public Instance Constructors

    /// <summary> 
    /// Initializes a new instance of the <see cref="AdoNetAppender" /> class.
    /// </summary>
    /// <remarks>
    /// Public default constructor to initialize a new instance of this class.
    /// </remarks>
    public AdoNetAppender()
    {
        m_connectionType = "System.Data.OleDb.OleDbConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089";
        m_useTransactions = true;
        m_commandType = System.Data.CommandType.Text;
        m_parameters = new ArrayList();
        m_reconnectOnError = false;
    }

    private bool m_reconnectOnError;
……
    public bool ReconnectOnError
    {
        get { return m_reconnectOnError; }
        set { m_reconnectOnError = value; }
    }
……
    override protected void SendBuffer(LoggingEvent[] events)
    {
        if (m_reconnectOnError && (m_dbConnection == null || m_dbConnection.State != ConnectionState.Open))
        {
            LogLog.Debug(declaringType, "Attempting to reconnect to database. Current Connection State: " + ((m_dbConnection==null)?SystemInfo.NullText:m_dbConnection.State.ToString()) );

            InitializeDatabaseConnection();
            InitializeDatabaseCommand();
        }

        // Check that the connection exists and is open
        if (m_dbConnection != null && m_dbConnection.State == ConnectionState.Open)
        {
            if (m_useTransactions)
            {
                // Create transaction
                // NJC - Do this on 2 lines because it can confuse the debugger
                IDbTransaction dbTran = null;
                try
                {
                    dbTran = m_dbConnection.BeginTransaction();

                    SendBuffer(dbTran, events);

                    // commit transaction
                    dbTran.Commit();
                }
                catch(Exception ex)
                {
                    // rollback the transaction
                    if (dbTran != null)
                    {
                        try
                        {
                            dbTran.Rollback();
                        }
                        catch(Exception)
                        {
                            // Ignore exception
                        }
                    }

                    // Can't insert into the database. That's a bad thing
                    ErrorHandler.Error("Exception while writing to database", ex);
                }
            }
            else
            {
                // Send without transaction
                SendBuffer(null, events);
            }
        }
    }
}




Log4Net配置文件:

<?xml version="1.0"?>
<configuration>
  <configSections>
    <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
  </configSections>
  <log4net>
    <appender name="AdoNetAppender_Error" type="log4net.Appender.AdoNetAppender">
      <!--BufferSize为缓冲区大小-->
      <bufferSize value="10" />
      <!--指定数据库类型-->
      <param name="ConnectionType" value="MySql.Data.MySqlClient.MySqlConnection, MySql.Data"/>
      <!--数据库连接字符串 -->
      <param name="ConnectionString" value="Server=127.0.0.1;Port=3306;Database=test;Uid=root;Pwd=;CharSet=utf8;"/>
      <!--数据库连接错误时重新连接 -->	  
	  <param name="ReconnectOnError" value="true"/>
      <!--INSERT 语句-->
      <commandText value="INSERT INTO sys_error_log (Date,Thread,Level,Logger,Message,Exception,GUID,OperateUID) VALUES (@LogDate, @thread, @LogLevel, @Logger, @Message, @Exception, @GUID, @OperateUID)" />

      <parameter>
        <parameterName value="@LogDate" />
        <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="@LogLevel" />
        <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="8000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@Exception" />
        <dbType value="String" />
        <size value="8000" />
        <layout type="log4net.Layout.ExceptionLayout" />
      </parameter>
      <parameter>
        <parameterName value="@GUID" />
        <dbType value="String" />
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%property{GUID}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@OperateUID" />
        <dbType value="Int64" />
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%property{OperateUID}" />
        </layout>
      </parameter>


    </appender>

    <!--写文本-->
    <appender name="RollingLogFileAppender_Error" type="log4net.Appender.RollingFileAppender">
      <!--日志文件路径-->
      <param name="File" value="ErrorLog\\" />
      <!--多线程时采用最小锁定-->
      <param name="lockingModel"  type="log4net.Appender.FileAppender+MinimalLock" />
      <!--是否追加到文件,默认为true,通常无需设置-->
      <param name="AppendToFile" value="true" />
      <!--日志文件名是否为静态:true,当前最新日志文件名永远为File节中的名字;false,File+DatePattern-->
      <param name="StaticLogFileName" value="false" />
      <!--日期的格式,每天换一个文件记录,如不设置则永远只记录一天的日志,需设置-->
      <param name="DatePattern" value="yyyy-MM-dd.LOG" />
      <!--变换的形式为日期,这种情况下每天只有一个日志-->
      <!--此时MaxSizeRollBackups和maximumFileSize的节点设置没有意义-->
      <param name="RollingStyle" value="Date" />
      <!--变换的形式为日志大小-->
      <!--这种情况下MaxSizeRollBackups和maximumFileSize的节点设置才有意义-->
      <!--<param name="RollingStyle" value="Size" />-->
      <!--每天记录的日志文件个数,与maximumFileSize配合使用-->
      <!--<param name="MaxSizeRollBackups" value="200" />-->
      <!--每个日志文件的最大大小-->
      <!--可用的单位:KB|MB|GB-->
      <!--不要使用小数,否则会一直写入当前日志-->
      <!--<param name="MaximumFileSize" value="10MB" />-->
      <!--自定义属性-->
      <parameter>
        <parameterName value="@GUID" />
        <dbType value="String" />
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%property{GUID}" />
        </layout>
      </parameter>
      <parameter>
        <parameterName value="@OperateUID" />
        <dbType value="Int64" />
        <layout type="log4net.Layout.PatternLayout">
          <param name="ConversionPattern" value="%property{OperateUID}" />
        </layout>
      </parameter>

      <!--%m(message):输出的日志消息,如ILog.Debug(…)输出的一条消息
      %n(new line):换行
      %d(datetime):输出当前语句运行的时刻
      %r(run time):输出程序从运行到执行到当前语句时消耗的毫秒数
      %t(thread id):当前语句所在的线程ID
      %p(priority): 日志的当前优先级别,即DEBUG、INFO、WARN…等
      %c(class):当前日志对象的名称,例如:
      %f(file):输出语句所在的文件名。
      %l(line):输出语句所在的行号。-->

      <!--日志格式-->
      <layout type="log4net.Layout.PatternLayout">
        <param name="Header" value="
LogDate		Thread		LogLevel		Logger		GUID		OperateUID		Message		Exception
" />
        <param name="Footer" value="
----------------------footer--------------------------
" />
        <param name="ConversionPattern" value="%d   %t    %p    %c    %property{GUID}   %property{OperateUID}   %m%n" />
      </layout>
    </appender>
   
    <logger name="DbErrorLogger">
      <level value="ALL" />
      <appender-ref ref="AdoNetAppender_Error" />
    </logger>
    <logger name="TextErrorLogger">
      <level value="ALL" />
      <appender-ref ref="RollingLogFileAppender_Error" />
    </logger>
  </log4net>
</configuration>


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Log4Net记录日志到数据库启动24小时后将无法向mysql数据库插入数据 的相关文章

  • 443https-公网证书nginx-freessl

    keymanage 生成证书 教程文档 freessl freessl cn acme sh帮助文档 主机记录 acme challenge 记录类型 CNAME 记录值 i7tdkyba41nr7ryod9hr dcv2 httpsaut
  • go基础语法

    基础语法 参考 log 日志 配置基础库参考 zap 日志 zap配置参考 go get u go uber org zap gin 日志 zap 生成 traceid gorm 空指针报错 传递指针地址 结果传递了值报错 reflect
  • 构建监控系统-2-zabbix开发

    参考 zabbix6官网自动发现 zabbix官网 agent监控项说明 go请求zabbix封装参考 ant design pro 前端构建 gin 官方文档 zabbix6 0接口官方文档 zabbix 各表开发介绍 zabbix we
  • 读取文件报错'utf-8' codec can't decode byte 0xb2 in position 49: invalid start byte

    python open打开文件报错 utf 8 codec can t decode byte 0xb2 in position 49 invalid start byte 解决方法 xff1a 1 操作字符为xb2 2 手动查看csv文件
  • python 技术大杂烩

    20230204 python升级报错 pip3 install span class token operator span U pip Could span class token keyword not span fetch URL
  • python 页面点击事件实现selenium

    pip install selenium coding 61 utf 8 from selenium import webdriver driver 61 webdriver Chrome driver maximize window dr
  • python 2.7 连接mysql

    sudo pip install MySQL python import xlrd import MySQLdb cursors conn 61 MySQLdb connect host 61 39 ip 39 user 61 39 use
  • 搭建react antd

    npm install g antd npm WARN antd 64 3 10 8 requires a peer of react 64 gt 61 16 0 0 but none is installed You must insta
  • UCF101和HMDB51数据集的处理 for Human Action Recognition

    数据集简介 xff1a 一 数据集获取 xff1a 1 UCF 101 http crcv ucf edu data UCF101 UCF101 rar 此外 xff0c 该数据集由于超过4G了无法上传百度云 xff0c 所以还在自己移动硬
  • 各种rtos(实时操作系统)比较

    RTOS在国内主要有vxworks和pSOS 现在还有nuclear QNX WinCE 说起好坏吗 其实 vxWorks要好一些 可能 不知道以前国内研究所一直用的VRTX是不是都被vxworks所替代了呢 据说因为VRTX是最早商业化的
  • 使用docker开启和停止一个容器

    我在网上看教程的时候 xff0c 使用docker开启一个容器用的是run命令 xff0c 这里有一个小坑 比如我用run开启了一个mysql xff0c 然后下次还用run开启的话 xff0c 实际上会生成两个mysql容器 正确的做法是
  • 使用python求一次函数和三角函数的交点并画图

    由于一些物理计算的需要 xff0c 我要用电脑将一个一次函数和一个三角函数 xff08 cotan xff09 的图像和交点画出来 本例程使用到的库 xff1a numpy 强大的科学计算库 matlibplot python绘图库 ran
  • 将MyEclipse的配色方案还原到最初的状态(主题还原)

    我的MyEclipse中导入了主题 xff0c 但是现在不想用那种花花绿绿的配色了 xff08 眼睛有点累 xff09 但是想还原却比较麻烦 xff0c 目前有三种方法吧 xff1a 1 xff1a 更换workspace 这种方法需要你重
  • 自己写的一个数组与list转化工具,请大神指正问题

    话不多说上代码 public class ListUtil public static void main String args List lt Integer gt lst1 61 new ArrayList lt Integer gt
  • Python学习记录-----批量发送post请求

    昨天学了一天的Python xff08 我的生产语言是java xff0c 也可以写一些shell脚本 xff0c 算有一点点基础 xff09 xff0c 今天有一个应用场景 xff0c 就正好练手了 这个功能之前再java里写过 xff0
  • 找不到系统安全日志/var/log/secure文件的问题

    今天打算配置一个服务器防止暴力破解的脚本 xff0c 原理不复杂 xff0c 搜索登录错误超过一定次数的ip地址 xff0c 加入防火墙 xff0c 但是在找登录日志的时候出现了问题 一般服务器的ssh登录等操作日志都是 var log s
  • osx多用户设置共享文件夹(MacBook)

    mac平台有很方便的多用户系统 xff08 Unix你懂的 xff09 我本人就一直在使用两个账户 xff0c 各有分工 xff0c 权限不同 有时候我们在一个账户下下载或者使用的文件 xff0c 也需要在另一个账户上使用 xff0c 这就
  • MySQL DROP TABLE操作以及 DROP 大表时的注意事项

    语法 xff1a 删表 sql view plain copy DROP TABLE Syntax DROP TEMPORARY TABLE IF EXISTS tbl name tbl name RESTRICT CASCADE 可一次删
  • python日期操作类

    coding utf 8 39 39 39 获取当前日期前后N天或N月的日期 39 39 39 from time import strftime localtime from datetime import timedelta date
  • ROS运行调用摄像头无法显示的解决办法

    报错 xff1a Unable to open camera calibration file home hri ros camera info head camera yaml 参考 xff1a https github com ros

随机推荐

  • [VC] 冒号(:)与C/C++

    这篇文章将总结C C 43 43 中的冒号的用法 1 位域定义 是C 43 43 里的 作用域分解运算符 比如声明了一个类A xff0c 类A里声明了一个成员函数voidf xff0c 但没有在类的声明里给出f的定义 xff0c 那么在类外
  • TX2入门(1)——开箱上电

    因为实验室有需求 导师购入了一块Jetson TX2开发板 下面就记录一下板子在我手机的应用过程 xff0c 方便以后查找 xff0c 如果也能给大家一些帮助就更好啦 欢迎转载 1 已经提前按照网上各种大神的意见采购好了电源线 HDMI转V
  • TX2入门(3)——ubuntu(包含tx2端)常用命令(持续补充中……)

    emmm xff0c 刷机完成 xff0c 突然发现还有一些常用指令需要整理一下 xff0c 以后查找起来方便 所以 xff0c tensorflow放到下一篇吧 一 系统架构类型 1 查看系统架构 uname a 2 显示操作系统架构类型
  • 使用 sphinx 制作简洁而又美观的文档

    Sphinx 是一种工具 xff0c 它允许开发人员以纯文本格式编写文档 xff0c 以便采用满足不同需求的格式轻松生成输出 这在使用 Version Control System 追踪变更时非常有用 纯文本文档对不同系统之间的协作者也非常
  • 关于C语言的空格符和字符串结束符

    空格 39 39 和结束符 39 0 39 是不一样的 xff0c 但是如果用scanf函数 s的格式输入 xff0c 遇到空格符就会当成结束符
  • 查看Jetson系列产品JetPack的版本信息

    想查看 JetPack 的版本信息 xff0c 网上搜了一下都是要查看 etc nv tegra release 也没说该怎么看和什么意思 图片链接 https www jianshu com p 7f2d8a563ded 查了一下 xff
  • docker run 参数详解

    命令格式 xff1a docker run OPTIONS IMAGE COMMAND ARG Usage Run a command in a new container 中文意思为 xff1a 通过run命令创建一个新的容器 xff08
  • Docker安装Minio

    寻找Minio镜像 Docker Hub 查找官方镜像 下载Minio镜像 下载最新版Minio镜像 span class token function docker span pull minio minio 等同于 span class
  • Docker安装Nginx

    寻找Nginx镜像 Docker Hub 查找官方镜像 下载Nginx镜像 下载最新版Nginx镜像 span class token function docker span pull nginx 等同于 span class token
  • Docker安装pgAdmin4

    寻找Redis镜像 Docker Hub 查找官方镜像 下载Redis镜像 下载最新版pgAdmin4镜像 span class token function docker span pull dpage pgadmin4 等同于 span
  • SQLServer跨库查询--分布式查询 用openrowset连接远程SQL或插入数据

    如果只是临时访问 可以直接用openrowset 查询示例 select from openrowset SQLOLEDB sql服务器名 用户名 密码 数据库名 dbo 表名 导入示例 select into 表 from openrow
  • ubuntu20 编译dpdk错误 -Werror=address-of-packed-member

    0x0 在ubuntu20上编译dpdk 18 11报错 xff0c gcc 版本为9 3 0 xff0c 报错如下 xff1a error converting a packed const struct ether addr point
  • Docker安装EMQX

    寻找EMQX镜像 Docker Hub 查找官方镜像 下载EMQX镜像 下载最新版EMQX镜像 span class token function docker span pull emqx emqx 等同于 span class toke
  • Aspose.Cells中文版文档

    Aspose Cells相应操作 1 上传 1 1 Workbook Workbook workBook 61 new Workbook 属性 名称 值类型 说明 Colors Color 获取或设置Excel颜色 ConvertNumer
  • expdp/impdp 详细参数解释

    数据泵导出实用程序提供了一种用于在 Oracle 数据库之间传输 数据对象的机制 该实用程序可以使用以下命令进行调用 示例 expdp scott tiger DIRECTORY 61 dmpdir DUMPFILE 61 scott dm
  • MSDN,我告诉你

    VS MSSQL Windows Windows Server等下载地址均为电骡下载地址 http msdn itellyou cn
  • ASP.NET MVC 4 插件化架构简单实现-思路篇

    用过和做过插件的都会了解插件的好处 xff0c 园子里也有很多和讨论 xff0c 但大都只些简单的加载程序集什么的 xff0c 这里主要讨论的就是使用 ASP NET MVC 4 来实现每个插件都可以完全从主站点剥离出来 xff0c 即使只
  • Quartz.NET 2.0 学习笔记(4) :cron表达式

    Quartz NET 项目地址 http quartznet sourceforge net Quartz NET 2 0 学习笔记 1 xff1a Quartz NET简介 Quartz NET 2 0 学习笔记 2 xff1a 和1 0
  • 修改oracle用户密码永不过期

    1 以在SQL Plus下以DBA身份登陆 用户名 密码 64 服务器SID as sysdba 方法一 xff1a xff08 注意必须用双引号把后面的引上 xff09 C Documents and Settings ssy gt sq
  • Log4Net记录日志到数据库启动24小时后将无法向mysql数据库插入数据

    最近用Log4Net做成服务把日志记录到MySql数据库可是发现可以个奇怪的的问题 xff0c 每过一个晚上Log4Net就不会自动向MySql 数据库记录日志 xff0c 后来经过多方面测试发现 这个问题主要是Mysql会把空闲8小时 x