Web Service Appender 管理日志纪录
引言 你可以使用 Web Service Appender 将日志集中到某一位置,同时,Web Service Appender 答应治理者监控、开发者调试面向服务架构(SOA)环境里可能存在的任何问题。Web Service Appender 是一种扩展
引言
你可以使用 Web Service Appender 将日志集中到某一位置,同时,Web Service Appender 答应治理者监控、开发者调试面向服务架构(SOA)环境里可能存在的任何问题。Web Service Appender 是一种扩展 Java 类,它由 Log4j 的 Appender 类扩展而来。
从定义上看,SOA 是一种彼此可以互相通信的服务集合,但这些服务的内容是各自独立的,每一类服务均不受其它服务内容或服务状态的影响,并且这些服务都工作在分布式的系统架构里。在 SOA 中,Web 服务通常被用来在给定事务中处理请求,这些请求可以是遗留代码、企业级 Java Beans(EJBs) 的封装,也可以是 Java 类的封装,使用一种可以将日志信息聚集在中心位置里的日志纪录方法,能帮助您隔离缺陷和问题,并能让你更好的理解逻辑流的处理。
将特定模块或服务的日志消息纪录到一个中心位置的机制,可以把可能潜在的问题和缺陷降低到最小。
本文对 Log4j 的功能进行了大体的概述,并介绍了如何编写自定义的 Log4j Appender,这类非凡的 Appender 将日志消息编到一种特定的 Web 服务。
Log4j 快速入门
Log4j 是一种开放源代码的日志库,它已被发展为 Apache Software Foundation 日志服务项目的子项目。该库是以 IBM 在 90 年代末开发的日志库为基础的,第一版发布于 1999 年。现在它在开放源代码团体得到了广泛使用,它的体系是围绕以下三个主要概念构建起来的:
Logger
Appender
Layout
这些概念可以让您根据消息类型、消息优先级来纪录消息,您可以控制消息在何处结束及消息如何格式化。 Logger 是应用程序首先调用以初始化消息纪录的对象。当把某一消息传递给日志时,logger 会生成 LoggingEvent,对消息进行封装。之后,Logger 对象将 LoggingEvent 传递给与之关联的 Appender。
Appender 将 LoggingEvent 所包含的消息发送给指定的目标输出文件。所谓指定的文件,大多数情况下,是 Log4 属性文件。一些 Appender 存在于 Log4j 中。您也可以扩展 Appender,使之支持其它的目标文件,比如 XML 文件、控制台等等。
在 Log4j 里, LoggingEvent 被赋予某一级别,以表明它们的优先级。缺省的级别包括如下几种:
OFF:可能是最高的级别,它是用来关闭日志纪录的
FATAL:指出现了非常严重的错误事件,这些错误可能会导致应用程序异常中止
ERROR:指虽有错误,但仍答应应用程序继续运行
WARN:指运行环境潜藏着危害
INFO:指报告信息,这些信息在粗粒度级别上突出显示应用程序的进程
DEBUG:指细粒度信息事件,细粒度信息事件对于应用程序的调试是最有用的
ALL:可能是最低的级别,其目的是打开所有日志记录
Logger 和 Appender 也被赋予上述的某一级别,并且仅执行等于或高于它们自身的级别的日志请求。比如,假如一个 Appender 属于 INFO 级别,而日志请求属于 DEBUG,那么 Appender 将不会为给定的日志事件写消息。
客户端组件
客户端 log4j.properties 文件
客户端 log4j.properties 文件是一种标准文件,它包含服务或模块使用的所有 Appender。Web Service Appender 要求有一个端点(endpoint) 属性以指定所使用的日志服务。
清单 1 描述了使用 WebServiceAppender 所必需的 Web 服务客户端 Log4j 属性。 黑体显示的文本指明了将访问 WebServiceAppender 服务器端的 Appender。属性文件是使用 Log4j 的基本需求,它可以让您配置应用程序以使用多个 Appender 以及 logging severity。一旦应用程序进入运行状态或潜在的问题得到解决,您就可以轻松地修改属性文件。
清单 1:客户端 Log4j 的属性文件
#set the level of the root logger log
4j.rootLogger = INFO, CONSOLE
#set own loggerlog
4j.logger.com.carmelouria.logging.test=CONSOLElog
4j.appender.CONSOLE=com.carmelouria.logging.WebServiceAppenderlog
4j.appender.CONSOLE.endpoint=
http://localhost:9080/log
4j/services/LogAppenderServicelog
4j.appender.CONSOLE.layout=org.apache.log
4j.PatternLayoutlog
4j.appender.CONSOLE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n
服务器的 Log4j.properties 文件
服务器 Log4j.properties 文件被用来关联客户端 Log4j 属性文件,它指定了日志的级别及服务器将如何输出消息。对于支持 Log4j 的应用程序,您可以定义多个 appender。当然,这些 appender 既可以用于客户端服务,也可以用于服务模块。
清单 2 描述了一份典型的 Log4j 属性文件,服务器端的 WebServiceAppender 使用缺省的 Log4j Appenders。服务器端的 Appender 可以潜在的调用另一个 WebServiceAppender,并将日志信息链接起来:
清单 2:服务器端的 Log4j 属性文件
#set the level of the root logger log
4j.rootLogger = INFO, FILE
#set own loggerlog
4j.appender.FILE=org.apache.log
4j.RollingFileAppenderlog
4j.appender.FILE.file=c:/temp/log
4j/server/server.loglog
4j.appender.FILE.layout=org.apache.log
4j.PatternLayoutlog
4j.appender.FILE.layout.ConversionPattern=%p [%t] %c{2} (%M:%L) :: %m%n
客户端程序测试示例:
这个客户端程序示例是无格式普通 Java 对象(POJO),它记录了一条消息,并被配置为使用 Web Service Appender 来处理消息。清单 3 显示了这个示例:
清单 3:客户端应用程序使用 WebServiceAppender 的示例
package com.carmelouria.logging.test;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
/**
* @author Carmelo Uria
*
*/public class LoggingSample
{
private static Logger logger = Logger.getLogger(LoggingSample.class.getName());
/**
*
*/
public LoggingSample()
{
super();
PropertyConfigurator.configure("c:/temp/log4j.properties");
logger.log(Level.INFO, "LoggingSample instantiation...");
System.out.println("finished...");
}
public static void main(String[] args)
{
LoggingSample sample = new LoggingSample();
}
}
WebServiceAppender
WebServiceAppender 是必需的,它可以将消息发送到指定的 Web 服务。WebServiceAppender 继续了 org.log4j.Appender,它答应使用 log4.properties,并成为有效的 Log4j Appender。
WebServiceAppender 使用基于 XML 的远程过程调用 (JAX-RPC) 的 Java API,来将消息发送到服务器。JAX-RPC 是一种规范,它描述使用 RPC 和 XML 构建 Web 服务和 Web 服务客户端的应用编程接口 (API) 和约定。JAX-RPC 又被称为 JSR 101。
LoggingEvent 通过 SOAPElement 被分割并表示为 XML。javax.xml.soap.SOAPElement 接口意味着服务端点接口将包含一个参数,或返回 javax.xml.soap.SOAPElement 类型的值,以对应于 schema 中每个使用
清单4:执行 WebServiceAppender 服务的 Append 方法
protected void append(LoggingEvent event)
{
// create Web Service client using endpoint
if (endpoint == null)
{
System.out.println("no endpoint set. Check configuration file");
System.out.println("[" + hostname + "] " + this.layout.format(event));
return;
}
executeWebService(event);
}
private void executeWebService(LoggingEvent event)
{
SoapClient client = new SoapClient();
URL endPoint = null;
try
{
endPoint = new URL(getendpoint());
}
catch (MalformedURLException e1)
{
e1.printStackTrace();
}
String nameSpace = "http://ejb.logging.carmelouria.com";
QName serviceName = new QName(nameSpace, "LogAppenderServiceService");
QName operation = new QName(nameSpace, "log");
QName port = new QName(nameSpace, "LogAppenderService");
Parameter message =
new Parameter("log", Constants.XSD_ANY, SOAPElement.class, ParameterMode.IN);
try
{
/
精彩图集
精彩文章