0

我正在尝试基于 log4net 库实现数据库记录器。我需要将我的日志写入 MySql 数据库。当我将一些硬编码值记录到我的日志表中时,一切都很好。当我尝试将至少一个参数传递给我的查询时,log4net 开始抱怨“准备期间未找到参数'@message'”。我发现了一个丑陋的解决方法,我实现了自己的 AdoNetAppender,并在其中将我的值传递给查询。但正如我所说,这是肮脏且不安全的解决方案。我想避免这种情况。我花了一整天的时间,我没有更多的想法如何以干净的方式解决它。

我的项目设置如下:Net Core 3.1、log4Net 2.0.12。

你知道为什么它不起作用吗?

先感谢您!

在我的代码下面:

namespace Application.Logging.Implementation
{
    public class DatabaseLogger : LoggerBase, Interfaces.ILogger
    {
        private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        public void LogDebug(string message, params object[] parameters)
        {
            _logger.Debug(buildLogMessage(message, parameters));
        }

        public void LogError(string message, params object[] parameters)
        {
            _logger.ErrorFormat(buildLogMessage(message, parameters));
        }

        public void LogInfo(string message, params object[] parameters)
        {
            _logger.InfoFormat(buildLogMessage(message, parameters));
        }

        protected override void configure()
        {
            AdoNetAppender dbAppender = new AdoNetAppender();
            dbAppender.BufferSize = 1;
            dbAppender.ConnectionString = "Server=<server_ip>;Database=<db_name>;Uid=<user_name>;Pwd=<password>;";
            dbAppender.ConnectionType = "MySql.Data.MySqlClient.MySqlConnection, MySql.Data";
            dbAppender.CommandType = System.Data.CommandType.Text;
            dbAppender.CommandText = "INSERT INTO LOG (LOG_DATE, LOG_LEVEL, LOG_MESSAGE) VALUES (Now(), 'DEBUG', @message)";
            dbAppender.ErrorHandler = new CustomErrorHandler();

            var dbParam = new AdoNetAppenderParameter
            {
                ParameterName = "@message",
                DbType = System.Data.DbType.String,
                Layout = (IRawLayout)new RawLayoutConverter().ConvertFrom(new PatternLayout('%message'))
            };

            dbAppender.AddParameter(dbParam);
            dbAppender.ActivateOptions();

            Hierarchy hierarchy = (Hierarchy)LogManager.GetRepository();
            hierarchy.Root.AddAppender(dbAppender);
            hierarchy.Root.Level = Level.All;
            hierarchy.Configured = true;

            log4net.Config.BasicConfigurator.Configure(hierarchy);
        }
    }
}


解决方法:我使用了一些预定义的字符串,而不是查询中的@message 参数,并将其替换为自己的 AdoNetAppenderParameter。我意识到它不能像这样工作......


namespace Application.Logging.Implementation
{
    public class MessageAdoNetAppenderParameter : AdoNetAppenderParameter
    {
        public UserAdoNetAppenderParameter()
        {
        }

        public override void Prepare(IDbCommand command)
        {
        }

        public override void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
        {
            var data = loggingEvent.RenderedMessage;
            command.CommandText = command.CommandText.Replace("'<message>'", $"'{data}'");
        }
    }
}


4

0 回答 0