NLog / NLog.Extensions.Logging

NLog as Logging Provider for Microsoft Extension Logging
https://nlog-project.org
BSD 2-Clause "Simplified" License
392 stars 150 forks source link

Default .NET Core NLog setup breaks ConfigSettingRenderLayout #404

Closed SirBisgaard closed 4 years ago

SirBisgaard commented 4 years ago

Bug

NLog version: 4.6.8 NLog.Extensions.Logging version: 1.6.1 NLog.Web.AspNetCore version: 4.9.0

Platform: .NET Core 3.2 Current 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"
      autoReload="true"
      internalLogLevel="Info"
      internalLogFile="c:\temp\internal-nlog.txt">

  <!-- enable asp.net core layout renderers -->
  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <!-- the targets to write to -->
  <targets>
    <target name="database" xsi:type="Database" dbProvider="Microsoft.Data.SqlClient.SqlConnection, Microsoft.Data.SqlClient"
            connectionString="${configsetting:name=ConnectionStrings.NLOG}">
      <commandText>
        EXEC LogInsert @MachineName, @Service, @Logged, @Identity, @CorrelationId, @Level, @Message, @Logger, @Callsite, @Exception
      </commandText>
      <parameter name="@MachineName" layout="${machinename}" />
      <parameter name="@Logged" layout="${date}" />
      <parameter name="@Service" layout="FTZPlusGlobalApi" />
      <parameter name="@Identity" layout="${aspnet-user-identity}" />
      <parameter name="@CorrelationId" layout="${activityid}" />
      <parameter name="@Level" layout="${level}" /> 
      <parameter name="@Message" layout="${message}" />
      <parameter name="@Logger" layout="${logger}" />
      <parameter name="@Callsite" layout="${callsite}" />
      <parameter name="@Exception" layout="${exception:tostring}" />
    </target>

    <!-- write logs to file  -->
    <target xsi:type="File" name="allfile" fileName="c:\temp\nlog-all-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}" />

    <!-- another file log, only own logs. Uses some ASP.NET core renderers -->
    <target xsi:type="File" name="ownFile-web" fileName="c:\temp\nlog-own-${shortdate}.log"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
  </targets>

  <!-- rules to map from logger name to target -->
  <rules>
    <!--Skip non-critical Microsoft logs and so log only own logs-->
    <!--<logger name="Microsoft.*" maxlevel="Info" final="true" />-->
    <!--All logs, including from Microsoft-->
    <!--<logger name="*" minlevel="Trace" writeTo="allfile" />-->
    <logger name="*" minlevel="Trace" writeTo="database" />
    <!-- BlackHole without writeTo -->
    <!--<logger name="*" minlevel="Trace" writeTo="ownFile-web" />-->
  </rules>
</nlog>
SirBisgaard commented 4 years ago

Jesus, I hope my issue will be found with this Id #404...

snakefoot commented 4 years ago

Sounds like a duplicate of #265 . NLog cannot read ${configsetting}-options before having loaded appsettings.json.

Chicken and the egg problem. You want the logging-framework up and running early, but suddenly it depends on having loaded appsettings.json.

I'm hoping that LogFactory.Setup in NLog 4.7 will make it easier to hook NLog together with Extension Logging (and friends). Thus removing NLogBuilder.ConfigureNLog("nlog.config")

SirBisgaard commented 4 years ago

It is like that issue #265. But should the documentation not be changed to match this problem? For example on the layout render it should state that this problem will occur when using web APIs.

snakefoot commented 4 years ago

@SirBisgaard You are completely right. Think the problem is that I have never used NLog.Extensions.Logging for anything. So I'm not the best person for writing documentation for this. I have tried to explain how it works here:

https://github.com/NLog/NLog/wiki/ConfigSetting-Layout-Renderer

But I have also tried to implement logic so it will automatically register itself using AddNLog and UseNLog (To make it more userfriendly, as you have witnessed when not using NLogBuilder). Ofcourse this is not possible using NLogBuilder.ConfigureNLog (Happens before HostBuilder). Which is the reason I will try to get rid of it and instead replace it with extension-methods on LogFactory.Setup in NLog 4.7.

Again NLog is a community project that is developed in peoples spare time. The more contribution the project gets the faster the development will become.

snakefoot commented 4 years ago

With NLog.Web.AspNetCore ver. 4.9.3 then you can replace this:

var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

With:

var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();

Allowing logging to work before having started hosting-environment.