JBoss AS 4.2.3.GA 控制台日志输出问题


  • 先说解决方法

解决方法

  • $JBOSS_HOME/server/default/conf/jboss-service.xml 文件 <mbean code="org.jboss.logging.Log4jService" 中添加配置: <attribute name="CatchSystemOut">false</attribute>
...
<mbean code="org.jboss.logging.Log4jService"
      name="jboss.system:type=Log4jService,service=Logging"
	  xmbean-dd="resource:xmdesc/Log4jService-xmbean.xml">
      <attribute name="ConfigurationURL">resource:jboss-log4j.xml</attribute>
      <!-- Set the org.apache.log4j.helpers.LogLog.setQuiteMode. As of log4j1.2.8
      this needs to be set to avoid a possible deadlock on exception at the
      appender level. See bug#696819.
      -->
      <attribute name="Log4jQuietMode">true</attribute>
      <!-- How frequently in seconds the ConfigurationURL is checked for changes -->
      <attribute name="RefreshPeriod">60</attribute>
	  <attribute name="CatchSystemOut">false</attribute>
   </mbean>
...

  • 以下不重要

现象

  • 项目有几个在用 jboss 作服务器;
    • A 项目,在 log4j.xml 中 没有配置控制台输出日志,鉴于项目非常大且非常复杂,没有调整过日志配置。但是无论如何 在使用 logger.info("XXX") 时是不能输出到控制台的,另一个现象是使用 System.out.println("XXXX") 时,控制台会自己添加时间戳和 [STOUT],例如:13:15:01,525 INFO [STDOUT]
    • B 项目 ,当程序运行起来后,所有 application 中使用的 logger.infoSystem.out.println 都不会再控制台显示,但是可以输出到文件中;对 项目的 log4j.xml 进行简单调整添加 appender 后还是没有效果。由于需求时间紧张也没有细致的调整。
    • C 项目,控制台没有输出 application 自定义的日志,文件一样是有输出,在调整配置文件 log4j.properties 后 控制台输出了 ERROR: invalid console appender config detected, console stream is looping,而且这个项目控制台什么都不输出,之前 有A 项目 和B项目的经验,我知道它们是会有问题的,而且业余时间我大概搜索了一下 jboss 的源码,jboss对 标准输出流进行了重定向。
    • 在这里插入图片描述

思考

  • 一个正常的想法就是,jboss 应该有配置可以调整这项设定。但是 redhat 文档我实在没找到,只能去conf 目录下看看对logging 或者 logger 的相关说明;
  • 使用 $JBOSS_HOME/server/default/conf/jboss-service.xml 文件中的 See bug#696819 关键字搜索,发现了 <attribute name="CatchSystemOut">false</attribute> 配置,在C项目试了一下,好使,sql 啥的都输出到控制台了
  • 搜索中还发现了这个博客

https://blog.csdn.net/vking_wang/article/details/8731469

  • 看博客的最后那个图片

在这里插入图片描述

  • 对于 C 项目它的标准输出流应该像这样,(我猜的):
System.out # application
loggerStream# jboss
org.apache.log4j.ConsoleAppender # application

jboss 源码

/***************************************
 *                                     *
 *  JBoss: The OpenSource J2EE WebOS   *
 *                                     *
 *  Distributable under LGPL license.  *
 *  See terms of license at gnu.org.   *
 *                                     *
 ***************************************/

package org.jboss.logging.util;

import java.io.IOException;
import java.io.PrintStream;

import org.apache.log4j.Logger;
import org.apache.log4j.Level;

import org.jboss.logging.XLevel;

/**
 * A subclass of PrintStream that redirects its output to a log4j Logger.
 * 
 * <p>This class is used to map PrintStream/PrintWriter oriented logging onto
 *    the log4j Categories. Examples include capturing System.out/System.err
 *
 * @version <tt>$Revision: 1.3 $</tt>
 * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
 * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>
 */
public class LoggerStream
    extends PrintStream
{
   /**
    * Default flag to enable/disable tracing println calls.
    * from the system property <tt>org.jboss.logging.util.LoggerStream.trace</tt>
    * or if not set defaults to <tt>false</tt>.
    */
   public static final boolean TRACE =
      getBoolean(LoggerStream.class.getName() + ".trace", false);

   /** Helper to get boolean value from system property or use default if not set. */
   private static boolean getBoolean(String name, boolean defaultValue)
   {
      String value = System.getProperty(name, null);
      if (value == null)
         return defaultValue;
      return new Boolean(value).booleanValue();
   }
   
   private Logger logger;
   private Level level;
   private boolean inWrite;
   private boolean issuedWarning;
   
   /**
    * Redirect logging to the indicated logger using Level.INFO
    */
   public LoggerStream(final Logger logger)
   {
      this(logger, Level.INFO, System.out);
   } 
    
   /**
    * Redirect logging to the indicated logger using the given
    * level. The ps is simply passed to super but is not used.
    */
   public LoggerStream(final Logger logger,
                       final Level level,
                       final PrintStream ps)
   {
      super(ps);
      this.logger = logger;
      this.level = level;
   }
    
   public void println(String msg)
   {
      if( msg == null )
         msg = "null";
      byte[] bytes = msg.getBytes();
      write(bytes, 0, bytes.length);
   }
    
   public void println(Object msg)
   {
      if( msg == null )
         msg = "null";
      byte[] bytes = msg.toString().getBytes();
      write(bytes, 0, bytes.length);
   }
    
   public void write(byte b)
   {
      byte[] bytes = {b};
      write(bytes, 0, 1);
   }
    
   private ThreadLocal recursiveCheck = new ThreadLocal();
   public void write(byte[] b, int off, int len)
   {
      Boolean recursed = (Boolean)recursiveCheck.get();
      if (recursed != null && recursed.equals(Boolean.TRUE))
      {
         /* There is a configuration error that is causing looping. Most
            likely there are two console appenders so just return to prevent
            spinning.
         */
         if( issuedWarning == false )
         {
            String msg = "ERROR: invalid console appender config detected, console stream is looping";
            try
            {
               out.write(msg.getBytes());
            }
            catch(IOException ignore)
            {
            }
            issuedWarning = true;
         }
         return;
      }

      // Remove the end of line chars
      while( len > 0 && (b[len-1] == '\n' || b[len-1] == '\r') && len > off )
         len --;

      // HACK, something is logging exceptions line by line (including
      // blanks), but I can't seem to find it, so for now just ignore
      // empty lines... they aren't very useful.
      if (len != 0)
      {
         String msg = new String(b, off, len);
         recursiveCheck.set(Boolean.TRUE);
         if (TRACE)
         {
            logger.log(level, msg, new Throwable());
         }
         else
         {
            logger.log(level, msg);
         }
         recursiveCheck.set(Boolean.FALSE);
      }
   }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值