9

I'm building a .Net Core 3.1 console app and I want to use the build in console logging. There are a zillion articles on .net logging, but I have not been able to find a sample that actually does write in the console.

   namespace test
   {
      class Program
      {

        static void Main(string[] args)
        {
            var serviceProvider = new ServiceCollection()
                .AddLogging(config => config.ClearProviders().AddConsole().SetMinimumLevel(LogLevel.Trace))
                .BuildServiceProvider();

            //configure console logging
            serviceProvider
                .GetService<ILoggerFactory>();


            var logger = serviceProvider.GetService<ILoggerFactory>()
                .CreateLogger<Program>();

            logger.LogDebug("All done!");

            Console.Write("Yup");
        }
    }

It compiles and runs, and even writes "Yup" to the console, but the "All done!" is not shown. Output in console window:console-output

This is my sample project structure: enter image description here

What am I missing?

It was a dispose of Services: Fix thanks to Jeremy Lakeman:

            static void Main(string[] args)
        {
            using (var serviceProvider = new ServiceCollection()
                .AddLogging(config => config.ClearProviders().AddConsole().SetMinimumLevel(LogLevel.Trace))
                .BuildServiceProvider())
            {
                //configure console logging
                serviceProvider
                    .GetService<ILoggerFactory>();


                var logger = serviceProvider.GetService<ILoggerFactory>()
                    .CreateLogger<Program>();

                // run app logic

                logger.LogDebug("All done!");
            }

            Console.Write("Yup");
        }
k.c.
  • 1,755
  • 1
  • 29
  • 53
  • Cannot reproduce the problem, it does write the text `"Yup"` as well generate the log entry "All done!". – Progman Jun 18 '20 at 17:04
  • @Progman Thanks for your time. I have updated the question so to provide my complete solution, if yours works, maybe we can compare notes. Do I need to add an additional config or something – k.c. Jun 19 '20 at 06:43
  • Logging can be buffered, you aren't disposing everything – Jeremy Lakeman Jun 19 '20 at 06:44
  • @JeremyLakeman Which items should be disposed? I saw none of that in the 3.1 logging samples, there where some usings in the 2.x version docu, but that would not even compile – k.c. Jun 19 '20 at 06:49
  • 1
    The `IServiceProvider` implementation should be `IDisposable`. – Jeremy Lakeman Jun 19 '20 at 06:52
  • Check this answer https://stackoverflow.com/a/51329388/9695286. Adding `serviceProvider.Dispose();` at end of `Main` worked for me. – Karan Jun 19 '20 at 06:55
  • 1
    Does this answer your question? [Logging in .Net core console application not working](https://stackoverflow.com/questions/51326463/logging-in-net-core-console-application-not-working) – Karan Jun 19 '20 at 06:56
  • @Karan No, it does not:."AddLogging(config => config.ClearProviders().AddConsole().SetMinimumLevel(LogLevel.Trace).AddDebug())" Does not compile. How would you make my sample work. The question you refer to is quite old and maybe on an older version of Core? – k.c. Jun 19 '20 at 07:02
  • @ Jeremy I have added a dispose at the end of the service provider and that works! Thanks. – k.c. Jun 19 '20 at 07:16
  • 1
    @JeremyLakeman if you add a short answer, I can give you the proper points for your solution – k.c. Jun 19 '20 at 07:25
  • Add **`serviceProvider.Dispose();`** at the end of `static void Main` and you will see `All done!`. You don't need to change anything else. – Karan Jun 19 '20 at 07:38

2 Answers2

5

I might be late but worth adding some inputs in case it helps. I was also struggling with this logging in .net core and keep having breaking changes with the latest release. However, can't complain as it keeps getting better and better. Here is what I have done with the .net core 5 released.

public static class ApplicationLogging
{
    public static ILoggerFactory LogFactory { get; } = LoggerFactory.Create(builder =>
    {
        builder.ClearProviders();
        // Clear Microsoft's default providers (like eventlogs and others)
        builder.AddSimpleConsole(options =>
            {
                options.IncludeScopes = true;
                options.SingleLine = true;
                options.TimestampFormat = "hh:mm:ss ";
            }).SetMinimumLevel(LogLevel.Warning);
    });

    public static ILogger<T> CreateLogger<T>() => LogFactory.CreateLogger<T>();
}

static void Main(string[] args)
{
    var logger = ApplicationLogging.CreateLogger<Program>();
    logger.LogInformation("Let's do some work");
    logger.LogWarning("I am going Crazy now!!!");
    logger.LogInformation("Seems like we are finished our work!");
    Console.ReadLine();
}
Valeriy Y.
  • 43
  • 1
  • 5
Brijesh Shah
  • 573
  • 6
  • 18
2

So that logging doesn't adversely impact the performance of your program, it may be written asynchronously.

Disposing the log provider and other logging classes should cause the log to flush.

The service provider should also dispose all services when it is disposed.

Jeremy Lakeman
  • 9,515
  • 25
  • 29
  • So....how do I do this with a Console App that runs a process on an Interval? If I dispose of the IServiceProvider, then my services all get disposed but I want to have live updates in the console. – jasonxz Sep 04 '21 at 02:22