简体   繁体   English

在 C# 中使用 DI 登录到控制台

[英]Logging to Console with DI in C#

in this short sample, if I keep just the .AddConsole() in ConfigureServices nothing gets logged to console regardless of the LogLevel, but if I add .AddConsole().AddDebug() all messages get logged to Console 3 times!在这个简短的示例中,如果我在ConfigureServices只保留.AddConsole() ,则无论 LogLevel 如何都不会记录到控制台,但是如果我添加.AddConsole().AddDebug()所有消息都会记录到控制台 3 次! What am I missing?我错过了什么? Thanks!谢谢!

namespace samples
{
    using System;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Logging;

    public class Program
    {    
        public static void Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
            var serviceProvider = serviceCollection.BuildServiceProvider();

            var app = serviceProvider.GetService<Application>();
            app.Run();
        }

        private static void ConfigureServices(IServiceCollection services)
        {
            // Add Logger
            services.AddLogging(configure => configure.AddConsole().AddDebug());

            // Register Application
            services.AddTransient<Application>();
        }
    }

    public class Application {
        private readonly ILogger logger;

        public Application(ILogger<Application> logger)
        {
            this.logger = logger;
            this.logger.LogInformation("In Application::ctor");
        }

        public void Run() 
        {
            this.logger.LogInformation("Info: In Application::Run");
            this.logger.LogWarning("Warn: In Application::Run");
            this.logger.LogError("Error: In Application::Run");
            this.logger.LogCritical("Critical: In Application::Run");
        }
    }
}

And this is what gets displayed for each Log*() call:这是每个 Log*() 调用显示的内容:

fail: samples.Application[0]
      Error: In Application::Run
samples.Application: Error: Error: In Application::Run

Update/Solution Thanks @panoskarajohn for figuring this out.更新/解决方案感谢@panoskarajohn解决这个问题。 App.Run() needed to be an async: Change app.Run(); => Task.Run(() => app.Run()).Wait(); App.Run() 需要是异步的:更改app.Run(); => Task.Run(() => app.Run()).Wait(); app.Run(); => Task.Run(() => app.Run()).Wait(); public void Run() => public async Task Run() And should work without debugging() option I cannot find anything on why this happens public void Run() => public async Task Run()并且应该在没有debugging()选项的情况下工作我找不到任何关于为什么会发生这种情况的信息

Anyone knows why?有谁知道为什么?

I am not aware why this is not happening for the addDebug() option.我不知道为什么addDebug()选项没有发生这种情况。

I suppose the AddDebug() has some special configuration, and flushes the output before the program exits.我想AddDebug()有一些特殊的配置,并在程序退出之前刷新输出。 Please if you have any clues enlighten us .如果您有任何线索,请赐教

Why the addConsole() does not work?为什么 addConsole() 不起作用?

Console logging is happening on a background thread.控制台日志记录发生在后台线程上。 So if the application exits too fast then the logger doesn't have time to log -> https://github.com/aspnet/Logging/issues/631因此,如果应用程序退出太快,那么记录器没有时间记录 -> https://github.com/aspnet/Logging/issues/631

So it is not that it is not happening.所以并不是说它没有发生。 It is that it does not have time to write to the console.就是它没有时间写到控制台。 The application exits too fast.应用程序退出太快。

In order to fix this in your code.为了在您的代码中修复此问题。 Add a Console.Read() at the end of your program so that it won't exit.在程序末尾添加Console.Read()使其不会退出。

public static void Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
            var serviceProvider = serviceCollection.BuildServiceProvider();

            var app = serviceProvider.GetService<Application>();
            app.Run();
            Console.Read(); // So the application will not exit and there will be time for the background thread to do its job
        }

Also i came across another solution which is create an asynchronous Task and wait upon it.我还遇到了另一个解决方案,它创建一个异步Task并等待它。

Update the code like this.像这样更新代码。

public static void Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
            var serviceProvider = serviceCollection.BuildServiceProvider();

            var app = serviceProvider.GetService<Application>();
            Task.Run(() => app.Run()).Wait();
        }
// also update your Application run method
public async Task Run()
        {
            logger.LogInformation("Info: In Application::Run");
            logger.LogWarning("Warn: In Application::Run");
            logger.LogError("Error: In Application::Run");
            logger.LogCritical("Critical: In Application::Run");
        }

The end result should look like this.最终结果应该是这样的。

public class Program
    {
        public static void Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();
            ConfigureServices(serviceCollection);
            var serviceProvider = serviceCollection.BuildServiceProvider();

            var app = serviceProvider.GetService<Application>();
            Task.Run(() => app.Run()).Wait();
            Console.Read();
        }

        private static void ConfigureServices(IServiceCollection services)
        {
            // Add Logger
            services.AddLogging(configure =>
            {
                configure.AddConsole();
            }).AddTransient<Application>();
        }
    }

    public class Application
    {
        private readonly ILogger<Application> logger;

        public Application(ILogger<Application> logger)
        {
            this.logger = logger;
            this.logger.LogInformation("In Application::ctor");
        }

        public async Task Run()
        {
            logger.LogInformation("Info: In Application::Run");
            logger.LogWarning("Warn: In Application::Run");
            logger.LogError("Error: In Application::Run");
            logger.LogCritical("Critical: In Application::Run");
        }

        //public void Run()
        //{
        //    logger.LogInformation("Info: In Application::Run");
        //    logger.LogWarning("Warn: In Application::Run");
        //    logger.LogError("Error: In Application::Run");
        //    logger.LogCritical("Critical: In Application::Run");
        //}
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM