`
guotufu
  • 浏览: 35128 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

部署在WAS下的log日志输出问题

阅读更多

在本地电脑里用RAD中开发项目并部署在本地WAS能正常输出日志,但部署到其它linux系统上里就出现可以创建日志文件但不能输出信息的问题,其中部署的ear包含两个war,每个war都有自己的配置信息,如log4j.xml等。

 

可能的原因:

 

一、WAS在启动后分配到的logger很可能不是log4j的,特别是使用logFactory.getLog(name)有得到不同的log实现类;

现在就来说说查找 LogFactory 的顺序:


1. 从系统属性中查找键为 org.apache.commons.logging.LogFactory 的值作为 LogFactory 的实现类;却通过 System.getProperty("org.apache.commons.logging.LogFactory") 获得

2.  使用 JDK1.3 jar 的 Service Provider Interface(SPI) 类发现机制,从配置文件 META-INF/services/org.apache.commons.logging.LogFactory 的的第一行读取 LogFactory 的实现类名。这个 META-INF/services/org.apache.commons.logging.LogFactory 文件可以是某个 Web 应用的根目录中;也可以在 classpath 下,如某个 Jar 包中,WebRoot/WEB-INF/classes 中等。这里需多加留心下 META-INF/services/org.apache.commons.logging.LogFactory 这个目录层次及文件名。

3.  在 Classpath 下的 commons-logging.properties 文件中的,找到 org.apache.commons.logging.LogFactory 属性值作为 LogFactory 实现类

4. 前面三步未找个 LogFactory 的实现类,或有任何异常的情况下,就用默认的实现类,即 LogFactory 为我们准备的 org.apache.commons.logging.impl.LogFactoryImpl


明白了以上的顺序,可以帮助我们理解和解决一些实际的问题,例如,为什么可以不用 commons-logging.properties 也是使用的 log4j 日志实现,部署在 WAS 下的应用 log4j 怎么就不能输出日志了呢?

一般,某个具体的 LogFactory 类对应就会使用与其相应的 Logger 实现,如 Log4jFactory.getLog() 得到的是 Log4JLogger 实例,WAS 的 TrLogFactory.getLog() 返回的是 TrLog 实例。

老师们教我们用 commons-logging 时也许会让我们在 classpath 下放一个 commons-logging.properties 文件,并在这个文件中写上一行:

org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.Log4jFactory

Log4jFactory 已不推荐使用,新的建议的用法是 LogFactory 统一用 LogFactoryImpl,然后在 LogFactoryImpl 中决定声明哪个 Log 实现类。

或者是这么两行:

org.apache.cmmons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

然而我们基本都是用的 Log4j 来输出日志,其实不管 commons-logging.properties 是第一种写法还是第二种写法或许(有时不是) 都是多余的,回望 LogFactory.getFactory() 方法,还要再看看 org.apache.commons.logging.impl.LogFactoryImpl 的 getLogClassName() 方法便可知。

LogFactory.getFactory() 在前面三步找不到 LogFactory 实现类时,就会用默认的 LogFactoryImpl,而默认的 LogFactoryImpl.getLog() 时,又会根据以下四个顺序来决定返回什么 Log 实例(Log 实例对应到实际的日志实现),在 LogFactoryImpl.getLogClassName() 中体现了:

1. commons-logging.properties 中的 org.apache.commons.logging.Log 指定的 Log 实现类
2. Log4j 可用就用 org.apache.commons.logging.impl.Log4JLogger
3. Jdk1.4 Logger 可用就用 org.apcache.commons.logging.impl.Jdk14Logger(JDK1.4 开始自带)
4. SimpleLog 可用就用 org.apache.commons.logging.impl.SimpleLog(commons-logging 自带)

所以这就是为什么了,使用了 commons-logging 的框架类,只要扔个 log4j 的 jar,根本不用 commons-logging.properties 文件就会用 log4j 来输出日志,当然 log4j 自己的配置文件 log4j.xml 或 log4j.properties 是需要的。

那为什么在 Tomcat 或别的应用服务器中 log4j  能正常输出日志,一放到 WAS 5 下却不灵了呢?原因是在 $WAS_HOME/lib/ws-commons-logging.jar 中有个文件 commons-logging.properties,其中有一行 org.apache.commons.logging.LogFactory=com.ibm.ws.commons.logging.TrLogFactory,虽然你的应用中可能也有一个 commons-logging.properties,可是很不幸,WAS  自己的 commons-logging.properties 优先了,原因是类加载器的委托机制在作用,所以最终 log4j 没派上用场,被 com.ibm.ws.commons.logging.TrLog 取而代之了,解决办法是要抢在它之前,比系统属性中声明 LogFactory 实现类,或是在 META-INF/services/org.apache.commons.logging.LogFactory 中指名 org.apache.commons.logging.impl.Log4jFactory 或 org.apache.commons.logging.impl.LogFactoryImpl 作为实现类名。

 

二、两个war里面定义的xml可能出现同名的情况。

 

这里先介绍下 commons-loggingLog4j。

Commons-loggin的目的是为“所有的Java日志实现”提供一个统一的接口,它自身的日志功能平常弱(只有一个简单的SimpleLog?),所以一般不会单独使用它。Log4j的功能非常全面强大,是目前的首选。我发现几乎所有的Java开源项目都会用到Log4j,但我同时发现,所有用到Log4j的项目一般也同时会用到commons-loggin。我想,大家都不希望自己的项目与Log4j绑定的太紧密吧。另外一个我能想到的“同时使用commons-loggingLog4j”的原因是,简化使用和配置。

 


Commons-logging提供一个统一的日志接口,简单了操作,同时避免项目与某个日志实现系统紧密耦合,很贴心的帮我们自动选择适当的日志实现系统(这一点非常好!)它甚至不需要配置。

 

这里看一下它怎么“‘很贴心的’帮我们‘自动选择’‘适当的’日志实现系统”。

首先org.apche.commons.logging.LogFactory 是一个抽象类,所以需要一个 LogFactory 具体类。Commons-logging查找 LogFactory 的实现类的顺序:

1. 从系统属性中查找键为 org.apache.commons.logging.LogFactory 的值作为 LogFactory 的实现类;却通过 System.getProperty("org.apache.commons.logging.LogFactory") 获得.
2.  使用 JDK1.3 jar 的 Service Provider Interface(SPI) 类发现机制,从配置文件 META-INF/services/org.apache.commons.logging.LogFactory 的的第一行读取 LogFactory 的实现类名。这个 META-INF/services/org.apache.commons.logging.LogFactory 文件可以是某个 Web 应用的根目录中;也可以在 classpath 下,如某个 Jar 包中,WebRoot/WEB-INF/classes 中等。这里需多加留心下 META-INF/services/org.apache.commons.logging.LogFactory 这个目录层次及文件名.
3.  在 Classpath 下的 commons-logging.properties 文件中的,找到 org.apache.commons.logging.LogFactory 属性值作为 LogFactory 实现类。
4. 如果前面未找个 LogFactory 的实现类,或有任何异常的情况下,就用默认的实现类,即 LogFactory 为我们准备的 org.apache.commons.logging.impl.LogFactoryImpl。

 

 

如果用了默认的LogFactoryImpl, LogFactoryImpl.getLog() 返回时,又会根据以下四个顺序来决定返回什么 Log 实例(Log 实例对应到实际的日志实现),在 LogFactoryImpl.getLogClassName() 中体现了:

1. commons-logging.properties 中的 org.apache.commons.logging.Log 指定的 Log 实现类;
2. 查看classpath中是否有Log4j的包,如果发现,则自动使用Log4j作为日志实现类;
3. Jdk1.4 Logger 可用就用 org.apcache.commons.logging.impl.Jdk14Logger(JDK1.4 开始自带);
4. SimpleLog 可用就用 org.apache.commons.logging.impl.SimpleLog(commons-logging 自带);


所 以这就是为什么了,使用了 commons-logging 的框架类,只要扔个 log4j 的 jar,根本不用 commons-logging.properties 文件就会用 log4j 来输出日志,当然 log4j 自己的配置文件 log4j.xml 或 log4j.properties 是需要的。

 

 

转回正题,was是在哪里先下手为强的呢?就在查找commons-logging.properties 文件。那为什么我指定了 commons-logging.properties 文件用 Log4jFactory 还不行呢?实际上 WAS 加载的是 $WAS_HOME/lib/ws-commons-logging.jar!/commons-logging.properties,则其中的内容 是:WebSphere 开发与应用社区 s S*u H O H
C ? ^ u.J v4f4u0org.apache.commons.logging.LogFactory=com.ibm.ws.commons.logging.TrLogFactoryWebSphere 开发与应用社区(B m b M,C K,}

 

所以实际应用的是 WAS 5 自带的 TrLogFactory,而不是 Log4jFactory 或别的。为什么优先加载了些 commons-logging.properties 而非应用中的 commons-logging.properties,原因就是类加载器的委托机制:commons-logging.properties 是通过 ClassLoader 定位的,子 ClassLoader 加载某个类或资源时会委托给父 ClassLoader 加载,父 ClassLoader 能加载到该类或资源则优先。而往往这个父加载器是was提供的。

 


知道了上面那些,那我们来找可能的解决办法,使我们的应用能借助 Log4j 输出日志:

1. 修改 $WAS_HOME/lib/ws-commons-logging.jar!commons-logging.properties 的内容为:
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl
或者org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.Log4jFactory

2. 把 $WAS_HOME/lib/ws-commons-logging.jar!/commons-logging.properties 文件删了?这样父 ClassLoader 是加载不到 commons-logging.properties,能用上应用中的 commons-logging.properties 文件,即使应用中没有 commons-logging.properties 文件也行(没有该文件时会使用 org.apache.commons.logging.impl.LogFactoryImpl,它找到了 Log4j 就用 Log4j),Log4j 也能用了。但这样做同样动了全局的东西。

3. 回到前面 LogFactory 决定具体实现类的步骤上,可以在第一、二步上做文章。其一,设置系统属性 org.apahe.commons.logging.LogFactory 为  org.apache.commons.logging.impl.LogFactoryImpl  或者为 org.apache.commons.logging.impl.Log4jFactory。
要在 WAS 管理控制台对相应的应用服务器设置系统属性,或在程序中设定。这样做同样影响了全局,似乎不怎么妥。

4. 还有第二步,应用 SPI,指定 SERVICE_ID,具体做法是在 WebRoot/  下放个文件 META-INF/services/org.apache.commons.logging.LogFactory,在该文件的第一行写上 org.apache.commons.logging.impl.LogFactoryImpl 或是 org.apache.commons.logging.impl.Log4jFactory 就 OK 啦,这无疑是最好的办法了。总之就是不让 WAS 用 com.ibm.ws.commons.logging.TrLogFactory。因为这个文件也是通过 ClassLoader 加载的,所以 META-INF/services/org.apache.commons.logging.LogFactory 也可以放在 WebRoot/WEB-INF/classes/ 或者是你应用的某个 jar 包中。

5. 还有个办法就是直接用 Log4j,而不用或绕开 commons-logging 的 LogFactory 定位机制,直接在代码中声明使用 Log4j 的 Log,Logger log = Logger.getLogger(TestLog.class),这里的 Logger 是 org.apache.log4j.Logger。这样再换成别的日志组件就没辙了,当然很少有必要去换的。

6. 再 WAS 可以改变应用的类载入器方式。管理控制台中,在应用的属性页面,类载入器方式可以选择 PARENT_FIRST 和 PARENT_LAST,默认是 PARENT_FIRST,遵循类加载器的委托机制。若是改成 PARENT_LAST,也能让你应用中的 commons-logging.properties 优先得到加载,使用上 Log4j。真要改成 PARENT_LAST 能造成的意外情况更是不可预知的。
WebSphere 开发与应用社区 X `:a G U E

 

 

具体解决方法有待改进。

 

 IBM的东西,真是太麻烦了,一个日志都给你替换掉,太霸道了,Google了下,居然是个普遍想象,不过也有相关的解决方

 

案,基本好像都是在 WAS5,WAS6.1上的,我没环境,不过我这边的WAS7 没试成功过

 

描述两种网上的流行的配置

 

第一种:

 

在你的项目的\webapp\META-INF下建立一个名叫services的文件夹,然后建立一个名为org.apache.commons.logging.LogFactory的文件,里面添加一行文字:

org.apache.commons.logging.impl.Log4jFactory

 

即可解决 

 

第二种:

 

在类路径下增加commons-logging.properties配置文件,文件内容为: 
priority=1 
org.apache.commons.logging.LogFactory=org.apache.commons.logging.impl.LogFactoryImpl

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4JLogger

 

.将类加载方式改成parent_last 

 

以上两种我在 WAS 7都没试成功过。

 

就在绝望之际,柳暗花明,在国外的小角落了发现了,下面一段描述

 

*A very strange solution :*
put in / /profiles//properties/
the file commons-logging.properties with :
priority=1
org.apache.commons.logging.LogFactory=org.apache.c ommons.logging.impl.LogFactoryImpl
org.apache.commons.logging.Log=org.apache.commons. logging.impl.Log4JLogger
I don't know which of those lines are really important...

 

http://fixunix.com/websphere/538047-log4j-commons-logging-was6-1-0-19-a.html 

 

尝试之果然有效

 

步骤如下(以windows为例):

 

1、将写好配置的commons-logging.properties 放到 

   D:\IBM\WebSphere\AppServer\profiles\AppSrv01\properties 目录

 

2、将 log4j-1.2.14.jar commons-logging-1.1.1.jar 放到

   D:\IBM\WebSphere\AppServer\lib 目录下

 

3、将你的log4j.Properties 也放到步骤2的目录下

 

不需要改类加载气先后顺序,也不要要动工程结构,重启下服务,日志就生效,,完全是按照log4j的配置文件打印日志的。

目前知道的缺点:所有的应用公用了一个日志配置文件,,需要改变websphere的本身的配置

 

为啥没就人家weblogic 方便呢,几乎啥都不用动,想怎么用就用怎么用。

分享到:
评论

相关推荐

    WAS上log4j日志不能输出(ibatis)sql语句解决办法[借鉴].pdf

    WAS 上 log4j 日志不能...解决 WAS 上 log4j 日志不能输出(ibatis)sql 语句的问题需要改变 WAS 的默认 LogFactory 实现类,使其使用 log4j 框架下的 LogFactory 实现类,并且需要正确配置 log4j.properties 文件。

    WAS问题跟踪情况描述

    在IT行业中,WebSphere Application Server (WAS) 是IBM提供的一款强大的企业级应用服务器,用于部署和管理Java EE(现在称为Jakarta EE)应用程序。"WAS问题跟踪情况描述"通常涉及对WAS运行时遇到的问题进行深入...

    was 7.0应用服务器安装配置及部署

    3. 如果安装成功则成功开启页面,如果安装错误则可查看启动日志,日志目录:IBM\WebSphere\AppServer\profiles\AppSrv01\logs\server1\SystemErr.log IBM\WebSphere\AppServer\profiles\AppSrv01\logs\server1\...

    DB2和WAS性能问题的发现和处理

    ### DB2和WAS性能问题的发现和处理 #### 一、引言 在现代的J2EE应用系统中,确保高性能和稳定性至关重要。...通过以上步骤,可以有效地诊断和解决DB2和WAS在性能方面的问题,从而提高系统的整体性能和稳定性。

    was应用配置

    为了方便监控和维护,还可以将日志文件输出到易于访问的位置,例如`/home/was/ppi/manager/log`目录。通过这些步骤,我们可以确保应用程序能够在WAS环境中稳定运行,并且能够方便地进行日志管理和性能监控。

    WebSphere部署war项目

    默认情况下,日志会记录在文件中,但可以修改配置使日志直接输出到控制台,例如将${SERVER_LOG_ROOT}/SystemOut.log和${SERVER_LOG_ROOT}/SystemErr.log改为console。记得在正式运行时恢复原来的设置,以便更好地...

    用友NC6WAS7安装配置指南

    - 查看部署状态的日志文件`nchome/bin/configsys.log`。 **五、NC创建账套及访问** 1. **创建账套:** - 在部署完成后,需要先停止WAS服务。 - 使用命令`C:\WebSphere\AppServer\profiles\AppSrv01\bin>...

    在myEclipse6中配置websphere6及部署调试

    - Websphere6的日志信息存储在`logs`目录下的`SystemOut.log`和`SystemErr.log`文件中,对于排查问题非常有帮助。 - 在myEclipse6中,可以通过服务器实例的"Console"视图实时查看服务器输出,便于定位运行时错误...

    在Linux(Rhel6.4)上安装oracle11g和was7全过程.doc

    1.3 文件系统划分:建议为不同的组件分配独立的分区,如/home/oracle用于用户主目录,/u01/app/oracle用于数据库文件,/opt/IBM用于WAS7安装,/var/log/oracle用于日志文件,/tmp用于临时文件等。 1.4 软件介质:...

    WebSphere8 安装问题诊断

    然而,在安装过程中可能会遇到各种问题,这些问题通常需要通过对安装或卸载过程中的日志文件进行分析来进行诊断。本文将详细介绍如何利用这些日志文件进行问题诊断,并提供针对不同操作系统环境下日志文件位置的具体...

    WebSphere6.1集群安装配置及部署应用说明

    ### WebSphere 6.1 集群...通过上述步骤,可以顺利完成 WebSphere 6.1 集群的安装配置以及应用程序的部署工作,同时解决了常见的乱码和日志输出问题。这些步骤为在生产环境中高效稳定地运行 Web 应用提供了坚实的基础。

    red hat5.8下安装websphere8.5 并部署应用手册

    在Red Hat 5.8操作系统环境下安装WebSphere Application Server (WAS) 8.5并部署应用程序是一项关键的任务,尤其对于那些需要在企业级Linux环境中运行Java EE应用程序的组织而言。以下将详细介绍整个过程,包括安装...

    WAS+IHS虚拟主机配置

    - 在“环境”下选择“更新Web服务器插件”,这一步是为了确保 WAS 与 IHS 之间的通信正常。 ##### 4. 复制 plugin 文件 - **复制文件**: - 将 WAS 的 plugin 文件夹复制到 IHS 的相应目录下。 ##### 5. 重启 ...

    webshpere7.0.0.0 部署手册

    - **日志查看**:可以通过查看`systemOut.log`和`systemErr.log`文件来监控应用的日志输出。 - **项目发布路径**:了解应用程序实际部署的文件位置。 - **访问已部署应用**:通过访问特定URL(例如`...

    在Linux(Rhel6.4)上安装oracle11g和was7全过程

    在Linux(RHEL6.4)上安装Oracle 11g和WebSphere Application Server (WAS) 7是一项复杂的任务,需要对操作系统、数据库管理和中间件部署有深入理解。以下是对整个过程的详细说明: 一、安装环境 1.1 IP地址 在安装...

    was与 web 服务器通信.doc

    WebSphere Application Server (WAS) 与Web服务器的通信是企业级应用部署的关键组成部分,这涉及到将Web应用程序、服务和资源暴露给互联网或内部网络用户。通常,Web服务器负责处理HTTP请求,而WAS则处理业务逻辑和...

    NC配置WAS[归纳].pdf

    - 在备份前,可以考虑删除`nclogs`文件夹下的日志文件以减少备份文件的大小。 **1.2 备份数据库** - **Oracle的逻辑备份与恢复**: - **备份**:使用`EXP`命令进行逻辑备份。 - 示例:将`nc50`用户的全部数据...

    异常日志

    部署在Was6.0服务器上

    IBMWebSphere8.5部署项目

    - 如果遇到任何异常,可以通过查看 `SystemErr.log` 文件来诊断问题。 以上是 IBM WebSphere 8.5 部署项目的详细步骤说明,涵盖了数据源创建、环境变量设置、服务启动停止、项目发布和更新等关键操作。通过这些...

Global site tag (gtag.js) - Google Analytics