Azure Functions : NLog and Database

Published 04-01-2019 04:50 PM 1,453 Views
Microsoft
First published on MSDN on Mar 16, 2017

Here are steps to write NLog to Database in Azure Functions

1. via Config (NLog.config)

<?xml version="1.0" encoding="utf-8" ?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<targets>

<!--<target name="logfile" xsi:type="File" fileName="file.txt" />-->

<target name="logfile" xsi:type="Database" connectionstring="Server=dbservername.database.windows.net,1433;Initial Catalog=dbname;Persist Security Info=False;User ID=dbuser;Password=password; MultipleActiveResultSets=False; Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;">

<commandText>

insert into LogTable(time_stamp,level,logger,message) values(@time_stamp, @level, @logger, @message);

</commandText>

<parameter name="@time_stamp" layout="${date}" />

<parameter name="@level" layout="${level}" />

<parameter name="@logger" layout="${logger}" />

<parameter name="@message" layout="${message}" />

</target>

</targets>

<rules>

<logger name="*" minlevel="Trace" writeTo="logfile" />

</rules>

</nlog>

2. via Code

static void Main(string[] args)

{

LogManager.ThrowExceptions = true;

LogManager.ThrowConfigExceptions = true;

//InternalLogger.LogToConsole = true;

InternalLogger.LogFile = "log.txt";

InternalLogger.LogLevel = LogLevel.Trace;

#if DEBUG1 //FILE_TARGET

NLog.Targets.FileTarget target = new NLog.Targets.FileTarget("file_target");

target.FileName = "logfile.txt";

NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);

Logger logger = LogManager.GetLogger("file_target");

#elif DEBUG2

NLog.Targets.DatabaseTarget target = new NLog.Targets.DatabaseTarget("db_target");

NLog.Targets.DatabaseParameterInfo param;

//target.DBProvider = "System.Data.SqlClient";

target.DBHost = "dbservername.database.windows.net";

target.DBUserName = "dbuser";

target.DBPassword = "password";

target.DBDatabase = "dbname";

target.CommandText = "insert into LogTable(time_stamp,level,logger,message) values(@time_stamp, @level, @logger, @message);";

param = new NLog.Targets.DatabaseParameterInfo();

param.Name = "@time_stamp";

param.Layout = "${date}";

target.Parameters.Add(param);

param = new NLog.Targets.DatabaseParameterInfo();

param.Name = "@level";

param.Layout = "${level}";

target.Parameters.Add(param);

param = new NLog.Targets.DatabaseParameterInfo();

param.Name = "@logger";

param.Layout = "${logger}";

target.Parameters.Add(param);

param = new NLog.Targets.DatabaseParameterInfo();

param.Name = "@message";

param.Layout = "${message}";

target.Parameters.Add(param);

NLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target, LogLevel.Trace);

Logger logger = LogManager.GetLogger("db_target");

#else

Logger logger = LogManager.GetCurrentClassLogger();

#endif

logger.Trace("Sample trace message");

logger.Debug("Sample debug message");

logger.Info("Sample informational message");

logger.Warn("Sample warning message");

logger.Error("Sample error message");

logger.Fatal("Sample fatal error message");

LogManager.Flush();

}

3. In Azure Functions, we need to set the location of NLog.config file using XmlLoggingConfiguration() class as shown below:

using System;

using NLog;

using NLog.Common;

using NLog.Config;

private static Logger logger = null;

public static void Run(TimerInfo myTimer, TraceWriter log)

{

log.Info($"C# Timer trigger function executed at: {DateTime.Now}");

if (logger == null)

{

LogManager.ThrowExceptions = true;

LogManager.ThrowConfigExceptions = true;

//InternalLogger.LogToConsole = true;

InternalLogger.LogFile = "log.txt";

InternalLogger.LogLevel = LogLevel.Trace;

LogManager.Configuration = new XmlLoggingConfiguration("D:\\home\\site\\wwwroot\\<your function name>\\NLog.config");

logger = LogManager.GetCurrentClassLogger();

}

4. Also note, we need to add NuGet package details in the Project.json as shown below

%3CLINGO-SUB%20id%3D%22lingo-sub-392378%22%20slang%3D%22en-US%22%3EAzure%20Functions%20%3A%20NLog%20and%20Database%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-392378%22%20slang%3D%22en-US%22%3E%0A%20%26lt%3Bmeta%20http-equiv%3D%22Content-Type%22%20content%3D%22text%2Fhtml%3B%20charset%3DUTF-8%22%20%2F%26gt%3B%3CSTRONG%3E%20First%20published%20on%20MSDN%20on%20Mar%2016%2C%202017%20%3C%2FSTRONG%3E%20%3CBR%20%2F%3E%3CP%3EHere%20are%20steps%20to%20write%20NLog%20to%20Database%20in%20Azure%20Functions%3C%2FP%3E%0A%20%20%3CP%3E%3C%2FP%3E%0A%20%20%3CP%3E1.%20via%20Config%20(NLog.config)%3C%2FP%3E%0A%20%20%3CTABLE%3E%0A%20%20%20%3CTBODY%3E%3CTR%3E%0A%20%20%20%20%3CTD%3E%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CNLOG%20xmlns%3D%22%26quot%3B%26lt%3BA%22%20href%3D%22http%3A%2F%2Fwww.nlog-project.org%2Fschemas%2FNLog.xsd%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%3CA%20href%3D%22http%3A%2F%2Fwww.nlog-project.org%2Fschemas%2FNLog.xsd%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttp%3A%2F%2Fwww.nlog-project.org%2Fschemas%2FNLog.xsd%3C%2FA%3E%22%3C%2FNLOG%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Exmlns%3Axsi%3D%22%3CA%20href%3D%22http%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3Ehttp%3A%2F%2Fwww.w3.org%2F2001%2FXMLSchema-instance%3C%2FA%3E%22%26gt%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CTARGETS%3E%3C%2FTARGETS%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C!--%3Ctarget%20name%3D%26quot%3Blogfile%26quot%3B%20xsi%3Atype%3D%26quot%3BFile%26quot%3B%20fileName%3D%26quot%3Bfile.txt%26quot%3B%20%2F%3E--%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CTARGET%20name%3D%22%26quot%3Blogfile%26quot%3B%22%20type%3D%22%26quot%3BDatabase%26quot%3B%22%20connectionstring%3D%22%26quot%3BServer%3Ddbservername.database.windows.net%2C1433%3BInitial%22%20catalog%3D%22dbname%3BPersist%22%20security%3D%22%22%20info%3D%22False%3BUser%22%20id%3D%22dbuser%3BPassword%3Dpassword%3B%22%20multipleactiveresultsets%3D%22False%3B%22%20encrypt%3D%22True%3BTrustServerCertificate%3DFalse%3BConnection%22%20timeout%3D%2230%3B%26quot%3B%22%3E%3C%2FTARGET%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CCOMMANDTEXT%3E%3C%2FCOMMANDTEXT%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Einsert%20into%20LogTable(time_stamp%2Clevel%2Clogger%2Cmessage)%20values(%40time_stamp%2C%20%40level%2C%20%40logger%2C%20%40message)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CPARAMETER%20name%3D%22%26quot%3B%40time_stamp%26quot%3B%22%20layout%3D%22%26quot%3B%24%7Bdate%7D%26quot%3B%22%3E%3C%2FPARAMETER%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CPARAMETER%20name%3D%22%26quot%3B%40level%26quot%3B%22%20layout%3D%22%26quot%3B%24%7Blevel%7D%26quot%3B%22%3E%3C%2FPARAMETER%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CPARAMETER%20name%3D%22%26quot%3B%40logger%26quot%3B%22%20layout%3D%22%26quot%3B%24%7Blogger%7D%26quot%3B%22%3E%3C%2FPARAMETER%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CPARAMETER%20name%3D%22%26quot%3B%40message%26quot%3B%22%20layout%3D%22%26quot%3B%24%7Bmessage%7D%26quot%3B%22%3E%3C%2FPARAMETER%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CRULES%3E%3C%2FRULES%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3CLOGGER%20name%3D%22%26quot%3B*%26quot%3B%22%20minlevel%3D%22%26quot%3BTrace%26quot%3B%22%20writeto%3D%22%26quot%3Blogfile%26quot%3B%22%3E%3C%2FLOGGER%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%3C%2FTD%3E%0A%20%20%20%3C%2FTR%3E%0A%20%20%3C%2FTBODY%3E%3C%2FTABLE%3E%0A%20%20%3CP%3E2.%20via%20Code%3C%2FP%3E%0A%20%20%3CTABLE%3E%0A%20%20%20%3CTBODY%3E%3CTR%3E%0A%20%20%20%20%3CTD%3E%3CP%3Estatic%20void%20Main(string%5B%5D%20args)%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%7B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogManager.ThrowExceptions%20%3D%20true%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogManager.ThrowConfigExceptions%20%3D%20true%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%2F%2FInternalLogger.LogToConsole%20%3D%20true%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3EInternalLogger.LogFile%20%3D%20%22log.txt%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3EInternalLogger.LogLevel%20%3D%20LogLevel.Trace%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%23if%20DEBUG1%20%2F%2FFILE_TARGET%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ENLog.Targets.FileTarget%20target%20%3D%20new%20NLog.Targets.FileTarget(%22file_target%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.FileName%20%3D%20%22logfile.txt%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ENLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target%2C%20LogLevel.Trace)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogger%20logger%20%3D%20LogManager.GetLogger(%22file_target%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%23elif%20DEBUG2%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ENLog.Targets.DatabaseTarget%20target%20%3D%20new%20NLog.Targets.DatabaseTarget(%22db_target%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ENLog.Targets.DatabaseParameterInfo%20param%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%2F%2Ftarget.DBProvider%20%3D%20%22System.Data.SqlClient%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.DBHost%20%3D%20%22dbservername.database.windows.net%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.DBUserName%20%3D%20%22dbuser%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.DBPassword%20%3D%20%22password%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.DBDatabase%20%3D%20%22dbname%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.CommandText%20%3D%20%22insert%20into%20LogTable(time_stamp%2Clevel%2Clogger%2Cmessage)%20values(%40time_stamp%2C%20%40level%2C%20%40logger%2C%20%40message)%3B%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam%20%3D%20new%20NLog.Targets.DatabaseParameterInfo()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Name%20%3D%20%22%40time_stamp%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Layout%20%3D%20%22%24%7Bdate%7D%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.Parameters.Add(param)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam%20%3D%20new%20NLog.Targets.DatabaseParameterInfo()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Name%20%3D%20%22%40level%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Layout%20%3D%20%22%24%7Blevel%7D%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.Parameters.Add(param)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam%20%3D%20new%20NLog.Targets.DatabaseParameterInfo()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Name%20%3D%20%22%40logger%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Layout%20%3D%20%22%24%7Blogger%7D%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.Parameters.Add(param)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam%20%3D%20new%20NLog.Targets.DatabaseParameterInfo()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Name%20%3D%20%22%40message%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eparam.Layout%20%3D%20%22%24%7Bmessage%7D%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Etarget.Parameters.Add(param)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ENLog.Config.SimpleConfigurator.ConfigureForTargetLogging(target%2C%20LogLevel.Trace)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogger%20logger%20%3D%20LogManager.GetLogger(%22db_target%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%23else%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogger%20logger%20%3D%20LogManager.GetCurrentClassLogger()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%23endif%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger.Trace(%22Sample%20trace%20message%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger.Debug(%22Sample%20debug%20message%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger.Info(%22Sample%20informational%20message%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger.Warn(%22Sample%20warning%20message%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger.Error(%22Sample%20error%20message%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger.Fatal(%22Sample%20fatal%20error%20message%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogManager.Flush()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%7D%3C%2FP%3E%0A%20%20%20%20%3C%2FTD%3E%0A%20%20%20%3C%2FTR%3E%0A%20%20%3C%2FTBODY%3E%3C%2FTABLE%3E%0A%20%20%3CP%3E3.%20In%20Azure%20Functions%2C%20we%20need%20to%20set%20the%20location%20of%20NLog.config%20file%20using%20XmlLoggingConfiguration()%20class%20as%20shown%20below%3A%3C%2FP%3E%0A%20%20%3CTABLE%3E%0A%20%20%20%3CTBODY%3E%3CTR%3E%0A%20%20%20%20%3CTD%3E%3CP%3Eusing%20System%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eusing%20NLog%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eusing%20NLog.Common%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eusing%20NLog.Config%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eprivate%20static%20Logger%20logger%20%3D%20null%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Epublic%20static%20void%20Run(TimerInfo%20myTimer%2C%20TraceWriter%20log)%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%7B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elog.Info(%24%22C%23%20Timer%20trigger%20function%20executed%20at%3A%20%7BDateTime.Now%7D%22)%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Eif%20(logger%20%3D%3D%20null)%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%7B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogManager.ThrowExceptions%20%3D%20true%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogManager.ThrowConfigExceptions%20%3D%20true%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%2F%2FInternalLogger.LogToConsole%20%3D%20true%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3EInternalLogger.LogFile%20%3D%20%22log.txt%22%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3EInternalLogger.LogLevel%20%3D%20LogLevel.Trace%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3ELogManager.Configuration%20%3D%20new%20XmlLoggingConfiguration(%22D%3A%5C%5Chome%5C%5Csite%5C%5Cwwwroot%5C%5C%3CYOUR%20function%3D%22%22%20name%3D%22%22%3E%5C%5CNLog.config%22)%3B%3C%2FYOUR%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3Elogger%20%3D%20LogManager.GetCurrentClassLogger()%3B%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%3C%2FP%3E%0A%20%20%20%20%20%3CP%3E%7D%3C%2FP%3E%0A%20%20%20%20%3C%2FTD%3E%0A%20%20%20%3C%2FTR%3E%0A%20%20%3C%2FTBODY%3E%3C%2FTABLE%3E%0A%20%20%3CP%3E4.%20Also%20note%2C%20we%20need%20to%20add%20NuGet%20package%20details%20in%20the%20Project.json%20as%20shown%20below%3C%2FP%3E%0A%20%20%3CP%3E%3CIMG%20src%3D%22https%3A%2F%2Ftechcommunity.microsoft.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F101011iFF32B5DB8F6AD4C0%22%20%2F%3E%3C%2FP%3E%0A%20%0A%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-392378%22%20slang%3D%22en-US%22%3EFirst%20published%20on%20MSDN%20on%20Mar%2016%2C%202017%20Here%20are%20steps%20to%20write%20NLog%20to%20Database%20in%20Azure%20Functions%20%26nbsp%3B%201.%3C%2FLINGO-TEASER%3E
Version history
Last update:
‎Aug 24 2020 12:36 PM
Updated by: