我正在尝试使用'Database' NLog target并希望NLog读取我的连接字符串,以避免在同一配置文件中设置两次。问题是我有Entity Framework-style connection string,因此使用connectionStringName
属性不起作用。
在log4net中,我可以使用custom AdoNetAppender并自己提取连接字符串的相应部分。有没有办法自定义NLog的数据库目标,所以我可以传入一个适当样式的连接字符串?
答案 0 :(得分:7)
通过在代码中配置日志记录目标,可以轻松解决此问题:
private DatabaseTarget CreateDatabaseTarget()
{
var entityFrameworkConnection = ConfigurationManager.ConnectionStrings["MyEntities"].ConnectionString;
var builder = new EntityConnectionStringBuilder(entityFrameworkConnection);
var connectionString = builder.ProviderConnectionString;
var target = new DatabaseTarget()
{
ConnectionString = connectionString,
CommandText = @"insert into Log ([DateTime], [Message]) values (@dateTime, @message);",
Parameters = {
new DatabaseParameterInfo("@dateTime", new NLog.Layouts.SimpleLayout("${date}")),
new DatabaseParameterInfo("@message", new NLog.Layouts.SimpleLayout("${message}")),
}
};
return target;
}
然后您可以使用NLog配置进行注册:
var target = CreateDatabaseTarget();
LogManager.Configuration.AddTarget("databaseTarget", CreateDatabaseTarget());
LogManager.Configuration.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Warn, target));
但是,如果您可以使用一些Nuget依赖项或想要更完整的解决方案,那么您可以查看两个都有nuget包可用的NLog.Mvc和NLog.EntityFramework个存储库...
答案 1 :(得分:5)
无法自定义内置DatabaseTarget
,因为它是sealed
。
并且没有任何其他扩展点,因为DatabaseTarget.InitializeTarget()
将始终抛出异常,因为它无法创建EF DbProviderFactory
providerName="System.Data.EntityClient"
形式
因此,使用当前的NLog版本2.0.0.0
,您必须遵循以下选项:
答案 2 :(得分:1)
从DbContext获取正常连接字符串的方法如下:
context.Database.Connection.ConnectionString
假设你有适当格式的连接字符串,我认为像这样配置目标更容易:
1)在配置中定义目标
<target name="database" type="Database" connectionString="${gdc:myConnectionString}">
<commandText>
...
</commandText>
2)在运行时设置连接字符串
GlobalDiagnosticsContext.Set("myConnectionString", connectionString);
这样,您就不会硬编码数据库目标行为。
答案 3 :(得分:1)
NLog 4.5添加了对从Entity Framework解析连接字符串的支持,因此可以直接使用它们:
https://github.com/NLog/NLog/pull/2510
NLog DatabaseTarget也不再密封,因此,如果需要特殊处理,则也可以这样做。
进行特殊解析/查找逻辑的正常方法是注册一个自定义layoutrenderer并在ConnectionString-Layout中引用它:
https://github.com/NLog/NLog/wiki/How-to-write-a-custom-layout-renderer
答案 4 :(得分:0)
将变量添加到NLog.config文件中
<variable name="connectionStringNLog" value="" />
然后在目标元素中引用此变量
<target name="my-db"
xsi:type="Database"
dbProvider="System.Data.SqlClient"
connectionString="${var:connectionStringNLog}"
commandType="StoredProcedure"
commandText="[dbo].[LogEntryInsert]">
,然后在您的contextfactory c#文件中添加以下行以分配连接字符串值,无论它是来自其他配置文件还是来自Key Vault:
LogManager.Configuration.Variables["connectionStringNLog"] = conn.ConnectionString;