我想使用我将在运行时定义的ConnectionString。我找到了很多例子,但我无法使它发挥作用。
我创建了一个自定义AdoNetAppender:
public class AdoNetMultiTenantAppender : AdoNetAppender
{
public new string ConnectionString
{
get
{
return base.ConnectionString;
}
set
{
base.ConnectionString = Tenant.Current.DataSource.ConnectionString; // Return the connection string
}
}
}
我有以下配置:
<appender name="AdoNetMultiTenantAppender" type="MyNameSpace.AdoNetMultiTenantAppender">
<bufferSize value="1" />
<connectionstring value="" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<commandText value="[...]" />
<parameter>
[...]
</parameter>
</appender>
我的记录器在配置文件中定义如下:
<logger name="ProcessLogger" additivity="false">
<level value="INFO"/>
<appender-ref ref="AdoNetMultiTenantAppender"/>
</logger>
最后,为了让我的Logger得到我正在做的代码:
[...]
private static readonly ILog Logger = LogManager.GetLogger("ProcessLogger");
[...]
ProcessLogger.Logger.Info(message);
[...]
当我试图将连接字符串“硬编码”到我的配置中时,它正在工作。但我不能这样做因为我需要一个不同的ConnectionString,具体取决于一些变量。我放在自定义appender中的属性ConnectionString永远不会调用。知道我错过了什么吗?
答案 0 :(得分:2)
您使用的是什么版本的log4net?
在任何情况下,派生类中的new
ConnectionString属性都不会从现有基础结构中自动调用。
您可以通过覆盖合适的虚拟成员获得更多成功:例如,如果您使用的是log4net 1.2.11,则可以覆盖CreateConnection
或ResolveConnectionString
方法。
更新发表评论:
但是CreateConnection只使用了一次,所以我不能为多个ConnectionString使用相同的appender
是的,log4net AdoNetAppender
有一个不寻常的设计,因为连接对象保持打开状态并重复用于每个日志记录请求。与通常推荐的方法形成对比,即尽可能晚地创建/打开数据库连接,并在使用后立即关闭它。推荐的方法允许应用程序利用ADO.NET的内置连接池。
您可以尝试的一件事可能是覆盖SendBuffer(LoggingEvent[] events)
,并在您的覆盖调用基类中然后关闭连接。这将强制每次调用SendBuffer
时重新打开连接。
我不确定这是否会为您提供所需的一切 - 您谈到使用多个连接字符串的Multitenant应用程序。在这种情况下,传递给LoggingEvent
的{{1}}数组可能包含应发送到不同连接的事件。也许您需要使用SendBuffer
的某个属性来通过目标连接拆分输入数组,然后对于每个目标连接,打开连接,调用LoggingEvent
然后关闭连接。
答案 1 :(得分:1)
这适用于现有的AdoNetAppender:
public static void SetConnectionString(string connectionString)
{
Hierarchy logHierarchy = log4net.LogManager.GetRepository() as Hierarchy;
if (logHierarchy == null)
{
throw new InvalidOperationException("Can't set connection string as hierarchy is null. Has logging been initialised?");
}
// Assumes there is only one appender to be configured
var appender = logHierarchy.GetAppenders().OfType<AdoNetAppender>().SingleOrDefault();
if (appender == null)
{
throw new InvalidOperationException("Can't set connection string as can't locate a database appender");
}
appender.ConnectionString = connectionString;
appender.ActivateOptions();
}
请注意,AdoNetAppender会抱怨配置中没有设置连接字符串值,但这并不重要,除非您打开所有例外,否则您可能无法注意到。< / p>