Asp.Net Core API disable startup complete message - c#

As part of my application I have a .Net Core API project. Unlike most cases where this project would run as its own process, I have the API run in a thread, among others, in a single process. Also for my project, I have implemented a custom logging system to suit my needs. However, I have come across a slight problem. Every time I run my program, once the API starts, this message is printed to the console:
Hosting environment: Production
Content root path: C:\Users\Path\To\Code
Now listening on: http://*:8000
Application started. Press Ctrl+C to shut down.
I would like to disable this message as there is no need for it, and it clutters up the otherwise well organized console log. I have a screenshot below so you know exactly what I'm talking about:
I have already disabled all other logging for the mvc (removed ILoggerFactory from ConfigureServices and set all logging to "None" in appsettings.json).
How do I go about disabling/suppressing this message?

.NET Core 3.x
Good news!
These annoying messages are not being written by ASP.NET Core using plain Console anymore. Now abstract Logger is used, so startup messages will be written by your logger in configured format, just like any other logs.
But if you want to get rid of these logs all along, you can use one of two following approaches
The first way is to use .ConfigureLogging(...) method on host builder to remove all default providers from logger:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders(); // <-- here
})
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
The other way is to configure .NET Core 3 logger with ConsoleLifetimeOptions in your Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
// ...
services.Configure<ConsoleLifetimeOptions>(opts => opts.SuppressStatusMessages = true);
// ...
}
NOTE: second approach won't disable Kestrel logs about an app being listened on port (but first will)
info: Microsoft.Hosting.Lifetime[0]
Now listening on: https://localhost:5001
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
.NET Core 2.x
These messages can be disabled in 2 ways (besides already mentioned console settings):
1) You can disable them with Environment variable:
"ASPNETCORE_SUPPRESSSTATUSMESSAGES": "true"
2) Or through code (in Program.cs):
WebHost.CreateDefaultBuilder(args)
.UseSetting(WebHostDefaults.SuppressStatusMessagesKey, "True")
or
WebHost.CreateDefaultBuilder(args)
.SuppressStatusMessages(true);

In ASP.NET Core 2.1, use the SuppressStatusMessages method on the WebHostBuilder.
WebHost.CreateDefaultBuilder()
.UseStartup<Startup>()
.SuppressStatusMessages(true);

You could also do this:
var host = BuildWebHost(args);
host.Start();
host.WaitForShutdown();
This will bypass the Console.WriteLine()s.

Removing logger factory won't help, because it is Console.WriteLine() (Ref : Github issue comment) . You need to suppress the Console.WriteLine outputs. In the Main method, write code like this. This will ignore the Console.WriteLine outputs.
public static void Main(string[] args)
{
Console.SetOut(new StreamWriter(Stream.Null));
BuildWebHost(args).Run();
}

Related

Attach console to .Net Windows Service

I currently have several .Net windows services running on my server. Is there a way to attach a console app to the service to get all of the ILogger data? I have had issues where the service runs perfectly as a console app/worker service but as soon as I run it as a windows service, it just sits there and does nothing.
I did find an article about attaching the VS debugger to the process, but this will not work with our network security.
I am open to any other suggestions as well.
The technical answer is no, but as #Fildor mentioned, you would set up a log sink of some sort. The file logger is just an example, but you can also have the logs send emails, post to some cloud logging service such as splunk or cloudwatch, etc.
One issue you may run into is that you need to capture an error prior to ILogger being available and properly configured for you. Here is a guide I followed for capturing startup errors using NLog: https://alistairevans.co.uk/2019/10/04/asp-net-core-3-0-logging-in-the-startup-class-with-nlog/
Startup classes are no longer necessary in the latest .NET version, so I modified their example to be code you would have in Program.cs:
// NLog: setup the nlog config first
NLogBuilder.ConfigureNLog("nlog.config");
try
{
var host = Host.CreateDefaultBuilder(args)
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
// Use NLog to provide ILogger instances.
.UseNLog()
.Build();
host.Run();
}
catch (Exception ex)
{
var logger = nlogLoggerProvider.CreateLogger(typeof(Program).FullName);
}
}
Here's the list of available log sinks you can configure in that nlog configuration file: https://nlog-project.org/config/
This same thing can be accomplished with other log providers you may already be using such as Serilog, Log4Net, etc.

Modifying VS generated gRPC server code to run as Windows Service looks nothing like samples

I'm using Visual Studio 2022 to create a gRPC server and would like to turn it into a Windows Service. I've created and tested the server but when I look at the examples on the web, none of them look like the program.cs created by VS shown here:
using eTutorService.Services;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddGrpc();
var app = builder.Build();
app.MapGrpcService<eTutorServiceMain>();
app.MapGet("/", () => "Communication with gRPC must be made through a gRPC client...");
app.Run();
Everything I find adds "UseWindowsService" to CreateDefaultBuilder like the following:
Host.CreateDefaultBuilder(args)
.UseWindowsService()
...
or
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseWindowsService() // Enable running as a Windows service
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
But I can't find how the "CreateHostBuilder" stuff relates to the "WebApplication.CreateBuilder" code created by VS. CreateBuilder doesn't support .UseWindowsService and WebApplication doesn't support CreateDefaultBuilder.
EDIT:
I was able to add UseWindowsService like this:
builder.Services.AddGrpc();
builder.Host
.UseWindowsService(options =>
{
options.ServiceName = "CADE eTutor Core Service";
});
It compiles and I added it to the Windows Services with that ServiceName using SC at the command line, but it fails to start with error 1053, "The service did not respond to the start or control request in a timely fashion".
Looking in the event log I see this error referencing the UseWindowService line.
Changing the host configuration using WebApplicationBuilder.Host is not supported. Use WebApplication.CreateBuilder(WebApplicationOptions) instead.
So I'm basically lost as to how to take the gRPC template created by VS and turn it into a Windows Service.
Well, apparently Microsoft has changed how services are created, https://github.com/dotnet/AspNetCore.Docs/issues/23387 and I found the fix there. I can't say I really appreciate why this is necessary but the following code worked as far as allowing the program to run as a Windows Service:
var options = new WebApplicationOptions
{
Args = args,
ContentRootPath = WindowsServiceHelpers.IsWindowsService() ? AppContext.BaseDirectory : default
};
var builder = WebApplication.CreateBuilder(options);

Why does my Asp.Net Core app, running as MS-service, immediately stop?

I wrote an Asp.Net Core app which is supposed to run as a MS-service in the back, however whenever I start it, it immediately stops. The URLs for my service are being read from a .config file and everything seems to work when normally starting my app.
I first published my app using Jetbrain's Rider with the following settings:
Then I tried to add it with the following command:
sc.exe create MyService binPath= "some\path\to\publish\to\MyService.exe"
It worked, and starting it via sc.exe start MyService also returned me a success message, however whenever I look at the list of services running in the Windows 10 tool, it says that my service stopped. Does the reading of URLs have something to do with it? If so, how else should I read my URLs from external sources?
Program.cs, CreateHostBuilder():
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
.ConfigureWebHost(config =>
{
//Set the urls and ports where the service should run.
config.UseUrls(Config.HttpsUrl, Config.HttpUrl);
//Run as MS service.
})
.UseWindowsService();
When adding it as a MS-service I looked at the following article.

ASP .Net Core RESTful App Deployed as Windows Service is not Working / Starting

I am working with some sort a small RESTful layer to expose (to the internet) the local application data in a host machine.
It behaves like a typical web service that listens incoming request to a port. I wrote it with ASP .NET Core 3.1 with a tiny layer wrapper called Carter, it has also a DLL / COM Reference (used for querying the data).
I followed the following guides to configure it as a windows service, publish the service, and then to create it.
https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/windows-service?view=aspnetcore-5.0&tabs=visual-studio
https://dotnetcoretutorials.com/2019/12/21/hosting-an-asp-net-core-web-app-as-a-windows-service-in-net-core-3/
I did successfully created a service but it won't start and windows is showing this error dialog.
I am relatively new to .NET development and I am not sure what's wrong here or how to fix this.
Program.cs
namespace Adapter
{
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
public class Program
{
public static void Main(string[] args)
{
var host = Host.CreateDefaultBuilder(args)
.UseWindowsService()
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.Build();
host.Run();
}
}
}
Startup.cs
namespace Adapter
{
public class Startup
{
public Startup()
{
// load the env values during start up
new Env().Load();
}
public void ConfigureServices(IServiceCollection services)
{
// interface binding for dependency injection
services.AddSingleTonServices();
// carter and routing services
services.AddCarter();
services.AddRouting();
services.AddHostedService<Worker>();
}
public void Configure(IApplicationBuilder app)
{
app.UseRouting();
app.UseEndpoints(builder => builder.MapCarter());
}
}
}
BTW My project is running correctly when you run or debug it in visual studio.
Any help or idea will be much appreciated.
Error 1053: The service did not respond to the start or control request in a timely fashion is the problem caused by the timeout after the particular request.
This error has many variants.You can read this article to try to solve:
[Fix] Error 1053: The service did not respond to the start or control request in a timely fashion
Alternatively, to resolve this issue, you can download the following registry fix for your operating system:
Windows Search “Error 1053” Fix for Windows 7
Windows Search “Error 1053” Fix for Windows 8.1
Windows Search “Error 1053” Fix for Windows 10

NLog console doesn't work on dotnet publish

So I am trying to run NLog on dotnet core (let's say 2.1.202) so I specifically want it to work with the console output stream. And I want to get as many messages as possible (yeah, logging..) so I've implemented a simple Tracer : TraceListener. So far so good and even if I try to run it via dotnet run it still works pretty well (everything is printed at console as it should be). However, if I try to run the web application via
dotnet publish
dotnet MyProjectName.dll
It fails. No log messages are actually being displayed and the project runs smoothly. So does anyone knows a way to print log messages on console via "publish" method.
Here is my Program.cs file (That's the only place where I mention Nlog, no specific services/configurations in Startup.cs)
public class Program
{
public static void Main(string[] args)
{
var host = BuildWebHost(args);
var logger = NLogBuilder.ConfigureNLog("nlog.config").GetCurrentClassLogger();
Trace.Listeners.Add(new Tracer(logger));
try
{
Trace.WriteLine("init main");
host.Run();
}
catch (Exception ex)
{
Trace.Fail(ex.ToString());
}
finally
{
NLog.LogManager.Shutdown();
}
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Trace);
})
.UseNLog()
.Build();
}
To be fair I've checked the given example from NLog and it actually works (from publish) but still I cannot find my problem in my app.
So if somebody done something like that and knows what I am missing here to run logs via publish it would be very helpful. Cheers!
So the problem was that there was internal second nlog.config (in a class library project) which was overriding my default nlog.config from the web project.
Shoutout to Julian for giving the idea to check internal nlog log - very helpful indeed.

Categories