Adding properties to log message in NLog in .net core

11,990

Solution 1

If you want custom layout properties (NLog calls them layout renderers) you can use the EventProperties Layout Renderer. You can simply do this in your code:

var logger = LogManager.GetCurrentClassLogger();
var eventInfo = new LogEventInfo(LogLevel.Info, logger.Name, "Message");
eventInfo.Properties["CustomValue"] = "My custom string";
eventInfo.Properties["CustomDateTimeValue"] = new DateTime(2020, 10, 30, 11, 26, 50);
// You can also add them like this:
eventInfo.Properties.Add("CustomNumber", 42);
// Send to Log
logger.Log(eventInfo);

Then you will be able to add these (any any properties you make up) in your nlog.config

<target>
  <parameter name="@customtime" layout="${event-properties:CustomDateTimeValue:format=yyyy-MM-dd HH\:mm\:ss}" />
  <parameter name="@customvalue" layout="${event-properties:item=CustomValue}" />
  <parameter name="@customnumber" layout="${event-properties:item=CustomNumber}" />
</target>

When using NLog with AspNetCore, it's useful to add the NLog.Web Package for ASP.NET Core which gives you many predefined Layout renderers. You can find more about NLog.Web for AspNetCore on their Github page.

This AspNetCore package will give you things like the following:

<parameter name="@UserName" layout="${aspnet-user-identity}" />
<parameter name="@MvcAction" layout="${aspnet-MVC-Action}" />
<parameter name="@Session" layout="${aspnet-session:Variable=User.Name:EvaluateAsNestedProperties=true}" />
... etc

You will find the complete list on the NLog.Web.AspNetCore Github page.

Solution 2

NLog can integrate with Microsoft ILogger, and will capture messsage-template properties:

logger.LogInformation("Message {PropertyName}", "PropertyValue");

It has been supported since NLog.Extensions.Logging ver. 1.0 in combination with NLog ver. 4.5.

More advanced examples of working with Microsoft ILogger can be found here: https://github.com/NLog/NLog.Extensions.Logging/wiki/NLog-properties-with-Microsoft-Extension-Logging

Notice that one is not required to use Microsoft ILogger when developing a NetCore-application. NLog Logger ver. 4.5 works without any issues on both .NetFramework- and .NetCore-applications. See also https://github.com/NLog/NLog/wiki/How-to-use-structured-logging

Solution 3

Find step by step information to setup Nlog in your .NET Application.

Step 1:- Installation

Install NLog and NLog.Extended of version 4.0.0.0 from Nuget Manager.

Step 2:- WebConfig configuration

    <configSections>
        <section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
    </configSections>
    
    <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" throwExceptions="false" internalLogFile="D:\NLogErrors\log.txt">
        <extensions>
          <!-- load NLog.Extended to enable ASP.NET-specific functionality -->
          <add assembly="NLog.Extended" />
        </extensions>
        <!--Define Various Log Targets like files, database or asp.net trace files-->
        <targets>
          <target name="oracle" xsi:type="Database" keepConnection="false" dbProvider="Oracle.DataAccess.Client.OracleConnection, Oracle.DataAccess, Version=4.121.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342" connectionString="Data Source=(DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = "" )(PORT = 1521))(CONNECT_DATA =(SID = "")));User Id="";Password="";" commandText="INSERT INTO LOGTABLE (LOGMESSAGE,LOGLEVEL,LOGGERNAME,CREATEDDATETIME,SESSIONID,BROWSERDETAIL,REQUESTURL,ERRORMESSAGE,PRODUCERCODE,QUOTENO,CUSTOMER_IP_ADDRESS,SERVER_IP_ADDRESS) values(:LOGMESSAGE,:LOGLEVEL,:LOGGERNAME,:CREATEDDATETIME,:SESSIONID,:BROWSERDETAIL,:REQUESTURL,:ERRORMESSAGE,:PRODUCERCODE,:QUOTENO,:CUSTOMER_IP_ADDRESS,:SERVER_IP_ADDRESS)">
            <parameter name="LOGMESSAGE" layout="${message}" />
            <parameter name="LOGLEVEL" layout="${level:uppercase=true}" />
            <parameter name="LOGGERNAME" layout="${logger}" />
            <parameter name="CREATEDDATETIME" layout="${date}" />
            <parameter name="SESSIONID" layout="${event-context:item=SessionId}" />
            <parameter name="BROWSERDETAIL" layout="${event-context:item=BrowserDetail}" />
            <parameter name="REQUESTURL" layout="${event-context:item=RequestUrl}" />
            <parameter name="ERRORMESSAGE" layout="${event-context:item=ErrorMessage}" />
            <parameter name="PRODUCERCODE" layout="${event-context:item=ProducerCode}" />
            <parameter name="QUOTENO" layout="${event-context:item=QuoteNo}" />
            <parameter name="CUSTOMER_IP_ADDRESS" layout="${event-context:item=CUSTOMER_IP_ADDRESS}"/>
            <parameter name="SERVER_IP_ADDRESS" layout="${event-context:item=SERVER_IP_ADDRESS}"/>
          </target>
          <target xsi:type="Mail" name="Email" html="true" addNewLines="false" replaceNewlineWithBrTagInHtml="false" subject="Error Log" to="[email protected]" useSystemNetMailSettings="true" body="${event-context:item=EmailBody}">
          </target>
        </targets>
        <rules>
          <logger name="*" minlevel="trace" writeTo="oracle" />
          
        </rules>
      </nlog>

Step 3:- Cs Code

    public static class NLogManager
        {
            public static ILogger _logger = 
             NLog.LogManager.GetCurrentClassLogger();
    
            public static void InfoLog(NLogData nLogData)
            {
                LogEventInfo theEvent = new LogEventInfo(LogLevel.Info, NLogManager._logger.Name, nLogData.Message);
                SetLogEventInfo(theEvent, nLogData);
                _logger.Log(theEvent);
            }
    }
    
     private static void SetLogEventInfo(LogEventInfo theEvent, NLogData 
         nLogData)
            {
                theEvent.Properties["SessionId"] = nLogData.SessionId;
                theEvent.Properties["BrowserDetail"] = nLogData.BrowserDetail;
                theEvent.Properties["RequestUrl"] = nLogData.RequestUrl;
                theEvent.Properties["ErrorMessage"] = nLogData.ErrorMessage;
                theEvent.Properties["EmailBody"] = nLogData.EmailBody;
                theEvent.Properties["ProducerCode"] = nLogData.ProducerCode;
                theEvent.Properties["QuoteNo"] = nLogData.QuoteNo;
                theEvent.Properties["CUSTOMER_IP_ADDRESS"] = nLogData.CustomerIPAddress;
                theEvent.Properties["SERVER_IP_ADDRESS"] = nLogData.ServerIPAddress;
            }

Step 4:- Model Entity


    public class NLogData
        {
            public string SessionId { get; set; }
    
            public string Message { get; set; }
    
            public string RequestUrl { get; set; }
    
            public string BrowserDetail { get; set; }
    
            public string Method { get; set; }
    
            public string ErrorMessage { get; set; }
    
            public string EmailBody { get; set; }
    
            public string ProducerCode { get; set; }
    
            public string QuoteNo { get; set; }
    
            public string CustomerIPAddress { get; set; }
    
            public string ServerIPAddress { get; set; }
        }

Step 5 :- Add Below line from where you have implement logging


     NLogManager.TraceLog(NLogData nlogData);

-- Create proper format which is accepted by above method and set value accordingly

If you have any query please leave comment or mail me on [email protected]

Share:
11,990

Related videos on Youtube

Purnima Naik
Author by

Purnima Naik

Updated on September 15, 2022

Comments

  • Purnima Naik
    Purnima Naik over 1 year

    I am using NLog for logging messages in .net core.

    I have added NLog in StartUp.cs as follows:

    loggerFactory.AddNLog();
    

    For logging to file, I am using following method:

    logger.LogInformation("Message");
    

    I want to add custom NLog event properties to my message. But LogInformation() is not allowing me to pass that. How can I do that?

  • BaBu
    BaBu over 6 years
    Tnx! (Sorry to admit I can't get any of the alternatives to work though... The first two possibly because I use NLog.Web.AspNetCore, but then I have to in order to get NLog to work with .NET Core, yes? Your third option, the 'MyLogEvent' class doesn't compile.)
  • BaBu
    BaBu over 6 years
    edit: the MyLogEvent class compiles fine, I'm an idiot. But the {$event-properties} renderer still doesn't pick up the illusive properties.
  • BaBu
    BaBu over 6 years
    about versions: I'm using NLog.Web.AspNetCore (4.4.1) which seems to include NLog (5.0.0-beta07) and NLog.Extensions.Logging (1.0.0-rtm-beta5). So, I should be ok. But it won't work.
  • Rolf Kristensen
    Rolf Kristensen over 6 years
    I know it is confusing, but NLog 5.0 BETA is stale and only useful for UWP10 application. The latest version is NLog 4.5 RC
  • Rolf Kristensen
    Rolf Kristensen over 6 years
    You should instead use NLog.Extensions.Logging ver. 1.0.0-rtm-rc2 with NLog 4.5 RC
  • BaBu
    BaBu over 6 years
    Thing is; the doc for NLog.Extensions.Logging says "ASP.NET Core users should use the ASP.NET Core 2 tutorial" and that page says "Needs NLog.Web.AspNetCore". So, can I use either? What's the difference between them? Anyway, I'm awarding you the bounty for your efforts. Tnx.
  • Rolf Kristensen
    Rolf Kristensen over 6 years
    NLog.Web.AspNetCore depends on NLog.Extensions.Logging, and adds some extra layout-renders that are useful when creating an Asp.NetCore application. When using NLog.Web.AspNetCore 4.5.0, then it will open access to the new stuff described in the above wiki-page.
  • Rolf Kristensen
    Rolf Kristensen over 6 years
    I have created github.com/NLog/NLog.Extensions.Logging/pull/171, so all logic available in Asp.NetCore2 is also available for Net461.
  • BaBu
    BaBu over 6 years
    Upgraded to NLog.Web.AspNetCore 4.5.0-beta04. That solved this issue. So, it can be closed by the thread starter. (Be warned however; there may still be some small glitches in this beta (e.g. github.com/NLog/NLog.Web/issues/234,) but I'm sure they will smooth out)