将消息记录到不同的数据库

Logging messages to different databases

我是 Log4Net 的新手。请帮我理解一些概念。

在我的应用程序中,我只有一个记录器。我想根据某些条件逻辑将消息记录到不同的数据库。

在应用程序配置文件中,我有一个路由到 AdonetAppender 的记录器

<log4net>
<appender name="SQLAppender" type="log4net.Appender.AdoNetAppender">     
   <connectionType value="" />
   <connectionString value="" />
</appender
<logger name="AuditLogger">
  <level value="ALL" />
  <appender-ref ref="SQLAppender"/>
</logger>
</log4net>

有没有办法通过代码动态设置连接字符串?

我的记录器 class 被设计为单例。我想知道附加程序是如何实例化的。它们是在每个记录器实例创建时实例化一次,还是在每次调用 ILog.Info(obj) 方法调用时实例化一次?

谢谢。

Every client uses the same code base. The only thing that changes is the connection string value based on the client.

对我来说,这不是 100% 清楚,我将其解读为 2 种可能的情况,因此根据您的配置有 2 种可能的解决方案。

多次部署

真正不需要自定义代码,因为您的部署应该知道它正在工作的数据库是什么on/with。基于此,您只需在初始化时配置一次 AdoNetAppender。我认为这不是那么简单,因为您在评论中提到您已使它起作用。

多租户应用程序

您对所有客户进行单一部署,并且代码根据请求的来源确定目标数据库。

  1. 我认为完成此操作的最简单方法是创建自定义 log4net appender. The existing AdoNetAppender 未密封,因此您可以继承并覆盖它。然后,您需要使用自己的代码覆盖受保护的方法 ResolveConnectionString,您可以在其中根据执行或请求上下文解析连接字符串。 感谢@stuartd 对 ResolveConnectionString 的指点。
  2. 您可以创建自己的 AdoNetAppender 自定义版本,它具有动态数据库连接字符串。唯一的其他移动部分是根据上下文分配它,因为您没有提到如何确定它(或者这个上下文甚至是什么,如果它是网络应用程序,可能是 URL?)。

创建附加程序后,只需将其添加到 .config 文件(或者如果您不想使用配置文件,则以编程方式配置它)。

感谢 Igor 提出了几种解析连接字符串的方法。

但是,我正在做这样的事情。

var loggerRepo = LogManager.GetRepository();
if (loggerRepo != null) {
var appender = loggerRepo.GetAppenders().OfType < AdoNetAppender > ().First(a => a.Name == "YourAppenderName");

appender.ConnectionString = ConfigurationManager.ConnectionStrings[""].ConnectionString;
appender.ActivateOptions();
}
_log.Info("LogSOmeth9ng");