Reputation: 18675
I often create logs that have a lot of custom columns like:
<target xsi:type="Database" name="Log" dbProvider="System.Data.SqlClient" connectionString="...">
<commandText>
INSERT
INTO [dbo].[Log]([Foo], [Bar], ...)
VALUES(@FOO, @BAR, ...)
</commandText>
<parameter name="@FOO" layout="..." />
<parameter name="@BAR" layout="..." />
...
</target>
but I don't really like how I have to repeat the names of the columns three times for each of them. It's difficult to maintain and easy to make a mistake.
Is there an easier and more efficient way to create NLog database targets?
Can NLog infer the insert from the parameters alone? It would be great if I just could write the schema and table name, the parameters and the INSERT
is pretty obvious so it actually could be build automatically. Is there such a mechanism yet?
I've added the c#
tag because if there is a programmatic solution I prefer c#
.
Upvotes: 2
Views: 542
Reputation: 36750
In addition to t3chb0t answer.
You could loop over all the database targets after the configuration changes:
private void Main() //or application_start
{
//init
GenerateDatabaseTargetQueries();
//update when config changes
LogManager.ConfigurationReloaded += (sender, args) => GenerateDatabaseTargetQueries();
}
public void GenerateDatabaseTargetQueries()
{
var databaseTargets = LogManager.Configuration.AllTargets.OfType<DatabaseTarget>();
foreach (var databaseTarget in databaseTargets)
{
//todo good init capacity for StringBuilder
var queryBuilder = new StringBuilder();
queryBuilder.Append("INSERT INTO [dbo].[Log]");
foreach (var dbParameter in databaseTarget.Parameters)
{
//append all the parameters to the query
}
databaseTarget.CommandText = queryBuilder.ToString();
}
}
Upvotes: 1
Reputation: 18675
I found a way. You need to update the CommandText
of the DatabaseTarget
.
var config = NLog.LogManager.Configuration;
var dbTarget = config.AllTargets[0] as DatabaseTarget;
dbTarget.CommandText = "INSERT...";
see also Auto-INSERT query for NLog on CodeReview
Upvotes: 1