Programatic Configuration of targets and rules

3 messages Options
Embed this post
Permalink
Glenn E. Lanier, II

Programatic Configuration of targets and rules

Reply Threaded More More options
Print post
Permalink
I'm trying to programatically configure a couple of targets and rules (hopefully so I won't have to distribute an NLog.config file) for a WinForms application.

First thing I did was ensure it would all work in the NLog.config file. Then, I tried to build the targets in code, removing the associated lines from the config file.

I have the following code (and I replaced the actual username/password/etc. with placeholder text):

// SQL Database
NLog.Targets.DatabaseTarget targetDB = new NLog.Targets.DatabaseTarget();
NLog.Targets.DatabaseParameterInfo paramDB;
targetDB.DBProvider = "mssql";
targetDB.Name = "db";
targetDB.DBHost = "host";
targetDB.DBDatabase = "dbname";
targetDB.DBUserName = "username";
targetDB.DBPassword = "password";
targetDB.CommandText = "INSERT INTO Logs(LogTime, LogLevel, WindowsUserID, Logger, Message) VALUES (@LogTime, @LogLevel, @WindowsUserID, @Logger, @Message);";

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@LogTime";
paramDB.Layout = "${date}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@LogLevel";
paramDB.Layout = "${level}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@WindowsUserID";
paramDB.Layout = "${windows-identity:domain=false}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@Logger";
paramDB.Layout = "${logger}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@Message";
paramDB.Layout = "${message}";
targetDB.Parameters.Add(paramDB);

// General Log File
NLog.Targets.FileTarget targetGenFile = new NLog.Targets.FileTarget();
targetGenFile.Name = "generalFile";
targetGenFile.CreateDirs = true;
targetGenFile.FileName = @"${basedir}\logs\${windows-identity:domain=false}\tb911.${date:format=yyyy.MM.dd}.log";
targetGenFile.Layout = "${longdate}|${logger}|${level}|${message}";

// Console
NLog.Targets.ConsoleTarget targetConsole = new NLog.Targets.ConsoleTarget();
targetConsole.Name = "console";
targetConsole.Layout = "${longdate}|${logger}|${level}|${message}";

If I use the SimpleConfigurator:

NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetDB, LogLevel.Trace);
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetGenFile, LogLevel.Trace); 
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetConsole, LogLevel.Trace);

it appears that the last item in the list is applied, but no others (i.e., this ordering allows the console messages to appear, but no file, and no DB. However, if I move targetDB to be the last command, console messages no longer appear, but DB messages are logged).

So, I searched for a more in-depth article and found one that suggested:

NLog.Config.LoggingConfiguration config = LogManager.Configuration;
if (null == config)
{
config = new NLog.Config.LoggingConfiguration();
}

config.AddTarget(targetDB.Name, targetDB);
config.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Trace, targetDB));

config.AddTarget(targetGenFile.Name, targetGenFile);
config.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Trace, targetGenFile));

but I'm not have any success there, either.

Can anyone shed some light on how I can configure a SQL database target, a file target, and possibly a console target programatically?

Thanks.
Glenn

[hidden email]

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Nlog-list mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/nlog-list
Glenn E. Lanier, II

Re: Programatic Configuration of targets and rules

Reply Threaded More More options
Print post
Permalink
To follow up, I received an answer to this problem (didn't pay attention to the mail headers -- reply was sent off-list).

Essentially, I needed to create a new configuration (or get the current one), make my changes, then assign that configuration BACK to the LogManager.Configuration

NLog.Config.LoggingConfiguration config = new NLog.Config.LoggingConfiguration();

// Do all my stuff here
config.AddTarget(targetDB.Name, targetDB);
config.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Trace, targetDB));

// Critical piece!
LogManager.Configuration = config;

--G

On Tue, Oct 7, 2008 at 10:44 AM, Glenn E. Lanier, II <[hidden email]> wrote:
I'm trying to programatically configure a couple of targets and rules (hopefully so I won't have to distribute an NLog.config file) for a WinForms application.

First thing I did was ensure it would all work in the NLog.config file. Then, I tried to build the targets in code, removing the associated lines from the config file.

I have the following code (and I replaced the actual username/password/etc. with placeholder text):

// SQL Database
NLog.Targets.DatabaseTarget targetDB = new NLog.Targets.DatabaseTarget();
NLog.Targets.DatabaseParameterInfo paramDB;
targetDB.DBProvider = "mssql";
targetDB.Name = "db";
targetDB.DBHost = "host";
targetDB.DBDatabase = "dbname";
targetDB.DBUserName = "username";
targetDB.DBPassword = "password";
targetDB.CommandText = "INSERT INTO Logs(LogTime, LogLevel, WindowsUserID, Logger, Message) VALUES (@LogTime, @LogLevel, @WindowsUserID, @Logger, @Message);";

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@LogTime";
paramDB.Layout = "${date}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@LogLevel";
paramDB.Layout = "${level}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@WindowsUserID";
paramDB.Layout = "${windows-identity:domain=false}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@Logger";
paramDB.Layout = "${logger}";
targetDB.Parameters.Add(paramDB);

paramDB = new NLog.Targets.DatabaseParameterInfo();
paramDB.Name = "@Message";
paramDB.Layout = "${message}";
targetDB.Parameters.Add(paramDB);

// General Log File
NLog.Targets.FileTarget targetGenFile = new NLog.Targets.FileTarget();
targetGenFile.Name = "generalFile";
targetGenFile.CreateDirs = true;
targetGenFile.FileName = @"${basedir}\logs\${windows-identity:domain=false}\tb911.${date:format=yyyy.MM.dd}.log";
targetGenFile.Layout = "${longdate}|${logger}|${level}|${message}";

// Console
NLog.Targets.ConsoleTarget targetConsole = new NLog.Targets.ConsoleTarget();
targetConsole.Name = "console";
targetConsole.Layout = "${longdate}|${logger}|${level}|${message}";

If I use the SimpleConfigurator:

NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetDB, LogLevel.Trace);
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetGenFile, LogLevel.Trace); 
NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetConsole, LogLevel.Trace);

it appears that the last item in the list is applied, but no others (i.e., this ordering allows the console messages to appear, but no file, and no DB. However, if I move targetDB to be the last command, console messages no longer appear, but DB messages are logged).

So, I searched for a more in-depth article and found one that suggested:

NLog.Config.LoggingConfiguration config = LogManager.Configuration;
if (null == config)
{
config = new NLog.Config.LoggingConfiguration();
}

config.AddTarget(targetDB.Name, targetDB);
config.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Trace, targetDB));

config.AddTarget(targetGenFile.Name, targetGenFile);
config.LoggingRules.Add(new NLog.Config.LoggingRule("*", LogLevel.Trace, targetGenFile));

but I'm not have any success there, either.

Can anyone shed some light on how I can configure a SQL database target, a file target, and possibly a console target programatically?

Thanks.
Glenn

[hidden email]


-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Nlog-list mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/nlog-list
Rod Spencer

Re: Programatic Configuration of targets and rules

Reply Threaded More More options
Print post
Permalink
In reply to this post by Glenn E. Lanier, II
I agree with you solution.  The problem is that the method you are using: ConfigureForTargetLogging is meant to configure only one Target.  The code below is the contents of the method.

            LoggingConfiguration config = new LoggingConfiguration();
            LoggingRule rule = new LoggingRule("*", minLevel, target);
            config.LoggingRules.Add(rule);
            LogManager.Configuration = config;

If I were you, I would add a new method to the Simpleconfigurator class called: ConfigureAddTargetLogging with the same parameters.  The code would look like this:

            LoggingConfiguration config = LogManager.Configuration;     // Keep original configuration
            config.AddTarget(target.Name, target);                            // Add new target
            LoggingRule rule = new LoggingRule("*", minLevel, target);   // Create logging rule
            config.LoggingRules.Add(rule);                                         // Add logging rule
            LogManager.Configuration = config;                                  // Reassign modified configuration


Then in your original code, change:
     NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetDB, LogLevel.Trace);
     NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetGenFile, LogLevel.Trace);
     NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetConsole, LogLevel.Trace);

to

     NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(targetDB, LogLevel.Trace);
     NLog.Config.SimpleConfigurator.ConfigureAddrTargetLogging(targetGenFile, LogLevel.Trace);
     NLog.Config.SimpleConfigurator.ConfigureAddTargetLogging(targetConsole, LogLevel.Trace);

Then each target should be available.