Docker 缺少 log4net ConsoleAppender 日志

Docker missing log4net ConsoleAppender logs

我有一个简单的 C# 程序,具有以下 log4net 配置:

<log4net>
    <appender name="stdout" type="log4net.Appender.ConsoleAppender">
    <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%%-5level - %message%newline" />
    </layout>
    </appender>

    <root>
        <level value="DEBUG" />
        <appender-ref ref="stdout" />
    </root>
</log4net>

以及以下代码(为清楚起见进行了缩写):

public static void Main(String[] args)
{
    var log = LogManager.GetLogger("Logger");
    log.Info("Hello From Logger");
    Console.WriteLine("Hello From Console");
}

我正在 Ubuntu 16.04 系统上使用 .NET 4.5 mono 进行编译和 运行ning。当我 运行 使用控制台的程序输出符合预期:

$ mono Program.exe
INFO - Hello From Logger
Hello From Console

然而,当我 运行 在一个 Docker 容器中处于分离模式(即 "docker run -d")的同一个程序然后检查日志时,我只从Console.WriteLine:

$ docker logs <container_id>
Hello From Console

在尝试追踪此问题时,我尝试 运行 使用守护程序工具 (more info here) 连接程序,它说明了相同的行为,让我相信这是 log4net 的问题而不是 docker。 我还为 log4net 编写了一个自定义附加程序,它只执行 Console.Write(我相信这与 ConsoleAppender 的功能相同,但我想消除任何其他可能的变量):

public class CustomAppender: AppenderSkeleton
{
    protected override void Append(LoggingEvent loggingEvent)
    {
        Console.Write(RenderLoggingEvent(loggingEvent));
    }
} 

但运气不好。 任何对 log4net 有深入了解的人都可以指出我在哪里可能做错了什么,或者解释 log4net 可以对 stdout 做什么,以便其他应该捕获该流的程序不会?

更新:剧情变厚了!我写了一个快速而肮脏的可执行文件,它使用 Process class 来执行我的示例程序。然后它从示例程序中获取标准输出并用 Console.WriteLine 写入它,如下所示:

Process proc = new Process();
proc.StartInfo.FileName = "/path/to/example.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInto.RedirectStandardOutput = true;
proc.Start();
Thread.Sleep(1000);
Console.WriteLine(proc.StandardOutput.ReadToEnd());

当我直接从控制台 运行 它时,这工作正常,但是当我从 docker / daemonize 运行 它时有同样的问题。所以现在我真的很困惑。

这不是一个很好的答案,但如果其他人遇到这个问题,我可以通过使用 NLog 库 here.

来使日志记录正常工作