Dev86
Dev86

Reputation: 91

Nlog set Database target programatically and access custom log message properties

I need to support database logging. For that I decided to use nlog because it brings database support. But first of all I need to setup the configuration programatically. As far as I understood it I have to set the layout for the target. But the class "DatabaseTarget" does not have any property related to Layout :/.

                        var dbTarget = new DatabaseTarget();
                    dbTarget.ConnectionString = LogConnectionString;
                    dbTarget.CommandType = System.Data.CommandType.StoredProcedure;
                    dbTarget.CommandText = "exec dbo.InsertLog @level=${level}, @callSite=${callsite}, @message=${message}, @stackTrace=${stacktrace}, @machinename=${machinename}, @processname=${processname}";

Is the layout definition really necessary for the DatabaseTarget. If so how do I set it programatically?

Additionally I want to pass some information. But I am not sure how I can assign those informations for the procedure. As far as I understood it I can assign those variables: https://github.com/nlog/nlog/wiki/Layout-Renderers

But NLog support generic arguments with his Log Method. It looks like this:

_nLog.Log<AJourFaultLevel>(ConvertLogLevel(logEntry.Level), logEntry.Message, logEntry.Fault);

How can I assign the passed "logEntry.Fault" value for my stored procedure?

Best regards

Upvotes: 2

Views: 703

Answers (1)

Rolf Kristensen
Rolf Kristensen

Reputation: 19867

Your current log-statement injects logEntry.Fault as parameter into string.Format(logEntry.Message, logEntry.Fault):

_nLog.Log<AJourFaultLevel>(ConvertLogLevel(logEntry.Level), logEntry.Message, logEntry.Fault);

If you are using NLog 4.5 then you can use structured-logging where you can name the parameter like this:

_nLog.Log<AJourFaultLevel>(ConvertLogLevel(logEntry.Level), "Fault occurred: {AJourFaultLevel}", logEntry.Fault);

Then you can access the named parameter using ${event-properties:item=}:

dbTarget.CommandText = "exec dbo.InsertLog @level=${level}, @callSite=${callsite}, @message=${message}, @stackTrace=${stacktrace}, @machinename=${machinename}, @processname=${processname}, @faultLevel=${event-properties:item=AJourFaultLevel}";

Upvotes: 2

Related Questions