我正在Windows下运行Tomcat 6,使用捆绑的Windows服务运行器。 我似乎有以下行为:
此外,jakarta_service_xxx.log不是stdout的直接转储; 相反,似乎是拦截标准输出,并通过Java日志redirect。 因此,运行免费的Tomcat的JVM通常会打印
283 s java.lang.StringBuffer::length (5 bytes)
在jakarta_service_xxx.log中显示的是这样的:
[2010-01-15 17:07:15] [info] 283 [2010-01-15 17:07:15] [info] s [2010-01-15 17:07:15] [info] java.lang.StringBuffer:: [2010-01-15 17:07:15] [info] l [2010-01-15 17:07:15] [info] e [2010-01-15 17:07:15] [info] n [2010-01-15 17:07:15] [info] g [2010-01-15 17:07:15] [info] t [2010-01-15 17:07:15] [info] h [2010-01-15 17:07:15] [info] (5 bytes)
你能否澄清为什么stdout会在两种情况下得到不同的处理? 或者,关于如何从-XX:+ PrintCompilation获取JVM输出的提示显示在stdout.log中,而不是上面的疯狂?
没有深入挖掘Tomcat的胆量,我认为序列会是这样的。
启动JVM的新进程,传递“stdin”,“stdout”和“stderr”文件描述符。 这些通常由调用shell设置,并通过fork / exec系统调用传递给JVM。 (或者任何与Windows相当的东西…)但是在这种情况下,有一些包装脚本或本机应用程序在JVM启动之前将“stdout”redirect到“jakarta_service_xxx.log”。
JVM创build了一些内部的日志系统(用本地代码实现),GC和其他JVM服务将使用它们来进行JVM日志logging。 这将使用“stdout”或“stderr”文件描述符。
JVM创build包装“stdout”和“stderr”文件描述符的PrintStream(OutputStream)对象,并分别为这些对象设置java.lang.System.out和java.lang.System.err 。
JVM调用Tomcat的main方法来启动Tomcat。
Tomcat打开一个新的FileOutputStream为“stdout_xxx.log”,并使用java.lang.System.setOut()来更新java.lang.System.out 。 如果每个webapp有不同的“stdout_xxx.log”文件,那么Tomcat可能已经实现了一个聪明的输出stream代理,它能够根据线程组或其他东西将输出解复用到不同的日志文件中。
我怀疑,JVM日志logging是不是使用java.util.Logging …或任何Java代码。 它看起来像是。 我这样说是因为我认为如果JVM尝试在特定的点上调用Java代码,就会陷入困境; 例如在GC的关键点。 但是我可能是错的
至于为什么会发生这种情况,我认为这是发生的,因为分离来自webapps和jvm / tomcat核心的“System.out / err”输出通常是一个好主意。 有可能是configuration文件等,让你改变这个…如果你想。
您通常希望将日志输出与webapp分隔开,并且还将其与容器内部的消息(如JVM诊断消息)分开。
除了支持各种日志框架之外,Tomcat还捕获System.out和System.err,并将它们redirect到相应的日志文件。
你应该能够在Tomcat的configuration文件中configuration确切的行为和格式(在Serverfault …上的更多内容)