Reputation: 67948
I've got a .NET Core console app. Pretty simple. At this point the goal was just to get DI and Configuration integrated. However, the LogDebug
isn't logging to the console.
What could I have possibly done wrong here?
class Program
{
static void Main(string[] args)
{
var topic = Environment.GetEnvironmentVariable("RECEIVER_TOPIC");
var entity = Environment.GetEnvironmentVariable("RECEIVER_ENTITY");
//setup our DI
var serviceProvider = new ServiceCollection()
.AddLogging()
.BuildServiceProvider();
//configure console logging
serviceProvider
.GetService<ILoggerFactory>()
.AddConsole(LogLevel.Debug);
var logger = serviceProvider
.GetService<ILoggerFactory>()
.CreateLogger<Program>();
logger.LogDebug($"Starting application. Topic: {topic}. Entity: {entity}.");
if (Debugger.IsAttached)
{
Console.ReadLine();
}
}
static IConfigurationRoot GetConfiguration()
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
return builder.Build();
}
}
I added the Microsoft.Extensions.Logging.Debug
NuGet package, and modified the serviceProvider
initialization to append the AddDebug
like so:
serviceProvider
.GetService<ILoggerFactory>()
.AddConsole(LogLevel.Debug)
.AddDebug();
But it's not even logging to the Debug
window.
Upvotes: 5
Views: 11106
Reputation: 1
Add logging.AddDebug(); works for me. Thanks a lot!
.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddConsole();
logging.AddDebug();
})
Updated: I've finally found the reason. In the Visual Studio, the output window is not the console, it is for the Debug provider. so that's why I could not see any logs inside it. When I published the project to a folder and then execute the .exe file, it opens a console, the is the place that the console provider take affect!
Upvotes: 0
Reputation: 4107
I just wanted to chip in with a revised ConfigureServices method which makes use of the logging section in an appsetting.json file.
First, I added an appsettings.json which looks like this:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning"
}
}
}
The, my ConfigureServices method:
static void ConfigureServices(IServiceCollection serviceCollection)
{
// Build configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", false)
.Build();
// Add logging
serviceCollection.AddLogging(config =>
{
// clear out default configuration
config.ClearProviders();
config.AddConfiguration(configuration.GetSection("Logging"));
config.AddDebug();
});
}
Note, no need to add ILogger
and ILoggerFactory
to the ServiceProvider
.
I believe this is handled in the AddLogging
extension method.
Upvotes: 0
Reputation: 470
I recently ran into the same exact problem, saw your answer, but did not understand why 'AddDebug()' was necessary. Removing it though stops the logger from logging to console. See Logging to Console with DI in C# if interested. My guess is that Console logger spins off a separate thread and tries to aggregate logs and flush on timer to not be as intrusive. The Debug logger logs immediately, but I only wanted one. Switching to having an App class with async Run() method solves all problems.
Upvotes: 2
Reputation: 67948
Got it working. I think the key was that I wasn't yet clear that concretes needed to be registered because I thought the extension was registering the concretes.
class Program
{
static void Main(string[] args)
{
var topic = Environment.GetEnvironmentVariable("RECEIVER_TOPIC");
var entity = Environment.GetEnvironmentVariable("RECEIVER_ENTITY");
// Create service collection
var serviceCollection = new ServiceCollection();
ConfigureServices(serviceCollection);
// Create service provider
var serviceProvider = serviceCollection.BuildServiceProvider();
var logger = serviceProvider
.GetRequiredService<ILoggerFactory>()
.CreateLogger<Program>();
logger.LogDebug($"Starting application. Topic: {topic}. Entity: {entity}.");
if (Debugger.IsAttached)
{
Console.ReadLine();
}
}
static void ConfigureServices(IServiceCollection serviceCollection)
{
// Add logging
serviceCollection.AddSingleton<ILoggerFactory, LoggerFactory>();
serviceCollection.AddSingleton(typeof(ILogger<>), typeof(Logger<>));
serviceCollection.AddLogging(loggingBuilder => loggingBuilder
.AddConsole()
.AddDebug()
.SetMinimumLevel(LogLevel.Debug));
// Build configuration
var configuration = new ConfigurationBuilder()
.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", false)
.Build();
// Add access to generic IConfigurationRoot
serviceCollection.AddSingleton(configuration);
}
}
Upvotes: 9