【问题标题】:AdoNetAppender stops working after changes are made进行更改后,AdoNetAppender 停止工作
【发布时间】:2011-03-12 15:27:54
【问题描述】:

我正在使用 log4net,并且我将我的 XML 文件配置为使用 AdoNetAppender 登录到数据库,当我创建应用程序并配置所有内容时,一切似乎都正常工作。我可以成功登录到数据库。但是当我更改代码中的消息时,它会停止记录到数据库。

这是我的配置:

<appender name="ADONetAppender" type="log4net.Appender.ADONetAppender">
  <bufferSize value="0" />
  <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  <connectionString value="Server=USER-PC;Integrated Security=SSPI;Initial Catalog=mydb;Trusted_Connection=true;"/>
  <commandText value="INSERT INTO Log1 ([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">
      <converter>
        <name value="hex_thread" />
        <type value="MyWebApplication.HexPatternConverter" />
      </converter>
      <conversionPattern value="%hex_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>

我在网上找到了它并做了一些修改以适合我的应用程序。我想这可能是因为我们在获取参数之前插入了表 Log1 可能我真的不知道,因为我是 XML 世界的新手,我对此知之甚少。

如果我的代码是

 private static readonly ILog dblog = LogManager.GetLogger("ADONetAppender");
 dblog.Info("logging to db");

它第一次工作,然后我像这样更改消息

dblog.Info("I AM LOGGING TO DB"); 
dblog.Info("me again");

它根本不起作用,我的文件附加程序很好,他们可以接受消息更改,但我的 AdoNetAppender 拒绝了。为什么会这样?

编辑添加:

我的功能很简单,我有这个类来做日志记录:

using System; 
using System.Collections.Generic; 
using System.Linq; using System.Web;using log4net; 
using log4net.Config; using log4net.Core;
using log4net.Layout; using System.Text; 
using System.IO; 
using log4net.Layout.Pattern; 

namespace myWebApplication 
{

public sealed class HexPatternConverter : PatternLayoutConverter
{
    override protected void Convert(TextWriter writer, LoggingEvent loggingEvent)
    {
        long id;
        if (long.TryParse(loggingEvent.ThreadName, out id))
        {
            writer.Write(id.ToString("X"));
        }
        else
        {
            writer.Write(loggingEvent.ThreadName);
        }
    }
}

public class myClass
{
    private static readonly ILog secondlog = LogManager.GetLogger("methodB");
    private static readonly ILog thirdlog = LogManager.GetLogger("methodC");
    private static readonly ILog fourthlog = LogManager.GetLogger("methodD");
    private static readonly ILog fifthlog = LogManager.GetLogger("ADONetAppender");

    public static int methodA()
    {
        int a = 0;
        return a;
    }
    public static void methodB()
    {
        methodA();
        secondlog.Info("inside method B");
    }
    public static void methodC()
    {
        methodB();
        thirdlog.Info("inside method C");
    }

    public static void methodD()
    {
        methodC();
        fourthlog.Info("inside D");
        fifthlog.Info("this is db log");
        fifthlog.Info("this is me logging to the db");
    }
}

}

只要我进行更改,文件日志就可以了,但我的数据库日志没有写入数据库,因为当我尝试检索表中的数据时,没有任何更改。我不确定我做错了什么。

我的记录器配置

<logger name="ADONetAppender">
<appender-ref ref="ADONetAppender"/>
</logger>
<logger name="methodB">
  <appender-ref ref="methodB"/>
</logger>
<logger name="methodC">
  <appender-ref ref="methodC"/>
</logger>
<logger name="methodD">
  <appender-ref ref="methodD"/>
</logger>
<root>     
</root>

最后三个是RollingFileAppenders,无论我更改消息还是添加一些其他消息,它们都可以正常工作。当我更改消息或向日志中添加更多消息时,让我头疼的是数据库。

【问题讨论】:

  • 如何在配置中配置记录器?
  • 我刚刚编辑添加了记录器...请看.....

标签: c# .net log4net adonetappender


【解决方案1】:

首先:将缓冲区大小改为 1,而不是 0。

第二:如果第一条日志消息有效,那么您的配置文件就可以了。它可能在您的其余代码中,向我们展示更多。

如果它很复杂,请使用一两个非常简单的函数进行测试,然后告诉我们会发生什么。

编辑添加

好的,我看到了您的代码,现在我看到 HexPatternConverter 正在用于格式化一列:所以那里可能出现了问题,例如抛出异常。我建议您尝试在不使用该类的情况下运行它(只需将 Thread 列写为纯字符串),看看是否有任何改变。

另外,以防万一您不知道:如果 log4net 遇到 SQL 问题,它将默默地失败。在这种情况下,这似乎不太可能,因为它至少会写入几条记录,但仍然如此。

编辑添加

当您更改配置文件时,IIS 会重新加载整个应用程序,因此您可能正在耗尽资源。您有其他数据库活动吗?它也停止了吗?您是否有可能打开数据库连接并忘记关闭它们?这将导致 db 活动失败,直到应用重新启动。

编辑添加

配置文件中的 ConnectionString 不会打开连接,它只是您的程序(或在本例中为 log4net)知道查看的地方。如果您除了 log4net 之外没有进行任何数据库活动,那么它可能不是连接问题。

接下来要尝试:log4net 的文本文件 Appender 有这个问题吗?

【讨论】:

  • 查看我复制了我的课程代码。我作为答案发布,因为我不知道如何将代码添加到评论中。请帮我查一下!
  • 我将您的代码移到了问题中——您可以通过单击“编辑”来执行此操作。也请参阅我的回复。
  • 该类将 threadID 转换为十六进制。但这不是问题的一部分,因为它工作正常。我只是包括显示整个代码。也许如果它的偶码排列错误。
  • log.Info 工作时工作正常; log.Info fails 时你不知道它是否正常工作。
  • 不,我不知道。除了现在,每当我更改代码并添加几行代码时,它都不会响应,但是当我将缓冲区大小更改为 1 一次,下一次更改为 0 时,它会返回并显示记录在数据库中的其他消息.我搜索了一下,发现缓冲区在写入之前保存了数据,这可能就是问题所在。我只是在缓冲区没有记录到数据库时不断更改缓冲区,但我希望我能理解为什么我需要不断更改配置文件。
【解决方案2】:

OOH 最后,它运行良好...我的 global.asax 中包含一些我认为不应该存在的代码。我只是尝试修改代码并且效果很好。现在,无论我做了多少更改,它都会立即写入。

这是代码,我不知道它的作用,但我只是在网上找到了它。在我的情况下不需要它

 log4net.Repository.Hierarchy.Hierarchy hier = log4net.LogManager.GetRepository() as log4net.Repository.Hierarchy.Hierarchy;

        if (hier != null)
        {
            //get ADONetAppender
            log4net.Appender.AdoNetAppender adoAppender =
              (log4net.Appender.AdoNetAppender)hier.GetLogger("ADONetAppender",
                hier.LoggerFactory).GetAppender("ADONetAppender");
            if (adoAppender != null)
            {
                adoAppender.ConnectionString =
                  System.Configuration.ConfigurationSettings.AppSettings["MyConnectionString"];
                adoAppender.ActivateOptions(); //refresh settings of appender
            }

        }

在我删除它之后问题解决了。

【讨论】:

    猜你喜欢
    • 2011-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-23
    • 2017-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-03
    相关资源
    最近更新 更多