Log4net AdoNetAppender滚动表

问题描述

我正在为.Net core 3.1应用程序使用MicroKnights.Logging.adonetappender。 我要为日志表(每个月日志的新表)滚动表名。

是否可以通过对log4net.config文件进行任何更改来实现这一目标?

我的log4net.config如下所示

<?xml version="1.0" encoding="utf-8" ?>
<log4net debug="true">
  <appender name="DebugAppender" type="log4net.Appender.DebugAppender" >
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date [%thread] %-5level %logger - %message%newline" />
    </layout>
  </appender>
  <appender name="RollingFile" type="log4net.Appender.RollingFileAppender">
    <file type="log4net.Util.PatternString" value="Log\logs_" />
    <staticLogFileName value="false" />
    <param name="AppendToFile" value="true" />
    <param name="RollingStyle" value="Date" />
    <param name="DatePattern" value="yyyy-MM-dd'.log'" />
    <appendToFile value="true" />
    <layout type="log4net.Layout.PatternLayout">
      <conversionPattern value="%date %5level %logger.%method [%line] - MESSAGE: %message%newline %exception" />
    </layout>
  </appender>
  <appender name="adonetappender" type="MicroKnights.Logging.adonetappender,MicroKnights.Log4Netadonetappender">
    <bufferSize value="1" />
    <connectionType value="Microsoft.Data.sqlClient.sqlConnection,Microsoft.Data.sqlClient,Version=1.0.0.0,Culture=neutral,PublicKeyToken=23ec7fc2d6eaa4a5"/>
    <connectionStringName value="log4net" />
    <connectionStringFile value="appsettings.json" />
    <commandText value="INSERT INTO [Log_@TableName]
                           ([ApiName],[RequestTimeUtc],[TimeElapsed],[Headers],[Body],[QueryString])
                     VALUES
                           (@ApiName,@RequestTimeUtc,@TimeElapsed,@Headers,@Body,@QueryString)" />
    <parameter>
      <parameterName value="@TableName" />
      <dbType value="String" />
      <size value="10000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{TableName}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@ApiName" />
      <dbType value="String" />
      <size value="10000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{ApiName}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@RequestTimeUtc" />
      <dbType value="DateTime" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{RequestTimeUtc}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@TimeElapsed" />
      <dbType value="String" />
      <size value="10000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{TimeElapsed}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@Headers" />
      <dbType value="String" />
      <size value="10000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{Headers}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@Body" />
      <dbType value="String" />
      <size value="10000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{Body}" />
      </layout>
    </parameter>
    <parameter>
      <parameterName value="@QueryString" />
      <dbType value="String" />
      <size value="10000" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%property{QueryString}" />
      </layout>
    </parameter>
  </appender>
  <root>
    <level value="ALL"/>
    <appender-ref ref="DebugAppender" />
    <appender-ref ref="RollingFile" />
    <appender-ref ref="adonetappender" />
  </root>
</log4net>

执行存储过程是我的最后选择。

解决方法

修改配置

<commandText value="INSERT INTO {0}
                           ([ApiName],[RequestTimeUtc],[TimeElapsed],[Headers],[Body],[QueryString])
                     VALUES
                           (@ApiName,@RequestTimeUtc,@TimeElapsed,@Headers,@Body,@QueryString)" />

然后按照以下步骤初始化log4net:

 public IEnumerable<string> InitializeLog4Net()
     {
    var repository = LogManager.GetRepository(GetType().Assembly);

   
    ConnectionString = _configuration.GetConnectionString("DefaultConnection");
    if (string.IsNullOrWhiteSpace(ConnectionString))
        throw new NullReferenceException($"Did not find the connectionString");

    var log4NetConfigFilename = $"Logging\\log4net.config";
    var fileInfo = new FileInfo(log4NetConfigFilename);
    if (fileInfo.Exists == false)
        throw new FileNotFoundException($"Did not find log4net configuration file \"{log4NetConfigFilename}\"");

    XmlConfigurator.Configure(repository,fileInfo);

    if (repository.Configured == false)
        throw new InvalidOperationException("Repository not configured");
    if (repository.ConfigurationMessages.Count != 0)
        throw new InvalidOperationException($"Repository messages found: {string.Join(",",repository.ConfigurationMessages)}");

    foreach (var appender in repository.GetAppenders())
    {
        if (appender is AdoNetAppender adoNetAppender)
        {
            adoNetAppender.CommandText = string.Format(adoNetAppender.CommandText,TableName);
            adoNetAppender.ConnectionString = ConnectionString;
            adoNetAppender.ErrorHandler = this;
            adoNetAppender.ActivateOptions();
        }
    }

   return _log4netErrors;
}

有问题地生成TableName或从appsettings.json中获取它