2

java -jar我有一个通过 bash 脚本调用的小型 Java 程序。该程序调用一个 SOAP Web 服务,我想在一个文件中捕获 SOAP 消息以供将来进行故障排除。我发现在独立 Java 应用程序中执行此操作的唯一方法是将其添加到我的客户端类中:

static
{
    // Output the SOAP message to the console
    System.setProperty("com.sun.xml.ws.transport.http.client.HttpTransportPipe.dump", "true");
    System.setProperty("com.sun.xml.ws.transport.http.HttpAdapter.dump", "true");
}

这会将 SOAP 消息输出到系统输出。我可以将系统重定向到一个文件,但我还有其他消息要发送到系统输出,我想在控制台上显示这些消息。可以在文件中包含这些消息,但是 SOAP 消息太多了,无法在控制台上显示。

有没有办法可以对控制台输出进行某种选择性重定向?

4

3 回答 3

1

取决于您使用的 SOAP 库,但通常大多数 SOAP 库在将内容写入控制台时都会使用某种日志记录工具。通常,当您使用这些日志记录工具时,SOAP 库本身不会直接写入 System.out。默认情况下,日志记录工具配置为将该数据写入 System.out。因此,如果您确定您正在使用哪个 SOAP 库,然后确定它使用什么日志记录工具,那么您可以将日志记录配置为写入文件而不是 System.out,但仍将其他消息发送到 System.out。

我认为您正在使用使用 Java Util Logging 的 Metro。不是那么容易配置,但它可以配置多个 appender 和 loggers。我认为这将对您有所帮助:

https://metro.java.net/guide/ch02.html#logging

于 2013-05-31T18:32:27.393 回答
1

为什么不将要捕获的消息写入stderr并适当地重定向呢?您应该考虑的一个问题是stdout [通常] 是缓冲的,而stderr不是。

您正在寻找shell 重定向和管道。假设您使用的是标准的 shell,如 shell、bash、csh 等......

  • command >foo.txt标准输出重定向 到文件。填充中的任何现有内容都将被替换。foo.txt
  • command >>foo.txt重定向 stdout,将其附加到文件foo.txt的现有内容(如果有)的foot.txt.
  • foo | bar将通过 command的标准输入管道foo命令的内容。stdoutbar

*nix 进程打开了三个标准 i/o 句柄:

  • stdin标准输入。它是文件句柄 0。
  • stdout标准输出。它是文件句柄 1。
  • stderr标准错误。它是文件句柄 2。

重定向和管道运算符也可以挂钩特定的文件句柄。所以...

command >foo.txt 2>&1

执行以下操作:

  1. 将标准输出重定向到文件foo.txt
  2. 将stderr重定向到文件句柄 1,stderr,现在打开为foo.txt.

其他 shell 可以(并且确实)使用不同但通常相似的语法。

您还应该了解一些有用的命令:

  • tee(1).

    这将获取给定的标准输入并将其写入命令行上指定的文件以及标准输出,因此链如下:

    some-command 2>&1 | tee some-command.log.2013-05-31.txt | less
    

    运行some-command,这可能会产生大量的输出,将其标准错误重定向到标准输出,然后通过管道传输tee(1),生成一个日志文件,some-commmand.log.2013-05-31.txt并通过管道传输less(1)它以在控制台上对其进行分页。

  • less(1)

  • more(1)

    more通常是less(1)这些日子的同义词。这两个都是分页器,它缓冲输出并一次显示一个屏幕,让您向前和向后翻页。

  • man(1)

  • apropos(1)

    这是*nix 的在线帮助系统。要了解有关它们的更多信息,请尝试运行以下命令:

    * `man man`
    * `man apropos`
    

    获取and命令的手册页。您也可以尝试, 或针对您正在使用的特定 shell(例如,将为您提供shell 的手册页,同时为您提供 Bourne shell ( ) 手册页并为您提供手册页。manaproposman teeman [your-shell-name]man cshcshman shshman bashbash

本页描述了 C 和 Bourne shell 系列的常用管道/重定向运算符:http: //www.mathinfo.u-picardie.fr/asch/f/MeCS/courseware/users/help/general/unix/redirection.html

您还应该阅读相应的 O'ReillyNutshell书籍:

编辑注意: 正如我在下面的评论中提到的,您可以将System.Outand替换System.Err为您自己的PrintStream,如下所示:

PrintStream originalStdOut = System.Out ;
PrintStream newStdout = CreateNewOutputSink() ;

System.Out.flush() ;
System.Out.setOut( newStdout ) ;

invokeSome3rdPartyCode() ;

System.Out.flush() ;
System.Out.setOut( originalStdout ) ;

这将让您挂钩来自 3rd 方库的输出并将其重定向到您选择的数据接收器,同时不会影响您的普通输出。如果您同时挂钩System.Out并将System.Err它们重定向到相同 PrintStream的位置,您将在此过程中捕获标准输出和错误输出。

于 2013-05-31T18:44:37.790 回答
0

您似乎不太可能在应用程序内执行此操作,因为 SOAP 代码将调用 System.out.print。

如果您的主要目标是将输出与来自 SOAP 的输出分开,那么您可以在消息前添加一个特殊符号,然后通过适当的脚本过滤输出。

如果您的打印语句分布在您的代码中,您可以考虑使用 AOP(即 AspectJ)来修改它们以插入此特殊符号。就我个人而言,我通过自己的实用程序方法进行所有打印,以便在需要时可以在一个地方进行全部更改。

于 2013-06-04T07:30:59.613 回答