Hosting Lifetime Startup Messages (original) (raw)
Hosting Lifetime Startup Messages
AspNetCore v2 applications will print the following magic messages directly to Console:
Now listening on: https://[::]:443
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.
AspNetCore v3 applications will print the following magic messages to Microsoft.Hosting.Lifetime-Logger:
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
The hosting application (Visual Studio / IIS / Docker / Azure Container) will hook into the console output, and will fail to recognize the application as running if this output is not generated (Long delays or nothing happening). Ex. Visual Studio Code uses this serverReadyAction filter by default:
"serverReadyAction": {
"action": "openExternally",
"pattern": "^\s*Now listening on:\s+(https?://\S+)"
}
Because ASP.NET Core 3 now uses the MEL-ILogger to write these messages, then it is important to NOT discard the output from the Microsoft.Hosting.Lifetime-Logger (or changing the expected output format).
Setup Microsoft Extension Logging Filter
The Microsoft Extension Logging is by default very chatty even on Info-Level, so many setup filters to only output warnings (or higher severity) from Microsoft.*-Loggers. This will also discard the important startup messages from the Microsoft.Hosting.Lifetime-Logger.
Example of appsettings.json with special filter rule for Microsoft.Hosting.Lifetime:
{ "Logging": { "IncludeScopes": false, "LogLevel": { "Default": "Trace", "Microsoft": "Warning", "Microsoft.Hosting.Lifetime": "Information" } }, "AllowedHosts": "*" }
Setup NLog Console Logger in AspNetCore v3
Extending the NLog.config from the NLog ASP.NET Core v3 Tutorial, so the NLog Console will output the Lifetime Startup Messages:
<!-- 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} <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>e</mi><mi>x</mi><mi>c</mi><mi>e</mi><mi>p</mi><mi>t</mi><mi>i</mi><mi>o</mi><mi>n</mi><mo>:</mo><mi>f</mi><mi>o</mi><mi>r</mi><mi>m</mi><mi>a</mi><mi>t</mi><mo>=</mo><mi>t</mi><mi>o</mi><mi>s</mi><mi>t</mi><mi>r</mi><mi>i</mi><mi>n</mi><mi>g</mi></mrow><mi mathvariant="normal">∣</mi><mi>u</mi><mi>r</mi><mi>l</mi><mo>:</mo></mrow><annotation encoding="application/x-tex">{exception:format=tostring}|url: </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal">e</span><span class="mord mathnormal">x</span><span class="mord mathnormal">ce</span><span class="mord mathnormal">pt</span><span class="mord mathnormal">i</span><span class="mord mathnormal">o</span><span class="mord mathnormal">n</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal" style="margin-right:0.10764em;">f</span><span class="mord mathnormal" style="margin-right:0.02778em;">or</span><span class="mord mathnormal">ma</span><span class="mord mathnormal">t</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">=</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mord mathnormal">t</span><span class="mord mathnormal">os</span><span class="mord mathnormal">t</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal">in</span><span class="mord mathnormal" style="margin-right:0.03588em;">g</span></span><span class="mord">∣</span><span class="mord mathnormal">u</span><span class="mord mathnormal" style="margin-right:0.02778em;">r</span><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mspace" style="margin-right:0.2778em;"></span><span class="mrel">:</span></span></span></span>{aspnet-request-url}|action: ${aspnet-mvc-action}" />
<target xsi:type="Console" name="lifetimeConsole"
layout="${level:truncate=4:lowercase=true}: <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mrow><mi>l</mi><mi>o</mi><mi>g</mi><mi>g</mi><mi>e</mi><mi>r</mi></mrow><mo stretchy="false">[</mo><mn>0</mn><mo stretchy="false">]</mo></mrow><annotation encoding="application/x-tex">{logger}[0]</annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:1em;vertical-align:-0.25em;"></span><span class="mord"><span class="mord mathnormal" style="margin-right:0.01968em;">l</span><span class="mord mathnormal">o</span><span class="mord mathnormal" style="margin-right:0.03588em;">gg</span><span class="mord mathnormal" style="margin-right:0.02778em;">er</span></span><span class="mopen">[</span><span class="mord">0</span><span class="mclose">]</span></span></span></span>{newline} ${message}" />
<!--Output hosting lifetime messages to make Docker / Visual Studio happy -->
<logger name="Microsoft.Hosting.Lifetime" level="Info" writeTo="lifetimeConsole, ownFile-web" final="true" />
<!--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="ownFile-web" />
Notice that NLog.Extensions.Logging v1.7.5 introduces the layout-renderer ${MicrosoftConsoleLayout}. It can be used like this: <target xsi:type="Console" name="lifetimeConsole" layout="${MicrosoftConsoleLayout}" />
See also: NLog Console vs. AddConsole.
Suppressing Startup Messages in AspNetCore v2.1
AspNetCore v2.1 WebHostBuilder can be configured to disable the direct output to Console:
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.SuppressStatusMessagesKey, "True") // add this line
.UseStartup<Startup>();This is similar to adding this environment variable: ASPNETCORE_SUPPRESSSTATUSMESSAGES = TRUE
See also Suppressing the startup and shutdown messages in ASP.NET Core
Suppressing Startup Messages in AspNetCore v3
AspNetCore v3 HostBuilder can be configured to disable output to Microsoft.Hosting.Lifetime-Logger:
public class Startup { public void ConfigureServices(IServiceCollection services) { // ... other configuration services.Configure(opts => opts.SuppressStatusMessages = true); } }
This will also prevent NLog from receiving the output.
See also ASP.NET Core 3.0: structured logging for startup messages