首页 > 解决方案 > Console.SetOut 不适用于 ConsoleLogger

问题描述

在我的 asp.net 应用程序中,我在调试时使用 ConsoleLogger。

services.AddLogging(builder => builder.AddConsole());

在集成测试中,我试图获得这样的控制台输出

var strWriter = new StringWriter();
Console.SetOut(strWriter);

// some code that has a lot of logging

var consoleOutput = strWriter.ToString();

并且 consoleOutput 是一个空字符串。

ConsoleLogger 有这个问题吗?如何获得控制台输出?

标签: c#asp.net.net

解决方案


不知道你为什么要这样做甚至更多 - 我会说你不应该这样做,至少这样,但如果你仍然想要 - 你将需要Console.SetOut在写入第一条消息以记录之前,即在 ASP.NET Core 的情况下它应该看起来像这样:

public static StringWriter GlobalStringWriter = new StringWriter(); // use this "singleton"
    
public static void Main(string[] args)
{
    Console.SetOut(GlobalStringWriter);
    CreateHostBuilder(args).Build().Run();
}

请注意,它将捕获所有并发请求(无论如何它都应该这样做)。

如果您查看源代码ConsoleLoggerProvider(实际上是通过AddConsole调用设置的),您会看到在内部使用AnsiLogConsole/AnsiParsingLogConsole两者都在内部捕获System.Console.Error/System.Console.Out在其构造函数中的当前值:

public AnsiParsingLogConsole(bool stdErr = false)
{
    _textWriter = stdErr ? System.Console.Error : System.Console.Out;
    _parser = new AnsiParser(WriteToConsole);
}

public AnsiLogConsole(bool stdErr = false)
{
    _textWriter = stdErr ? System.Console.Error : System.Console.Out;
}

因此,在此捕获发生后设置字符串写入器实际上并不会改变写入日志的位置。

我会说这不是很好的方法,可能你最好考虑实现某种你自己的记录器提供程序,它可以让你处理这个用例,或者使用现有的一个并将其设置为调试模式以写入文件。


推荐阅读