top of page

Advanced NLog features in ASP.NET Core

What is NLog?

NLog is an open source lightweight logging framework, which provides rich log routing and management functions. At the same time, NLog is also very easy to configure and expand. In fact, I have discussed NLog in the previous article.


Core Features of NLog

  1. Simple to get started – it takes just 3-4 lines of code to get you started with this popular logging framework.

  2. Template Rendering – Complete control to structure the logging messages via your own defined templates.

  3. FREE – NLog is an Open Source Project, completely FREE to use.

  4. Structured Logging at it’s best.

  5. Well maintained documentation – You can never get stuck while using this framework. They have an above-decent documentation with almost everything packed up.


Install NLog

Can passNuGet Package ManagerVisual interface orNuGet Package Manager ConsoleThe console installs the following package files.

  • NLog.Web.AspNetCore

  • NLog.Extensions.Logging

  • NLog.Config

When you finish installingNLog.ConfigAfter that, there was one calledNLog.configThe file will be automatically referenced into your project. It is worth noting that,NLog.ConfigIt is not unique to NLog. The implication is that you can use either config mode orCode basedMode configuration.


Use the. Config file to configure NLog

NLog provides two configurations.

  • file-basedConfiguration mode

  • code-basedConfiguration mode

Back to the question just now, how to usefile-basedThe nlog.config introduced just now is as follows:

<?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"autoReload="true">
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<targets>
<target name="logfile" xsi:type="File" fileName="D:\logs\LogMessages-${shortdate}.log" />
</targets>
<rules>
<logger name="*" minlevel="Trace" writeTo="logfile" />
</rules>
</nlog>

The following code shows how to log with NLog under controller.

public class HomeController : Controller
{
     Logger _logger = (Logger)LogManager.GetCurrentClassLogger(typeof(Logger));
     
     public IActionResult Index()
     {         
        _logger.Info("Application started");
        return View();
    }
    //Other action methods
}

If you want to find the target of the current NLog programmatically, you can use the following code:

var fileTarget = (FileTarget)LogManager.Configuration.FindTargetByName("logfile");


Configuring NLog with code

Similarly, you can configure NLog in the form of coding. You only need to call the API interface provided by NLog. The following code shows how to configure NLog.

private static void ConfigureNLog()
{
      var logConfiguration = new LoggingConfiguration();
      var dbTarget = new DatabaseTarget();
      dbTarget.ConnectionString = "Data Source=JOYDIP;
            initial catalog=NLogDemo;User Id=sa;
            Password=sa1@3#.;"; 
      dbTarget.CommandText = "INSERT INTO DbLog (level, callsite, message, logdatetime)" +" Values(@level, @callsite, @message, @logdatetime)";
      
      dbTarget.Parameters.Add(new DatabaseParameterInfo("@level", "${level}"));
      
      dbTarget.Parameters.Add(new DatabaseParameterInfo("@callSite", "${callSite}"));
      
      dbTarget.Parameters.Add(new DatabaseParameterInfo("@message", "${message}"));
      
      dbTarget.Parameters.Add(new DatabaseParameterInfo("@logdatetime","${date:s}"));
      var rule = new LoggingRule("*", LogLevel.Debug, dbTarget);
      
      logConfiguration.LoggingRules.Add(rule);
      LogManager.Configuration = logConfiguration;
}


Configure rotation log

You can make NLog automaticRotation log, what do you meanRotationAnd? To put it simply: you can let NLog only save logs for nearly n hours and automatically delete logs greater than n hours. This feature is too practical. Otherwise, you need to often delete logs in production. The following code shows how to use it.configRealize automatic rotation log.

<?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"autoReload="true">
<targets>
    <target name="logfile"
            xsi:type="File"
            fileName="${basedir}/logs/App.log"
            layout="${longdate}  ${message}"
            archiveFileName="${basedir}/logs/archive.{#}.log"
            archiveEvery="Day"
            archiveNumbering="Rolling"
            maxArchiveFiles="7"
            concurrentWrites="true"
            keepFileOpen="true" />
</targets>
<rules>
    <logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>


Log to database


Create database

You can use NLog to access logs into the database. The following script is used to create several log tables.

CREATE TABLE [dbo].[DbLog](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Level] [varchar](max) NULL,
    [CallSite] [varchar](max) NULL,
    [Message] [varchar](max) NULL,
    [AdditionalInfo] [varchar](max) NULL,
    [LogDateTime] [datetime] NOT NULL, 
CONSTRAINT [PK_DbLogs] PRIMARY KEY CLUSTERED
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO


Database connection string and parameter properties

Next, please note how to specify the database connection string in the target of NLogconnectionStringandcommandTextHow is it configured.

<target name="database" xsi:type="Database" keepConnection="true"useTransactions="true"dbProvider="System.Data.SqlClient"connectionString="data source=localhost;initial
 catalog=NLogDemo;integrated security=false;
 persist security info=True;User ID=sa;Password=sa1@3#."commandText="INSERT INTO DbLog (level, callsite, message, additionalInfo,
 logdatetime) Values (@level, @callsite, @message, @additionalInfo,
 @logdatetime)">


Use parameterization

Finally, useParameterized queryTo prevent injection attacks, the detailed code is as follows.

<parameter name="@level" layout="${level}" />
<parameter name="@callSite" layout="${callsite}" />
<parameter name="@message" layout="${message}" />
<parameter name="@additionalInfo" layout="${var:AdditionalInfo}" />
<parameter name="@logdatetime" layout="${date:s}" />


Complete NLog

The following is a complete NLog file for reference only.

<?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"autoReload="true">
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<variable name="AdditionalInfo" value=""/>
<targets>
<target name="database" xsi:type="Database" keepConnection="true"
useTransactions="true"
dbProvider="System.Data.SqlClient"
connectionString="data source=localhost;initial
    
catalog=NLogDemo;integrated security=false;persist security  
    
info=True;User ID=sa;Password=sa1@3#."
commandText="INSERT INTO DbLog
    (level, callsite, message, additionalInfo, logdatetime)
    Values (@level, @callsite, @message, @additionalInfo, @logdatetime)">
<parameter name="@level" layout="${level}" />
<parameter name="@callSite" layout="${callsite}" />
<parameter name="@message" layout="${message}" />
<parameter name="@additionalInfo" layout="${var:AdditionalInfo}" />
<parameter name="@logdatetime" layout="${date:s}" />
</target>
</targets>
<rules>
<logger levels="Debug,Info,Error,Warn,Fatal" name="databaseLogger" writeTo="database"/>
</rules>
</nlog>

exceptSQL ServerIn addition, you can use NLog to log toMySQL,OracleandSQLitedatabase


Using asyncwrapper to improve performance

NLog supports a variety of targets, such as asyncwrapper, bufferingwrapper, fallbackgroup and retryingwrapper. Asynchronous targets are used to improve performanceQueuing of messagesAnd extract queue messages from multiple threads. The following code shows how to use itAsyncWrapper。

<targets>
    <target xsi:type="AsyncWrapper"
                name="String"
                queueLimit="Integer"
                timeToSleepBetweenBatches="Integer"
                batchSize="Integer"
                overflowAction="Enum">
    <target ... />
  </target>
</targets>


You can achieveAsyncWrapperTo realize asynchronous logging. The detailed configuration is as follows:

<targets>
    <target name="asyncFile" xsi:type="AsyncWrapper">
        <target xsi:type="File" name="fileLog"
            fileName="${basedir}/Logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}"/>
        </target>
</targets>
<rules>
    <logger levels="Debug,Info,Error,Warn,Fatal" writeTo="asyncFile"/>
</rules>

In addition to this method, you can also use it on all targetsasync=trueDirectly mark as asynchronous target, as shown in the following configuration:

<targets async="true">
  ... Write your targets here ...
</targets>


Reource: developpaper.com


The Tech Platform

www.thetechplatform.com

0 comments
bottom of page