问题描述
我正在使用 log4net 登录 MysqL 数据库。 log4net 配置是正确的,因为我已经测试登录 sql server 和文件,但是当我在 MysqL 数据库中写入日志时,它会提示我错误。
我的 log4net 配置如下
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<log4net>
<appender name="adonetappender" type="log4net.Appender.adonetappender">
<bufferSize value="1" />
<connectionType value="MysqL.Data.MysqLClient.MysqLConnection,MysqL.Data" />
<connectionString value="Server=127.0.0.1;Database=logdb;Uid=abc;Pwd=abc;" />
<commandText value="INSERT INTO log (timestamp,Thread,Level,Logger,Message) VALUES (?log_date,?thread,?log_level,?logger,?message);" />
<parameter>
<parameterName value="?log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.RawTimeStampLayout" />
</parameter>
<parameter>
<parameterName value="?thread" />
<dbType value="String" />
<size value="32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%thread" />
</layout>
</parameter>
<parameter>
<parameterName value="?log_level" />
<dbType value="String" />
<size value="32" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%level" />
</layout>
</parameter>
<parameter>
<parameterName value="?logger" />
<dbType value="String" />
<size value="256" />
<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>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="adonetappender" />
</root>
</log4net>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add name="textWriterTraceListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="C:\Logs\log4net.txt"/>
</listeners>
</trace>
</system.diagnostics>
</configuration>
class Program
{
private static readonly ILog Logger = LogManager.GetLogger(System.Environment.MachineName);
static void Main(string[] args)
{
log4net.Config.XmlConfigurator.Configure();
Logger.Info("Testing information log from .Net app");
Logger.Debug("Testing Debug log from .Net app");
Logger.Fatal("Testing Fatal log from .Net app");
}
}
我也是
“[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Web.config",Watch = true)]
”
汇编文件中的这一行。
我遇到的错误是
**
log4net:ERROR [adonetappender] ErrorCode: GenericFailure. Exception while writing to database
system.invalidOperationException: Parameter '?log_date' was not found during prepare.
at MysqL.Data.MysqLClient.PreparableStatement.Prepare()
at MysqL.Data.MysqLClient.MysqLCommand.Prepare(Int32 cursorPageSize)
at MysqL.Data.MysqLClient.MysqLCommand.Prepare()
at log4net.Appender.adonetappender.SendBuffer(IDbTransaction dbTran,LoggingEvent[] events)
at log4net.Appender.adonetappender.SendBuffer(LoggingEvent[] events)
log4net: Shutdown called on Hierarchy [log4net-default-repository]
**
但实际上我正在传递所有必需的参数,但不知道为什么会出现此错误。
任何人都可以指导。
解决方法
这是 MySql.Data 中的一个错误。据我所知,没有针对它提交的错误报告,但是您可以从 MySqlConnector integration tests 中看到,如果在添加参数之前调用 MySqlCommand.Prepare
,MySql.Data 会失败。
然而,这正是 what AdoNetAppender
does。 (该代码中有一个 try
/catch
块,但这是 2.0.12 之后的最新更改。)
有两种可能的修复:
- 切换到 MySqlConnector 并更改
<connectionType />
以使用它。 - 将
IgnorePrepare=true
添加到您的 MySql.Data 连接字符串,这将导致Prepare
成为空操作。
正如@Bradley Grainger 提到的,MySqlConnector 完成了这项工作
遗憾的是,我无法发表评论,但@hashimkayani 要求举个例子,我确实试过了,而且效果很好:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
</configSections>
<appSettings>
<add key="log4net.Internal.Debug" value="true"/>
</appSettings>
<log4net>
<appender name="dbAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="MySqlConnector.MySqlConnection,MySqlConnector" />
<connectionString value="Server=localhost;Database=dbName;Uid=dbUser;Pwd=dbPassword;persistsecurityinfo=True;SslMode=none;" />
<commandText value="INSERT INTO afmlog(date,thread,level,logger,message) VALUES (@log_date,@thread,@log_level,@logger,@message);" />
<parameter>
<parameterName value="@log_date" />
<dbType value="DateTime" />
<layout type="log4net.Layout.PatternLayout" value="%date{yyyy'-'MM'-'dd HH':'mm':'ss'.'fff}" />
</parameter>
<parameter>
<parameterName value="@thread" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout" value="%thread" />
</parameter>
<parameter>
<parameterName value="@log_level" />
<dbType value="String" />
<size value="50" />
<layout type="log4net.Layout.PatternLayout" value="%level" />
</parameter>
<parameter>
<parameterName value="@logger" />
<dbType value="String" />
<size value="255" />
<layout type="log4net.Layout.PatternLayout" value="%logger" />
</parameter>
<parameter>
<parameterName value="@message" />
<dbType value="String" />
<size value="4000" />
<layout type="log4net.Layout.PatternLayout" value="%message" />
</parameter>
</appender>
</log4net>
<system.diagnostics>
<trace autoflush="true">
<listeners>
<add
name="textWriterTraceListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="C:\temp\log4net.txt" />
</listeners>
</trace>
</system.diagnostics>
</configuration>