Log4Net似乎连接到数据库但不是Insert

时间:2017-07-27 19:11:40

标签: c# iis log4net log4net-configuration log4net-appender

我打开了调试,所以我很确定它正在连接到数据库。我这样说是因为如果我拼错了数据库名称,它会输出一个错误。

我不确定我做错了什么。我知道我还没有使用参数。

我所做的是将this tutorial改编成一个项目。如果您需要了解更多信息,请告知我们。

Log4Net.config

<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
  <root>
    <level value="ALL"/>
    <appender-ref ref="AdoNetAppender"/>
    <appender-ref ref="DebugAppender"/>
  </root>
  <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
  <bufferSize value="1" />
  <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <connectionString value="Data Source=server;Initial Catalog=db; User Id=user; Password=pass" />
  <commandText value="INSERT INTO LogException ([LogLevel],[LogMessage],[StackTrace],[Object],[CreateDateTime]) VALUES (@log_level, @message, @stacktrace, @exception, @date)" />
    <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>
    <parameter>
      <parameterName value="@entryAssembly" />
      <dbType value="String" />
      <size value="200" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{entryAssembly}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@callingAssembly" />
      <dbType value="String" />
      <size value="200" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{callingAssembly}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@method" />
      <dbType value="String" />
      <size value="2000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{method}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@stacktrace" />
      <dbType value="String" />
      <size value="2000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%stacktrace" />
      </layout>
    </parameter>
  </appender>
</log4net>

Log4netLoggingService.cs

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Logging.Contracts.Log;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Filter;
using log4net.Util;


namespace Logging
{
    public class Log4NetLoggingService : ILoggingService
    {
        private readonly ILog _logger;

        static Log4NetLoggingService()
        {
            var log4NetConfigFilePath = @"C:\Work\folder\Main\Logging\Log4Net.config";

            XmlConfigurator.ConfigureAndWatch(new FileInfo(log4NetConfigFilePath));

        }

        //targets reads from and enum to know where to save.
        public Log4NetLoggingService(LogTarget targets = LogTarget.All)
        {
            _logger = LogManager.GetLogger(new StackFrame(1).GetMethod().DeclaringType);
#if DEBUG
            var error = LogManager.GetRepository().ConfigurationMessages.Cast<LogLog>();
#endif

            if (targets.HasFlag(LogTarget.All))
                return;

            SwitchOffLogTargets(targets);
        }

        protected ILog logger { get { return _logger; } }

        public void Fatal(ErrorLogEntry logEntry)
        {
            logEntry.Level = Level.Fatal.ToString();
            if (_logger.IsFatalEnabled)
                _logger.Fatal(logEntry);
        }

        public void Error(ErrorLogEntry logEntry)
        {
            logEntry.Level = Level.Error.ToString();
            if (_logger.IsErrorEnabled)
                _logger.Error(logEntry);
        }

        public void Warn(LogEntry logEntry)
        {
            logEntry.Level = Level.Warn.ToString();
            if (_logger.IsWarnEnabled)
                _logger.Warn(logEntry);
        }

        public void Info(LogEntry logEntry)
        {
            logEntry.Level = Level.Info.ToString();
            if (_logger.IsInfoEnabled)
                _logger.Info(logEntry);
        }

        public void Debug(LogEntry logEntry)
        {
            logEntry.Level = Level.Debug.ToString();
            if (_logger.IsDebugEnabled)
                _logger.Debug(logEntry);
        }

        private void SwitchOffLogTargets(LogTarget targets)
        {
            var appenders = _logger.Logger.Repository.GetAppenders().ToList();

            if (!targets.HasFlag(LogTarget.Database))
            {
                var db = appenders.FirstOrDefault(piA => piA is AdoNetAppender);
                if (db != null)
                    ((AdoNetAppender)db).AddFilter(new DenyAllFilter());
            }

            if (!targets.HasFlag(LogTarget.TextFile))
            {
                var file = appenders.FirstOrDefault(piA => piA is RollingFileAppender);
                if (file != null)
                    ((RollingFileAppender)file).AddFilter(new DenyAllFilter());
            }

            if (!targets.HasFlag(LogTarget.Trace))
            {
                var trace = appenders.FirstOrDefault(piA => piA is AspNetTraceAppender);
                if (trace != null)
                    ((AspNetTraceAppender)trace).AddFilter(new DenyAllFilter());
            }

        }
    }
}

更新

事实证明我的最新尝试有效。我刚拼错了配置文件名。我希望这可以帮助将来的某个人。我打算写一篇关于此事的博客文章。

Log4Net.config

<?xml version="1.0" encoding="utf-8" ?>
<log4net>
  <root>
    <level value="ALL" debug="true"/>
    <!--Add the appenders you want to use here-->
    <appender-ref ref="AdoNetAppender"/>
    <!--to debug log4net. check the output window of Visual Studio-->
    <appender-ref ref="DebugAppender"/>
  </root>
  <appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
    <bufferSize value="1" />
    <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
    <connectionString value="data source=(localdb)\MSSQLLocalDB;initial catalog=log4NetTestDB;integrated security=false;persist security info=True;" />
    <commandText value="INSERT INTO LogException ([Message]) VALUES (@message)" />
      <parameter>
        <parameterName value="@message" />
        <dbType value="String" />
        <size value="4000" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%message" />
        </layout>
      </parameter>
  </appender>
</log4net>

ILoggingAdapter

namespace Logging
{
    public interface ILoggingAdapter
    {
        TimeSpan ExecutionTime { get; set; }
        int Counter { get; set; }
        void Info(string message);
        void Warn(string message);

    }
}

日志

namespace Logging
{
    public sealed class Logger : ILoggingAdapter
    {
        private ILog _log = LogManager.GetLogger(typeof(Logger));

        public TimeSpan ExecutionTime { get; set; }
        public int Counter { get; set; }
        public string Info { get; set; }
        public string Warn { get; set; }


        void ILoggingAdapter.Info(string message)
        {
            throw new NotImplementedException();
        }

        void ILoggingAdapter.Warn(string message)
        {
            _log.Warn(message);
        }
    }
}

1 个答案:

答案 0 :(得分:3)

好几个音符

  • 您是否尝试以指定用户身份登录数据库并运行所需的插入查询?
  • 您是否在log4net中尝试了enabling debug mode以了解最新情况?
  • 与上述相关,在根目录下使用两个记录器 - 一个用于db,另一个用于文件。仅使用数据库日志记录是一个可怕的想法,因为如果数据库失败,您将无法获得有关它失败的日志。至少,您的本地开发环境应该记录到文件
  • beefycoder has written a ton about understanding log4net请注意该教程的许多部分
  • 我不知道为什么你会做if (_logger.IsInfoEnabled)这样的事情 - 那就是
  • 为什么你要将LogInfo作为参数类型?使用像这样的服务类的全部意义在于打破对log4net的硬依赖。通过使用该类类型,您只是在消费者中创建了对log4net的硬依赖。只是传入字符串。同样,你不会需要整个LogEntry无意义的
  • 文件中的硬编码路径字符串。现在,这将不适用于其他开发人员的计算机。
  • 在构造函数中进行堆栈检查 - 您现在已经显着减慢了使用它的任何类的构建速度,在内置RELEASE模式且启用了内联时,它将为您提供不同的结果。不要使用服务类,只需创建一个扩展方法,或者将您希望记录器来源的对象作为执行相同操作的参数传递。
  • 您的代码配置会覆盖xml配置(我认为... log4net&#39的优先顺序规则是模糊的 - 这就是我更喜欢NLog的重要原因)
  • logEntry.Level = Level.Warn.ToString();为什么!?如果您想要这种行为,只需更改配置文件即可。配置文件可以定义它想要的任何目标并随时更改,但是在这里你只是假设它恰好有某些东西。