ASP.NET Core Logging does not work on Production

9k views Asked by At

Turns out the issue was not anyway related to NLog or ASP.NET Logging system. Logging was configured correctly but the build server was publishing a Debug build to the Production due to a configuration error.

I am trying to setup a third party logger in my ASP.NET Core 2.0 (SDK 2.1.401) project. So far I have tried Serilog and NLog. However I am having same issue for both. To summarise the issue,

  • It works as intended when I run the app like dotnet run (ie. In Development environment)
  • But it does not when I run the binary dotnet MyApplication.dll (ie. In Production environment).
  • I do not have anything defined in "Logging" section for Development environment in my appsettings.Development.json file.

The issue described below is for NLog. I have tried SeriLog and hit the same issue.

Here is the relevant part from Program.cs

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseApplicationInsights()
        .UseStartup<Startup>()
        .ConfigureLogging((env, logging) =>
        {
            logging.ClearProviders();
            logging.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Trace);
        })
        .UseNLog()
        .Build();

Note I have cleared all providers and added NLog also the nlog.config file is defined:

<?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="error"
  internalLogFile="./internal-nlog.txt">

  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <targets>
    <target name="Console" 
      xsi:type="Console" 
      layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="Console" />
  </rules>
</nlog>

When running in Development mode, I see the logs exactly as I expected

$ dotnet run
Using launch settings from .. /Properties/launchSettings.json...
2018-09-16 19:04:39.7585||DEBUG|My.WebApp.Program|init main |url: |action:
Hosting environment: Development
Content root path: /Users/ ...
Now listening on: http://localhost:61638
Application started. Press Ctrl+C to shut down.
2018-09-16 19:04:46.5405|1|INFO|Microsoft.AspNetCore.Hosting.Internal.WebHost|Request starting HTTP/1.1 GET http://localhost:61638/api/_doc   |url: http://localhost/api/_doc|action:
2018-09-16 19:04:46.7381|1|INFO|Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker|Executing action method My.WebApp.RestApi.Doc (My.WebApp) with arguments ((null)) - ModelState is Valid |url: http://localhost/api/_doc|action: Doc

However, when I run the app in Production envoronment, the console output looks as if I do not have NLog installed and I haven't cleared the default providers.

dotnet .\My.WebApp.dll
Hosting environment: Production
Content root path: C:\inetpub\wwwroot\myapp\wwwroot
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
      Request starting HTTP/1.1 GET http://localhost:5000/
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
      Executing action method My.WebApp.Controllers.HomeController.Index (My.WebApp) with arguments ((null)) - ModelState is Valid

Notice those lines begins with info:? those are standard console logging format you get when you use the default logging setup defined in Microsoft.Extensions.Logging. But I definitely cleared Console provider by calling logging.ClearProviders(); in the Program.cs file.

Thanks for any help.

1

There are 1 answers

3
Gopi On

I was able to reproduce your problem and fix it. Please find my configuration here.

appsettings.json

{
  "Logging": {
    "LogLevel": {
      "Default": "Trace",
      "Microsoft": "Information"
    }
  },
  "AllowedHosts": "*"
}

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="error"
      internalLogFile="./internal-nlog.txt">

  <extensions>
    <add assembly="NLog.Web.AspNetCore"/>
  </extensions>

  <targets>
    <target name="Console"
            xsi:type="Console"
            layout="${longdate}|${event-properties:item=EventId_Id}|${uppercase:${level}}|${logger}|${message} ${exception:format=tostring}|url: ${aspnet-request-url}|action: ${aspnet-mvc-action}" />
  </targets>

  <rules>
    <logger name="*" minlevel="Trace" writeTo="Console" />

    <!--Skip non-critical Microsoft logs and so log only own logs-->
    <logger name="Microsoft.*" maxLevel="Info" final="true" />
    <!-- BlackHole without writeTo -->
    <logger name="*" minlevel="Trace" writeTo="Console" />
  </rules>
</nlog>

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();

        try
        {
            logger.Debug("init main");
            CreateWebHostBuilder(args).Build().Run();
        }
        catch (Exception ex)
        {
            //NLog: catch setup errors
            logger.Error(ex, "Stopped program because of exception");
            throw;
        }
        finally
        {
            // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux)
            NLog.LogManager.Shutdown();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .ConfigureLogging((env, logging) =>
            {
                logging.ClearProviders();
                logging.SetMinimumLevel(LogLevel.Trace);
            })
            .UseNLog();
}

added the following entry to .csproj file

<ItemGroup>
    <Content Update="nlog.config">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </Content>
</ItemGroup>

Reference:

  1. https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2