C# 在log4j/log4net中捕获标准输出

C# 在log4j/log4net中捕获标准输出,c#,java,logging,stdout,C#,Java,Logging,Stdout,我有一个用Java写标准输出的库。我想使用log4j在日志中捕获这个输出。(我没有编写这个库,所以我无法控制库中的代码) 有没有一个简单的方法可以做到这一点?系统设置是否正确?我要传递什么到System.setOut 另外,在.NET/C#中如何执行此操作?为什么要执行此操作。您不应该直接写入sysout,如果希望输出到sysout,您应该写入log4j并配置控制台appender。您应该能够将GUI应用程序连接到列出的标准输出并获得所需的结果。一个解决方案是将OutputStream子类化。您

我有一个用Java写标准输出的库。我想使用log4j在日志中捕获这个输出。(我没有编写这个库,所以我无法控制库中的代码)

有没有一个简单的方法可以做到这一点?系统设置是否正确?我要传递什么到System.setOut


另外,在.NET/C#中如何执行此操作?

为什么要执行此操作。您不应该直接写入sysout,如果希望输出到sysout,您应该写入log4j并配置控制台appender。

您应该能够将GUI应用程序连接到列出的标准输出并获得所需的结果。

一个解决方案是将
OutputStream
子类化。您只需实现
write(intb)
。然后使用构造函数中的
OutputStream
创建一个
PrintStream

它可能看起来像:

public class L4JOS extends OutputStream {
  logger = Logger.getLogger( "std.out" );
  private int lineEnd = (int)'\n';
  private ByteArrayOutputStream baos = new ByteArrayOutputStream();

  public void write( int b ) throws IOException {
    baos.write( b );
    if ( b == lineEnd ) {
      logger.info( baos.toString() );
      baos.reset();
    }
  }

}

如果它是多线程的,那么你有更多的工作。并确保appender没有进入System.out。

您可以实现自己的OutputStream,它只将输出的内容记录到log4j,然后将user System.setOut记录到该OutputStream的实例

请注意,在log4j在标准输出上输出内容的情况下,这可能会导致无限循环


因此,您可能应该进行一些筛选,以确定要传递给log4j的内容以及要传递给原始标准输出流的内容。我不想使用setOut(),因为它是一个全局变量。您将遇到“远距离操作”:您只想为这个库拦截stdout,而不想践踏可能需要使用stdout的任何其他内容

如果可能,在单独的进程空间中运行调用库函数的代码;然后,您可以编写一个线程,从该进程读取标准输出并发送到记录器

new Thread() {
  public void run() {
    ProcessBuilder pb = new ProcessBuilder(command);
    Process p = pb.start();
    BufferedReader in = new BufferedReader(p.getInputStream());
    String line;
    while ((line = in.readLine()) != null) {
      log.info(line);
      // or you could parse line and try to dynamically pick a log level
    }
  }
}

您需要一种很好的方法将被调用进程的输出返回给调用者,但是如果它像返回值一样简单,那么应该很容易将其作为标准输出的最后一行或带有特殊信号代码的行或其他内容返回。

我没有编写这个库,我只是在使用它,我想捕获它产生的输出。尽管这不是解决当前问题的正确方法,但它可能会引导其他人走上正轨,因此我对它进行了升级。还有以下替代实现: