使用 WebSphere Integration Developer 和 WebSphere ESB V7 在中介模块中实现跟踪、日志记录、错误处理,第 1 部分

中介流中为错误处理设计的策略

本文介绍了在使用 WebSphere® Integration Developer V7 在中介模块中创建的几种不同跟踪、日志记录和错误处理功能。该运行时功能同样适用于运行在 WebSphere Enterprise Service Bus 和 WebSphere Process Server 中的中介。

Frank I. Toth, 软件工程师, IBM

Frank Toth 在 IBM 从事过 4 年软件开发,并拥有 6 年客户支持经验。他的职责包括使用 WebSphere Integration Developer 解决客户报告的软件相关问题。



Dave Screen, 软件工程师, IBM

Dave Screen 照片Dave Screen是一名软件工程师,目前是英国 IBM Hursley Software Lab IBM Software Services for WebSphere (ISSW) 的一名 BPM 顾问。有 9 年的从业经验,涉及领域包括 WebSphere、安全性、事务处理、Jave 运行时以及 Eclipse。



2012 年 1 月 09 日

简介

中介模块是使用 WebSphere Integration Developer V7(以下称为 Integration Developer)创建的。每个模块可以包含若干中介流组件。每个组件可以实现 Web Service (WSDL) 界面上定义的若干操作,操作的每个实现称之为一个中介流,在中介流(简称 “中介流实例” 或 “流”)执行期间,可能会出现各种类型的事件。

考虑以下失败场景:

  1. 消息内的数据与应用程序预期的规则不匹配时,出现无效帐户错误。
  2. Web 服务调用返回一个错误(在其 WSDL 界面上定义的)消息时,出现提供的帐户号码无效。
  3. 输入请求是一个无效数据格式时,出现畸形 XML。
  4. 目标服务故障时,出现 HTTP 404 状态代码响应,Web 服务调用失败
  5. 数据管理员离线,数据库行更新失败。

如何处理每个可能出现的故障,取决于解决方案的要求,如下所示:

  1. 在数据库中记录一个无效数据项。
  2. 将下行错误传回中介客户端。
  3. 跟踪系统日志中的无效数据用于诊断。
  4. 发送邮件给管理员报告系统故障。
  5. 允许数据库异常作为系统故障传播,因为应用程序不能操作,除非数据库是可操作的。

本文使用术语 “日志记录” 表示记录一个事件用于应用程序目的。示例包括审计用于业务目的或者保留记录用于后续调节。术语 “跟踪” 表示记录一个事件用于技术和诊断目的。您可以使用 “跟踪” 来定位问题。有时候,精细的跟踪或调试可能是必须的。在中介流中,中介原语 (Mediation primitives) 处理消息为 Service Message Objects (SMO)。中介原语和其他功能与 SMO 结合使记录数据和提供详细信息(有助于分析和调试 bug)均成为可能。

本系列第 1 部分文章定义了可用的中介原语和运行时功能,这是最适合日志记录和跟踪的。某些情况下,这是一个灰色区域,因为您可以使用原语实现任一目的。

当中介流执行一个 Web 服务或者调用现有 Web 服务时,关于如何处理故障有多种选择。例如,这些失败可以被 “建模 (modeled)” 为 WSDL 接口上的声明错误,或者 “未建模 (unmodeled)” 为系统故障。下一篇文章,第 2 部分中,将介绍几种中介流中处理错误的方法。


WebSphere ESB 中介中的跟踪和记录功能

有几个不同的中介流原语可用于记录和跟踪。在中介流编辑器中,您可以在任何中介原语(这些中介原语有一个Input、Output 或 Fail 终端)之前或之后插入这些原语。考虑到它们通常应用的环境,让我们来区分跟踪和记录组件。

跟踪组件通常被用于短期和临时调试目的,处理有限的数据。

记录组件用于长期数据集合和存储。其设计更加以性能为向导,供生产使用。

  • 交叉组件跟踪 (XCT):XCT 使您可以通过 SCA 模块和组件跟踪消息。
  • Integrated Test Client:使用该功能来测试组件或模块并通过中介原语查看数据流。
  • 跟踪原语:使用该原语跟踪记录到服务器日志或者文件的消息。
  • 消息日志记录器原语:使用该原语在一个关系数据库中查寻存储消息,或者如果您使用定制日志记录功能则可存储在其他存储介质中。
  • 事件发射器原语:该原语可以创建通用基础事件,可以不包含、部分包含或全部包含消息数据。
  • 自定义中介转换原语,使用 Standard Visual Snippet 实用工具:使用这些实用工具记录详情数据到服务器的 SystemOut.log 文件。

中介流中的跟踪组件

以下中介功能可用于跟踪。

交叉组件跟踪

交叉组件跟踪 (XCT) 使您可以通过 SCA 模块和组件跟踪消息。它增加了标准跟踪语句,在 Integration Developer 中可通过一个查看器进行解析。WebSphere ESB 可通过单个原语跟踪该消息的进程,而不仅仅是在中介组件级。如图 1 示例所示。

图 1. 交叉组件跟踪
交叉组件跟踪

与其他跟踪和日志记录机制相比,交叉组件跟踪的一个优势是您可以在运行时完全启用或禁用它,无需开发环境介入。这使它适合于测试或生产环境。XCT 可以跟踪原语、组件和模块之间的交互。当在管理控制台上设置时您也可以在每个模块基上启用它。它还拥有数据快照选项,也就是说还可以捕获数据。要启用,就需要使用 Server Logs 视图的工具栏,或者 Troubleshooting > Cross-Component Trace State 下的管理控制台中的工具栏(图 2)。日志记录直接导入 SystemOut 日志,而这些文件可以在 Server Logs 视图中的 Integration Developer 内消耗。

图 2. 交叉组件跟踪状态
交叉组件跟踪状态

Integrated Test Client

Integrated Test Client (ITC) 直接连接服务器启动测试和跟踪流的执行(图 3)。您可以以下两种方法使用它:

  • 测试组件/导出/导入:这将使用 GUI 编辑器中输入的消息调用操作。
  • 附加模式:这是请求的跟踪执行,不能通过 ITC 初始化。

ITC 的最大优势是测试(包括输入消息)可以被存储,因此可以在 Test 项目 Test Trace 文件中重新使用。您可以以 XML(例如,从文件导入)输入数据。或者使用 Business Object 编辑器图形化。它可以发送 SOAP 消息来进行 Web Service Export 绑定,同时有一个用于配置端点的选项(在 Transport 选项卡中)。在中介流之间传递的数据可用于检查。

另一个关键功能是模仿参考。这使得它可以孤立测试组件,所有操作无需请求后台。

当中介被外部客户端(比如 SOAPUI)驱动时,或者通过发送消息(比如,使用 MQ/JMS 处理的 WebSphere MQ 消息)驱动时,该附加模式对于检查行为非常有用。

图 3. Integrated Test Client 测试一个 Web Service Export 绑定
Integrated Test Client 测试一个 Web Service Export 绑定

跟踪中介原语

使用跟踪中介原语调试中介流,指定要记录到服务器日志或者文件中的跟踪消息。该跟踪消息可以包含服务消息对象 (SMO) 消息内容和关于消息流的其他信息。

图 4 中的示例显示了跟踪原语,可以配置来将一个建模 Web 服务调用异常记录到平面文件 C:\WSTestTrace.log 中。

图 4. 跟踪中介原语
跟踪中介原语

下列可配置属性可用于跟踪中介原语:

  • 启用:与其他原语一样,它可以启用或禁用该原语的功能。它是一个可提升属性。
  • 目的位置:指定跟踪原语应该添加的位置,Local Server Log (SystemOut.log)、User Trace (UserTrace.log) 或 File (User-defined) 其中之一。
  • 文件路径:当目的字段被指定为 File 时,指定跟踪文件的位置。
  • 消息:定义应跟踪的消息格式:{0} = 时间戳,{1} = 消息 ID,{2} = 中介名称,{3} = 模块名称,{4} = 根属性定义的消息,{5} = SMO 的版本。您可以在占位符中包括额外说明文本。
  • 根路径:一个 XPath 表达式,确定哪部分 SMO 应该被序列化到该消息中。

注意,该原语通常不能期望用于生产系统,因为 MessageLogger 或 EventEmitter 更适合。

在中介流中记录组件

消息记录器原语

使用消息记录器中介原语通过一个 IBM 定义的数据模式(表结构)将消息存储到一个关系型数据库。它可以通过自定义的日志记录设备写入其他存储介质,比如平面文件。稍后您可以使用该消息进行数据挖掘或审计。

图 5 显示了配置到一个日志的消息日志记录器原语,该日志器原语使用 JNDI 名作为 “Data source name” 将 Web 服务调用异常模式化到预配置数据库。

图 5. 消息日志记录器原语
消息日志记录器原语

以下可配置属性可用于消息日志记录器原语:

  • 启用:类似于其他原语,它可以启用或禁用该原语的功能,是一个可提升属性。
  • :一个 XPath 表达式,确定哪部分 SMO 应该被序列化到该消息中。
  • 事务模式:“Same” 将消息记录到当前事务下,“New” 将消息记录到其自身事务下。
  • 日志记录类型:指定了跟踪语句应该被添加的位置,或者默认添加到一个数据库,或者使用用户定义的处理器,如下所述。
  • 数据源名称:指定了预配置的数据库,当日志记录类型被指定为 “Database” 时,参考 JNDI。
  • 处理器:直接输出到数据库之外的其他地方,指定一个扩展 java.util.logging.Handler 的类。
  • 格式器:指定了数据格式器类,实现 java.util.logging.Formatter。
  • 过滤器:指定了数据过滤处理器类,实现 java.util.logging.Filter。
  • Literal:定义了跟踪的消息格式:{0} = 时间戳,{1} = 消息 ID,{2} = 中介名称,{3} = 模块名称,{4} = 根属性定义的消息,{5} = SMO 的版本。您也可以包括额外说明文本。
  • 级别:这指定了用于记录消息的跟踪级别。这是传递到处理器的日志记录的一部分。

使用 “New” 事务模式确保将一个成功的消息记录到一个数据库总是坚定的。也就是说,在 “Same” 模式下,如果封装的事务是可以回滚的,则记录的消息是不坚定的。事务不坚定的一个例子是,如果使用 Fail 中介原语,将触发一个 ServiceRuntimeException。

提供的 WESBFileHandler 被记录到临时目录下的 MessageLog.log 文件中。

要实现您自己的处理器:

  • 扩展 java.util.logging.Handler 并使您的类在运行时可用,例如,将其直接包括在您的项目中,或者作为库中的一个 Jar 包。
  • 在您的实现中,重载发布 (LogRecord) 并使用 getFilter() 和 getFormatter() 方法访问指定的其他类。
  • 在 LogRecord 参数中使用 getLevel() 从中介原语中访问 Level 属性。
  • 如果记录到一个文件中,则使用缓存,比如一个新的 BufferedWriter(新的 FileWriter)。

事件发射器原语

事件发射器原语定义应用程序特定事件数据,放置于通用基础事件的 extendedDataElements 部分。该主题概述了在事件发射器原语中定义的属性与通用基础事件的元素之间的映射。

当您从一个拥有事件发射器原语的中介流中生成一个事件定义时,生成的事件定义在这些位置包含原语的属性:

  • 原语的标签属性变成生成事件的名称。
  • 中介模块名称是 ModuleName of extendedDataElement。
  • 原语名称是 MediationName of extendedDataElement.
  • 原语的根属性,例如 /body,是在 extendedDataElement 根中。
  • 该消息中的元素值包含在 extendedData 的消息中。

发射通用基础事件

您可以在中介流中通过使用一个事件发射中介原语在有效点上发射一个通用基础事件。您也可以定义包含在该事件中的消息部分。通用基础事件被发射到 CEI 服务器,可以通过各种不同消耗此事件的应用程序进行访问。

如果您在一个中介流中创建一个事件发射原语时,您可以为该事件和包含在该事件的消息部分定义一个标签。在运行时,当事件发射器原语运行中介流时,发射通用基础事件。事件标签和消息信息包含在通用基础事件的 Extended Data Elements 中。

何时不用事件发射器

考虑一下要将事件处理器放在哪里,以及选择在该事件中存储什么数据。避免将事件发射器放在常用中介流运行路径,因为这将影响性能,导致大量事件的生成。

何时使用一个事件发射器

事件发射器原语提供一种方法从中介流中生成重要的业务事件。考虑将事件发射器作为一个通知机制,用于预示异常事件,比如中介流中出现重大故障,或者不常用的中介流路经。避免将一个事件发射器放在常用中介流路径下,因为这将影响性能,导致大量事件的生成。

如图 6 中的中介流所示。当消息流发生故障时使用一个事件发射器,这是该流中的一个重大故障。

图 6. 事件发射器原语
事件发射器原语

自定义中介原语

该原语可以使用 Standard Visual Snippet 函数作为日志记录功能。我们推荐使用一个开箱即用原语,比如跟踪原语或者消息记录器原语。这些原语都有一些优势,比如有一个内置的 “启用” 属性,一旦提升管理员就可以启动或禁用它们的功能。使用自定义原语的一个特殊情形是当需要条件逻辑决定记录什么或者是否需要记录时。

对于故障排除,Custom Mediation 转换原语有几个内置 Standard Visual Snippet 实用函数实现这一目的。一旦它被放置到中介流编辑器的流中,Properties 选项卡 > Details 会提供几个 Standard Visual Snippet 实用工具选项,将在下一部分描述:

  • 打印到日志:可以打印任何文本到 SystemOut 日志。
  • 打印 BO 到日志:可以打印一个 Business Object 或者 Service Message Object 到 SystemOut 日志。
  • 打印到日志记录器:可以打印文本到 java.util.logging 日志记录器。
  • BO 打印到日志记录器:可以打印一个 Business Object 或者 Service Message Object 到 java.util.logging 日志记录器。
  • 打印到文本:可以打印 Java Object 的 toString() 到日志。

打印到日志

使用该片段可将任何文本打印到 SystemOut 日志。注意:大量记录到 SystemOut 日志将会导致应用程序性能降低。

  1. 选择 Standard Visual Snippet 实用工具打印到日志功能,如图 7 所示。
    图 7. 选择 Standard Visual Snippet 实用函数
    选择 Standard Visual Snippet 实用函数
  2. 将其拖放到 Visual Snippet 编辑器面板中,如图 8 所示。
    图 8. Visual Snippet 编辑器
    Visual Snippet 编辑器
  3. 生成的运行时 Java™ 代码是基于 Java System.out.println() 方法的,如清单 1 所示。
    清单 1. 生成的 Java 代码
    java.lang.String __result__5 = "Start logging - print to log";
    {// print to log
    	System.out.println(__result__5);
    }

打印 BO 到日志

使用该片段打印一个 Business Object 或 Service Message Object 到 SystemOut 日志。注意:初始化业务对象需要大量运算,因此,将会降低应用程序性能。

  1. 选择 Standard Visual Snippet 实用工具打印 BO 到日志功能,如图 9 所示。
    图 9. 选择 Standard Visual Snippet 实用函数
    选择 Standard Visual Snippet 实用函数
  2. 将其拖放到 Visual Snippet 编辑器面板,如图 10 所示。
    图 10. Visual Snippet 编辑器
    Visual Snippet 编辑器
  3. 生成的运行时 Java 代码是基于 commonj.sdo API 接口的,如清单 2 所示。
    清单 2. 生成的 Java 代码
    commonj.sdo.DataObject __smo = (commonj.sdo.DataObject)smo;
    try {
    	{// print BO to log
    	 com.ibm.websphere.bo.BOXMLSerializer srv = 
         (com.ibm.websphere.bo.BOXMLSerializer) new 
         com.ibm.websphere.sca.ServiceManager().locateService
    ("com/ibm/websphere/bo/BOXMLSerializer");
    	 commonj.sdo.Type type = __smo.getType();
    	 srv.writeDataObject(__smo, type.getURI(), 
    type.getName(), java.lang.System.out);
    	}
    }
    catch(java.io.IOException ex2){
    	{// print to log
    	 System.out.println(ex2);
    	}
    	}

打印到日志记录器

使用该片段将文本打印到一个 java.util.logging 日志记录器。您可以使用跟踪级别,以便当使用特定跟踪设置配置服务器时仅输出消息。

  1. 选择 Standard Visual Snippet 实用工具打印到日志记录器功能,如图 11 所示。
    图 11. 选择 Standard Visual Snippet 实用函数
    选择 Standard Visual Snippet 实用函数
  2. 将其拖放到 Visual Snippet 编辑器面板,如图 12 所示。
    图 12. Visual Snippet 编辑器
    Visual Snippet 编辑器
  3. 生成的运行时 Java 代码是基于 java.util.logging.Logger 类的,如清单 3 所示。您可以通过设置日志级别来生成各种详细级别信息:
    • Severe、Warning、Info 和 Config 消息打印到 SystemOut.log。如果在服务器上启用跟踪,它们也可以打印到服务器的 trace.log 文件。
    • Fine、Finer 和 Finest 消息仅可打印到 trace.log 文件,并且只有当在服务器上启用跟踪时才可打印。
    • 将级别设置为 OFF 或 ALL,将会导致消息总是可以打印到 SystemOut.log 文件。
      清单 3. 生成的 Java 代码
      java.lang.String __result__17 = "Print to logger";
      commonj.sdo.DataObject __result__18 = __smo.getDataObject("body");
      {// Log Level: SEVERE
      	final String FQCN = getClass().getName();
      	java.util.logging.Logger l = java.util.logging.Logger.getLogger(FQCN);
      	if(l.isLoggable(java.util.logging.Level.SEVERE)) 
      	{
      	l.logp(java.util.logging.Level.SEVERE, FQCN.substring
           (FQCN.lastIndexOf('.') + 1), "snippet", 
      String.format("%s: %s",__result__17,java.lang.String.valueOf(__result__18)));
      	}
      	}

BO 打印到日志记录器

使用该片段将 Business Object 或 Service Message Object 打印到 java.util.logging 日志记录器。

  1. 选择 Standard Visual Snippet 实用工具 BO 打印到日志记录器功能,如图 13 所示。
    图 13. 选择 Standard Visual Snippet 实用函数
    选择 Standard Visual Snippet 实用函数
  2. 将其拖放到 Visual Snippet 编辑器面板,如图 14 所示。
    图 14. Visual Snippet 编辑器
    Visual Snippet 编辑器
  3. 生成的运行时代码是基于 commonj.sdo API 接口和 java.util.logging.Logger 类的。如清单 14 所示。您可以通过设置 Log 级别来生成各种详细级别信息:
    • Severe、Warning、Info 和 Config 消息打印到 SystemOut.log。如果服务器启用的话,它们也可以打印到服务器上的 trace.log 文件。
    • Fine、Finer 和 Finest 消息只能打印到 trace.log 文件,并且只有当在服务器上启用跟踪时才可打印。
    • 将级别设置为 OFF 或 ALL,将会导致消息总是可以打印到 SystemOut.log 文件。
      清单 4. 生成的 Java 代码
      java.lang.String __result__3 = "BO print to logger";
      try {
      	{// Log Level: ALL
      	 final String FQCN = getClass().getName();
      	 java.util.logging.Logger l = java.util.logging.Logger.getLogger(FQCN);
      	 if(l.isLoggable(java.util.logging.Level.ALL))
      	  {
      	 com.ibm.websphere.bo.BOXMLSerializer serializer =
           (com.ibm.websphere.bo.BOXMLSerializer) com.ibm.websphere.sca.
           ServiceManager.INSTANCE.locateService
           ("com/ibm/websphere/bo/BOXMLSerializer");
      	 java.io.ByteArrayOutputStream stream = new java.io.
           ByteArrayOutputStream();
      	 serializer.writeDataObject(__smo,__smo.getType().getURI(),
           __smo.getType().getName(),stream);
      	 l.logp(java.util.logging.Level.ALL, FQCN.substring(FQCN.lastIndexOf('.') 
             + 1), 
           "snippet", String.format
      ("%s: %s",__result__3 ,stream.toString() ));
      		}
      	}
      }
      catch(java.io.IOException ex){
      	{// print to log
      		System.out.println(ex);
      	}
      	}

打印到文本

使用该片段可以将一个 Java Object 的 toString() 打印到日志。

  1. 选择 Standard Visual Snippet 实用工具打印到文本功能,如图 15 所示。
    图 15. 选择 Standard Visual Snippet 实用函数
    选择 Standard Visual Snippet 实用函数
  2. 将其拖放到 Visual Snippet 编辑器面板,如图 16 所示。
    图 16. Visual Snippet 编辑器
    Visual Snippet 编辑器
  3. 生成的运行时 Java 代码使用 object.toString() 方法,并基于 Java System.out.println() 方法,如清单 5 所示。
    清单 5. 生成的 Java 代码
    java.lang.String __result__20;
    {// to text
    	__result__20 = __smo.toString();	
    }
    {// print to log
    	System.out.println(__result__20);
    }

性能考虑

所有跟踪和日志记录功能对性能有一定影响,需要考虑。例如,需要记录整条消息吗?特别是,输出到日志文件可能会大大降低执行速度,而成为一个性能瓶颈。

如果您是使用跟踪来为测试记录文件,那么在性能测试或者生产时完全删除它,或者设计一种机制来启动或禁用。跟踪中介原语有一个名为 “Enabled” 的可提升属性,您可以使用它在 Integrated Solutions Console( Enterprise Applications > SCA Modules > <moduleName> > Properties 下)中为管理员生成一个跟踪属性。在中介流中保留一个禁用原语无关紧要。


结束语

本文介绍了几个用于在中介模块中进行跟踪和日志记录的可用中介原语,并且使用了 WebSphere Integration Developer V7,运行在 WebSphere ESB V7 服务器上。本文详细介绍了中介原语及其行为,可帮助您为项目设计的中介流选择正确的原语。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere, SOA and web services
ArticleID=784267
ArticleTitle=使用 WebSphere Integration Developer 和 WebSphere ESB V7 在中介模块中实现跟踪、日志记录、错误处理,第 1 部分
publish-date=01092012